diff options
Diffstat (limited to 'monitor.c')
-rw-r--r-- | monitor.c | 679 |
1 files changed, 348 insertions, 331 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: monitor.c,v 1.180 2018/03/03 03:15:51 djm Exp $ */ | 1 | /* $OpenBSD: monitor.c,v 1.186 2018/07/20 03:46:34 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright 2002 Niels Provos <provos@citi.umich.edu> | 3 | * Copyright 2002 Niels Provos <provos@citi.umich.edu> |
4 | * Copyright 2002 Markus Friedl <markus@openbsd.org> | 4 | * Copyright 2002 Markus Friedl <markus@openbsd.org> |
@@ -56,10 +56,6 @@ | |||
56 | # endif | 56 | # endif |
57 | #endif | 57 | #endif |
58 | 58 | ||
59 | #ifdef SKEY | ||
60 | #include <skey.h> | ||
61 | #endif | ||
62 | |||
63 | #ifdef WITH_OPENSSL | 59 | #ifdef WITH_OPENSSL |
64 | #include <openssl/dh.h> | 60 | #include <openssl/dh.h> |
65 | #endif | 61 | #endif |
@@ -68,21 +64,14 @@ | |||
68 | #include "atomicio.h" | 64 | #include "atomicio.h" |
69 | #include "xmalloc.h" | 65 | #include "xmalloc.h" |
70 | #include "ssh.h" | 66 | #include "ssh.h" |
71 | #include "key.h" | 67 | #include "sshkey.h" |
72 | #include "buffer.h" | 68 | #include "sshbuf.h" |
73 | #include "hostfile.h" | 69 | #include "hostfile.h" |
74 | #include "auth.h" | 70 | #include "auth.h" |
75 | #include "cipher.h" | 71 | #include "cipher.h" |
76 | #include "kex.h" | 72 | #include "kex.h" |
77 | #include "dh.h" | 73 | #include "dh.h" |
78 | #include "auth-pam.h" | 74 | #include "auth-pam.h" |
79 | #ifdef TARGET_OS_MAC /* XXX Broken krb5 headers on Mac */ | ||
80 | #undef TARGET_OS_MAC | ||
81 | #include "zlib.h" | ||
82 | #define TARGET_OS_MAC 1 | ||
83 | #else | ||
84 | #include "zlib.h" | ||
85 | #endif | ||
86 | #include "packet.h" | 75 | #include "packet.h" |
87 | #include "auth-options.h" | 76 | #include "auth-options.h" |
88 | #include "sshpty.h" | 77 | #include "sshpty.h" |
@@ -113,9 +102,7 @@ static Gssctxt *gsscontext = NULL; | |||
113 | extern ServerOptions options; | 102 | extern ServerOptions options; |
114 | extern u_int utmp_len; | 103 | extern u_int utmp_len; |
115 | extern u_char session_id[]; | 104 | extern u_char session_id[]; |
116 | extern Buffer auth_debug; | 105 | extern struct sshbuf *loginmsg; |
117 | extern int auth_debug_init; | ||
118 | extern Buffer loginmsg; | ||
119 | extern struct sshauthopt *auth_opts; /* XXX move to permanent ssh->authctxt? */ | 106 | extern struct sshauthopt *auth_opts; /* XXX move to permanent ssh->authctxt? */ |
120 | 107 | ||
121 | /* State exported from the child */ | 108 | /* State exported from the child */ |
@@ -123,46 +110,44 @@ static struct sshbuf *child_state; | |||
123 | 110 | ||
124 | /* Functions on the monitor that answer unprivileged requests */ | 111 | /* Functions on the monitor that answer unprivileged requests */ |
125 | 112 | ||
126 | int mm_answer_moduli(int, Buffer *); | 113 | int mm_answer_moduli(int, struct sshbuf *); |
127 | int mm_answer_sign(int, Buffer *); | 114 | int mm_answer_sign(int, struct sshbuf *); |
128 | int mm_answer_pwnamallow(int, Buffer *); | 115 | int mm_answer_pwnamallow(int, struct sshbuf *); |
129 | int mm_answer_auth2_read_banner(int, Buffer *); | 116 | int mm_answer_auth2_read_banner(int, struct sshbuf *); |
130 | int mm_answer_authserv(int, Buffer *); | 117 | int mm_answer_authserv(int, struct sshbuf *); |
131 | int mm_answer_authpassword(int, Buffer *); | 118 | int mm_answer_authpassword(int, struct sshbuf *); |
132 | int mm_answer_bsdauthquery(int, Buffer *); | 119 | int mm_answer_bsdauthquery(int, struct sshbuf *); |
133 | int mm_answer_bsdauthrespond(int, Buffer *); | 120 | int mm_answer_bsdauthrespond(int, struct sshbuf *); |
134 | int mm_answer_skeyquery(int, Buffer *); | 121 | int mm_answer_keyallowed(int, struct sshbuf *); |
135 | int mm_answer_skeyrespond(int, Buffer *); | 122 | int mm_answer_keyverify(int, struct sshbuf *); |
136 | int mm_answer_keyallowed(int, Buffer *); | 123 | int mm_answer_pty(int, struct sshbuf *); |
137 | int mm_answer_keyverify(int, Buffer *); | 124 | int mm_answer_pty_cleanup(int, struct sshbuf *); |
138 | int mm_answer_pty(int, Buffer *); | 125 | int mm_answer_term(int, struct sshbuf *); |
139 | int mm_answer_pty_cleanup(int, Buffer *); | 126 | int mm_answer_rsa_keyallowed(int, struct sshbuf *); |
140 | int mm_answer_term(int, Buffer *); | 127 | int mm_answer_rsa_challenge(int, struct sshbuf *); |
141 | int mm_answer_rsa_keyallowed(int, Buffer *); | 128 | int mm_answer_rsa_response(int, struct sshbuf *); |
142 | int mm_answer_rsa_challenge(int, Buffer *); | 129 | int mm_answer_sesskey(int, struct sshbuf *); |
143 | int mm_answer_rsa_response(int, Buffer *); | 130 | int mm_answer_sessid(int, struct sshbuf *); |
144 | int mm_answer_sesskey(int, Buffer *); | ||
145 | int mm_answer_sessid(int, Buffer *); | ||
146 | 131 | ||
147 | #ifdef USE_PAM | 132 | #ifdef USE_PAM |
148 | int mm_answer_pam_start(int, Buffer *); | 133 | int mm_answer_pam_start(int, struct sshbuf *); |
149 | int mm_answer_pam_account(int, Buffer *); | 134 | int mm_answer_pam_account(int, struct sshbuf *); |
150 | int mm_answer_pam_init_ctx(int, Buffer *); | 135 | int mm_answer_pam_init_ctx(int, struct sshbuf *); |
151 | int mm_answer_pam_query(int, Buffer *); | 136 | int mm_answer_pam_query(int, struct sshbuf *); |
152 | int mm_answer_pam_respond(int, Buffer *); | 137 | int mm_answer_pam_respond(int, struct sshbuf *); |
153 | int mm_answer_pam_free_ctx(int, Buffer *); | 138 | int mm_answer_pam_free_ctx(int, struct sshbuf *); |
154 | #endif | 139 | #endif |
155 | 140 | ||
156 | #ifdef GSSAPI | 141 | #ifdef GSSAPI |
157 | int mm_answer_gss_setup_ctx(int, Buffer *); | 142 | int mm_answer_gss_setup_ctx(int, struct sshbuf *); |
158 | int mm_answer_gss_accept_ctx(int, Buffer *); | 143 | int mm_answer_gss_accept_ctx(int, struct sshbuf *); |
159 | int mm_answer_gss_userok(int, Buffer *); | 144 | int mm_answer_gss_userok(int, struct sshbuf *); |
160 | int mm_answer_gss_checkmic(int, Buffer *); | 145 | int mm_answer_gss_checkmic(int, struct sshbuf *); |
161 | #endif | 146 | #endif |
162 | 147 | ||
163 | #ifdef SSH_AUDIT_EVENTS | 148 | #ifdef SSH_AUDIT_EVENTS |
164 | int mm_answer_audit_event(int, Buffer *); | 149 | int mm_answer_audit_event(int, struct sshbuf *); |
165 | int mm_answer_audit_command(int, Buffer *); | 150 | int mm_answer_audit_command(int, struct sshbuf *); |
166 | #endif | 151 | #endif |
167 | 152 | ||
168 | static int monitor_read_log(struct monitor *); | 153 | static int monitor_read_log(struct monitor *); |
@@ -171,7 +156,7 @@ static Authctxt *authctxt; | |||
171 | 156 | ||
172 | /* local state for key verify */ | 157 | /* local state for key verify */ |
173 | static u_char *key_blob = NULL; | 158 | static u_char *key_blob = NULL; |
174 | static u_int key_bloblen = 0; | 159 | static size_t key_bloblen = 0; |
175 | static int key_blobtype = MM_NOKEY; | 160 | static int key_blobtype = MM_NOKEY; |
176 | static struct sshauthopt *key_opts = NULL; | 161 | static struct sshauthopt *key_opts = NULL; |
177 | static char *hostbased_cuser = NULL; | 162 | static char *hostbased_cuser = NULL; |
@@ -185,7 +170,7 @@ static pid_t monitor_child_pid; | |||
185 | struct mon_table { | 170 | struct mon_table { |
186 | enum monitor_reqtype type; | 171 | enum monitor_reqtype type; |
187 | int flags; | 172 | int flags; |
188 | int (*f)(int, Buffer *); | 173 | int (*f)(int, struct sshbuf *); |
189 | }; | 174 | }; |
190 | 175 | ||
191 | #define MON_ISAUTH 0x0004 /* Required for Authentication */ | 176 | #define MON_ISAUTH 0x0004 /* Required for Authentication */ |
@@ -221,10 +206,6 @@ struct mon_table mon_dispatch_proto20[] = { | |||
221 | {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery}, | 206 | {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery}, |
222 | {MONITOR_REQ_BSDAUTHRESPOND, MON_AUTH, mm_answer_bsdauthrespond}, | 207 | {MONITOR_REQ_BSDAUTHRESPOND, MON_AUTH, mm_answer_bsdauthrespond}, |
223 | #endif | 208 | #endif |
224 | #ifdef SKEY | ||
225 | {MONITOR_REQ_SKEYQUERY, MON_ISAUTH, mm_answer_skeyquery}, | ||
226 | {MONITOR_REQ_SKEYRESPOND, MON_AUTH, mm_answer_skeyrespond}, | ||
227 | #endif | ||
228 | {MONITOR_REQ_KEYALLOWED, MON_ISAUTH, mm_answer_keyallowed}, | 209 | {MONITOR_REQ_KEYALLOWED, MON_ISAUTH, mm_answer_keyallowed}, |
229 | {MONITOR_REQ_KEYVERIFY, MON_AUTH, mm_answer_keyverify}, | 210 | {MONITOR_REQ_KEYVERIFY, MON_AUTH, mm_answer_keyverify}, |
230 | #ifdef GSSAPI | 211 | #ifdef GSSAPI |
@@ -300,7 +281,7 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) | |||
300 | memset(authctxt, 0, sizeof(*authctxt)); | 281 | memset(authctxt, 0, sizeof(*authctxt)); |
301 | ssh->authctxt = authctxt; | 282 | ssh->authctxt = authctxt; |
302 | 283 | ||
303 | authctxt->loginmsg = &loginmsg; | 284 | authctxt->loginmsg = loginmsg; |
304 | 285 | ||
305 | mon_dispatch = mon_dispatch_proto20; | 286 | mon_dispatch = mon_dispatch_proto20; |
306 | /* Permit requests for moduli and signatures */ | 287 | /* Permit requests for moduli and signatures */ |
@@ -338,13 +319,16 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) | |||
338 | #ifdef USE_PAM | 319 | #ifdef USE_PAM |
339 | /* PAM needs to perform account checks after auth */ | 320 | /* PAM needs to perform account checks after auth */ |
340 | if (options.use_pam && authenticated) { | 321 | if (options.use_pam && authenticated) { |
341 | Buffer m; | 322 | struct sshbuf *m; |
342 | 323 | ||
343 | buffer_init(&m); | 324 | if ((m = sshbuf_new()) == NULL) |
325 | fatal("%s: sshbuf_new failed", | ||
326 | __func__); | ||
344 | mm_request_receive_expect(pmonitor->m_sendfd, | 327 | mm_request_receive_expect(pmonitor->m_sendfd, |
345 | MONITOR_REQ_PAM_ACCOUNT, &m); | 328 | MONITOR_REQ_PAM_ACCOUNT, m); |
346 | authenticated = mm_answer_pam_account(pmonitor->m_sendfd, &m); | 329 | authenticated = mm_answer_pam_account( |
347 | buffer_free(&m); | 330 | pmonitor->m_sendfd, m); |
331 | sshbuf_free(m); | ||
348 | } | 332 | } |
349 | #endif | 333 | #endif |
350 | } | 334 | } |
@@ -428,18 +412,21 @@ monitor_child_postauth(struct monitor *pmonitor) | |||
428 | static int | 412 | static int |
429 | monitor_read_log(struct monitor *pmonitor) | 413 | monitor_read_log(struct monitor *pmonitor) |
430 | { | 414 | { |
431 | Buffer logmsg; | 415 | struct sshbuf *logmsg; |
432 | u_int len, level; | 416 | u_int len, level; |
433 | char *msg; | 417 | char *msg; |
418 | u_char *p; | ||
419 | int r; | ||
434 | 420 | ||
435 | buffer_init(&logmsg); | 421 | if ((logmsg = sshbuf_new()) == NULL) |
422 | fatal("%s: sshbuf_new", __func__); | ||
436 | 423 | ||
437 | /* Read length */ | 424 | /* Read length */ |
438 | buffer_append_space(&logmsg, 4); | 425 | if ((r = sshbuf_reserve(logmsg, 4, &p)) != 0) |
439 | if (atomicio(read, pmonitor->m_log_recvfd, | 426 | fatal("%s: reserve: %s", __func__, ssh_err(r)); |
440 | buffer_ptr(&logmsg), buffer_len(&logmsg)) != buffer_len(&logmsg)) { | 427 | if (atomicio(read, pmonitor->m_log_recvfd, p, 4) != 4) { |
441 | if (errno == EPIPE) { | 428 | if (errno == EPIPE) { |
442 | buffer_free(&logmsg); | 429 | sshbuf_free(logmsg); |
443 | debug("%s: child log fd closed", __func__); | 430 | debug("%s: child log fd closed", __func__); |
444 | close(pmonitor->m_log_recvfd); | 431 | close(pmonitor->m_log_recvfd); |
445 | pmonitor->m_log_recvfd = -1; | 432 | pmonitor->m_log_recvfd = -1; |
@@ -447,26 +434,28 @@ monitor_read_log(struct monitor *pmonitor) | |||
447 | } | 434 | } |
448 | fatal("%s: log fd read: %s", __func__, strerror(errno)); | 435 | fatal("%s: log fd read: %s", __func__, strerror(errno)); |
449 | } | 436 | } |
450 | len = buffer_get_int(&logmsg); | 437 | if ((r = sshbuf_get_u32(logmsg, &len)) != 0) |
438 | fatal("%s: get len: %s", __func__, ssh_err(r)); | ||
451 | if (len <= 4 || len > 8192) | 439 | if (len <= 4 || len > 8192) |
452 | fatal("%s: invalid log message length %u", __func__, len); | 440 | fatal("%s: invalid log message length %u", __func__, len); |
453 | 441 | ||
454 | /* Read severity, message */ | 442 | /* Read severity, message */ |
455 | buffer_clear(&logmsg); | 443 | sshbuf_reset(logmsg); |
456 | buffer_append_space(&logmsg, len); | 444 | if ((r = sshbuf_reserve(logmsg, len, &p)) != 0) |
457 | if (atomicio(read, pmonitor->m_log_recvfd, | 445 | fatal("%s: reserve: %s", __func__, ssh_err(r)); |
458 | buffer_ptr(&logmsg), buffer_len(&logmsg)) != buffer_len(&logmsg)) | 446 | if (atomicio(read, pmonitor->m_log_recvfd, p, len) != len) |
459 | fatal("%s: log fd read: %s", __func__, strerror(errno)); | 447 | fatal("%s: log fd read: %s", __func__, strerror(errno)); |
448 | if ((r = sshbuf_get_u32(logmsg, &level)) != 0 || | ||
449 | (r = sshbuf_get_cstring(logmsg, &msg, NULL)) != 0) | ||
450 | fatal("%s: decode: %s", __func__, ssh_err(r)); | ||
460 | 451 | ||
461 | /* Log it */ | 452 | /* Log it */ |
462 | level = buffer_get_int(&logmsg); | ||
463 | msg = buffer_get_string(&logmsg, NULL); | ||
464 | if (log_level_name(level) == NULL) | 453 | if (log_level_name(level) == NULL) |
465 | fatal("%s: invalid log level %u (corrupted message?)", | 454 | fatal("%s: invalid log level %u (corrupted message?)", |
466 | __func__, level); | 455 | __func__, level); |
467 | do_log2(level, "%s [preauth]", msg); | 456 | do_log2(level, "%s [preauth]", msg); |
468 | 457 | ||
469 | buffer_free(&logmsg); | 458 | sshbuf_free(logmsg); |
470 | free(msg); | 459 | free(msg); |
471 | 460 | ||
472 | return 0; | 461 | return 0; |
@@ -476,8 +465,8 @@ int | |||
476 | monitor_read(struct monitor *pmonitor, struct mon_table *ent, | 465 | monitor_read(struct monitor *pmonitor, struct mon_table *ent, |
477 | struct mon_table **pent) | 466 | struct mon_table **pent) |
478 | { | 467 | { |
479 | Buffer m; | 468 | struct sshbuf *m; |
480 | int ret; | 469 | int r, ret; |
481 | u_char type; | 470 | u_char type; |
482 | struct pollfd pfd[2]; | 471 | struct pollfd pfd[2]; |
483 | 472 | ||
@@ -504,10 +493,12 @@ monitor_read(struct monitor *pmonitor, struct mon_table *ent, | |||
504 | break; /* Continues below */ | 493 | break; /* Continues below */ |
505 | } | 494 | } |
506 | 495 | ||
507 | buffer_init(&m); | 496 | if ((m = sshbuf_new()) == NULL) |
497 | fatal("%s: sshbuf_new", __func__); | ||
508 | 498 | ||
509 | mm_request_receive(pmonitor->m_sendfd, &m); | 499 | mm_request_receive(pmonitor->m_sendfd, m); |
510 | type = buffer_get_char(&m); | 500 | if ((r = sshbuf_get_u8(m, &type)) != 0) |
501 | fatal("%s: decode: %s", __func__, ssh_err(r)); | ||
511 | 502 | ||
512 | debug3("%s: checking request %d", __func__, type); | 503 | debug3("%s: checking request %d", __func__, type); |
513 | 504 | ||
@@ -521,8 +512,8 @@ monitor_read(struct monitor *pmonitor, struct mon_table *ent, | |||
521 | if (!(ent->flags & MON_PERMIT)) | 512 | if (!(ent->flags & MON_PERMIT)) |
522 | fatal("%s: unpermitted request %d", __func__, | 513 | fatal("%s: unpermitted request %d", __func__, |
523 | type); | 514 | type); |
524 | ret = (*ent->f)(pmonitor->m_sendfd, &m); | 515 | ret = (*ent->f)(pmonitor->m_sendfd, m); |
525 | buffer_free(&m); | 516 | sshbuf_free(m); |
526 | 517 | ||
527 | /* The child may use this request only once, disable it */ | 518 | /* The child may use this request only once, disable it */ |
528 | if (ent->flags & MON_ONCE) { | 519 | if (ent->flags & MON_ONCE) { |
@@ -572,14 +563,16 @@ monitor_reset_key_state(void) | |||
572 | 563 | ||
573 | #ifdef WITH_OPENSSL | 564 | #ifdef WITH_OPENSSL |
574 | int | 565 | int |
575 | mm_answer_moduli(int sock, Buffer *m) | 566 | mm_answer_moduli(int sock, struct sshbuf *m) |
576 | { | 567 | { |
577 | DH *dh; | 568 | DH *dh; |
578 | int min, want, max; | 569 | int r; |
570 | u_int min, want, max; | ||
579 | 571 | ||
580 | min = buffer_get_int(m); | 572 | if ((r = sshbuf_get_u32(m, &min)) != 0 || |
581 | want = buffer_get_int(m); | 573 | (r = sshbuf_get_u32(m, &want)) != 0 || |
582 | max = buffer_get_int(m); | 574 | (r = sshbuf_get_u32(m, &max)) != 0) |
575 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
583 | 576 | ||
584 | debug3("%s: got parameters: %d %d %d", | 577 | debug3("%s: got parameters: %d %d %d", |
585 | __func__, min, want, max); | 578 | __func__, min, want, max); |
@@ -588,17 +581,19 @@ mm_answer_moduli(int sock, Buffer *m) | |||
588 | fatal("%s: bad parameters: %d %d %d", | 581 | fatal("%s: bad parameters: %d %d %d", |
589 | __func__, min, want, max); | 582 | __func__, min, want, max); |
590 | 583 | ||
591 | buffer_clear(m); | 584 | sshbuf_reset(m); |
592 | 585 | ||
593 | dh = choose_dh(min, want, max); | 586 | dh = choose_dh(min, want, max); |
594 | if (dh == NULL) { | 587 | if (dh == NULL) { |
595 | buffer_put_char(m, 0); | 588 | if ((r = sshbuf_put_u8(m, 0)) != 0) |
589 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
596 | return (0); | 590 | return (0); |
597 | } else { | 591 | } else { |
598 | /* Send first bignum */ | 592 | /* Send first bignum */ |
599 | buffer_put_char(m, 1); | 593 | if ((r = sshbuf_put_u8(m, 1)) != 0 || |
600 | buffer_put_bignum2(m, dh->p); | 594 | (r = sshbuf_put_bignum2(m, dh->p)) != 0 || |
601 | buffer_put_bignum2(m, dh->g); | 595 | (r = sshbuf_put_bignum2(m, dh->g)) != 0) |
596 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
602 | 597 | ||
603 | DH_free(dh); | 598 | DH_free(dh); |
604 | } | 599 | } |
@@ -608,7 +603,7 @@ mm_answer_moduli(int sock, Buffer *m) | |||
608 | #endif | 603 | #endif |
609 | 604 | ||
610 | int | 605 | int |
611 | mm_answer_sign(int sock, Buffer *m) | 606 | mm_answer_sign(int sock, struct sshbuf *m) |
612 | { | 607 | { |
613 | struct ssh *ssh = active_state; /* XXX */ | 608 | struct ssh *ssh = active_state; /* XXX */ |
614 | extern int auth_sock; /* XXX move to state struct? */ | 609 | extern int auth_sock; /* XXX move to state struct? */ |
@@ -618,14 +613,15 @@ mm_answer_sign(int sock, Buffer *m) | |||
618 | char *alg = NULL; | 613 | char *alg = NULL; |
619 | size_t datlen, siglen, alglen; | 614 | size_t datlen, siglen, alglen; |
620 | int r, is_proof = 0; | 615 | int r, is_proof = 0; |
621 | u_int keyid; | 616 | u_int keyid, compat; |
622 | const char proof_req[] = "hostkeys-prove-00@openssh.com"; | 617 | const char proof_req[] = "hostkeys-prove-00@openssh.com"; |
623 | 618 | ||
624 | debug3("%s", __func__); | 619 | debug3("%s", __func__); |
625 | 620 | ||
626 | if ((r = sshbuf_get_u32(m, &keyid)) != 0 || | 621 | if ((r = sshbuf_get_u32(m, &keyid)) != 0 || |
627 | (r = sshbuf_get_string(m, &p, &datlen)) != 0 || | 622 | (r = sshbuf_get_string(m, &p, &datlen)) != 0 || |
628 | (r = sshbuf_get_cstring(m, &alg, &alglen)) != 0) | 623 | (r = sshbuf_get_cstring(m, &alg, &alglen)) != 0 || |
624 | (r = sshbuf_get_u32(m, &compat)) != 0) | ||
629 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 625 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
630 | if (keyid > INT_MAX) | 626 | if (keyid > INT_MAX) |
631 | fatal("%s: invalid key ID", __func__); | 627 | fatal("%s: invalid key ID", __func__); |
@@ -675,13 +671,13 @@ mm_answer_sign(int sock, Buffer *m) | |||
675 | 671 | ||
676 | if ((key = get_hostkey_by_index(keyid)) != NULL) { | 672 | if ((key = get_hostkey_by_index(keyid)) != NULL) { |
677 | if ((r = sshkey_sign(key, &signature, &siglen, p, datlen, alg, | 673 | if ((r = sshkey_sign(key, &signature, &siglen, p, datlen, alg, |
678 | datafellows)) != 0) | 674 | compat)) != 0) |
679 | fatal("%s: sshkey_sign failed: %s", | 675 | fatal("%s: sshkey_sign failed: %s", |
680 | __func__, ssh_err(r)); | 676 | __func__, ssh_err(r)); |
681 | } else if ((key = get_hostkey_public_by_index(keyid, ssh)) != NULL && | 677 | } else if ((key = get_hostkey_public_by_index(keyid, ssh)) != NULL && |
682 | auth_sock > 0) { | 678 | auth_sock > 0) { |
683 | if ((r = ssh_agent_sign(auth_sock, key, &signature, &siglen, | 679 | if ((r = ssh_agent_sign(auth_sock, key, &signature, &siglen, |
684 | p, datlen, alg, datafellows)) != 0) { | 680 | p, datlen, alg, compat)) != 0) { |
685 | fatal("%s: ssh_agent_sign failed: %s", | 681 | fatal("%s: ssh_agent_sign failed: %s", |
686 | __func__, ssh_err(r)); | 682 | __func__, ssh_err(r)); |
687 | } | 683 | } |
@@ -710,12 +706,12 @@ mm_answer_sign(int sock, Buffer *m) | |||
710 | /* Retrieves the password entry and also checks if the user is permitted */ | 706 | /* Retrieves the password entry and also checks if the user is permitted */ |
711 | 707 | ||
712 | int | 708 | int |
713 | mm_answer_pwnamallow(int sock, Buffer *m) | 709 | mm_answer_pwnamallow(int sock, struct sshbuf *m) |
714 | { | 710 | { |
715 | struct ssh *ssh = active_state; /* XXX */ | 711 | struct ssh *ssh = active_state; /* XXX */ |
716 | char *username; | 712 | char *username; |
717 | struct passwd *pwent; | 713 | struct passwd *pwent; |
718 | int allowed = 0; | 714 | int r, allowed = 0; |
719 | u_int i; | 715 | u_int i; |
720 | 716 | ||
721 | debug3("%s", __func__); | 717 | debug3("%s", __func__); |
@@ -723,7 +719,8 @@ mm_answer_pwnamallow(int sock, Buffer *m) | |||
723 | if (authctxt->attempt++ != 0) | 719 | if (authctxt->attempt++ != 0) |
724 | fatal("%s: multiple attempts for getpwnam", __func__); | 720 | fatal("%s: multiple attempts for getpwnam", __func__); |
725 | 721 | ||
726 | username = buffer_get_string(m, NULL); | 722 | if ((r = sshbuf_get_cstring(m, &username, NULL)) != 0) |
723 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
727 | 724 | ||
728 | pwent = getpwnamallow(username); | 725 | pwent = getpwnamallow(username); |
729 | 726 | ||
@@ -731,10 +728,11 @@ mm_answer_pwnamallow(int sock, Buffer *m) | |||
731 | setproctitle("%s [priv]", pwent ? username : "unknown"); | 728 | setproctitle("%s [priv]", pwent ? username : "unknown"); |
732 | free(username); | 729 | free(username); |
733 | 730 | ||
734 | buffer_clear(m); | 731 | sshbuf_reset(m); |
735 | 732 | ||
736 | if (pwent == NULL) { | 733 | if (pwent == NULL) { |
737 | buffer_put_char(m, 0); | 734 | if ((r = sshbuf_put_u8(m, 0)) != 0) |
735 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
738 | authctxt->pw = fakepw(); | 736 | authctxt->pw = fakepw(); |
739 | goto out; | 737 | goto out; |
740 | } | 738 | } |
@@ -743,31 +741,40 @@ mm_answer_pwnamallow(int sock, Buffer *m) | |||
743 | authctxt->pw = pwent; | 741 | authctxt->pw = pwent; |
744 | authctxt->valid = 1; | 742 | authctxt->valid = 1; |
745 | 743 | ||
746 | buffer_put_char(m, 1); | 744 | /* XXX don't sent pwent to unpriv; send fake class/dir/shell too */ |
747 | buffer_put_string(m, pwent, sizeof(struct passwd)); | 745 | if ((r = sshbuf_put_u8(m, 1)) != 0 || |
748 | buffer_put_cstring(m, pwent->pw_name); | 746 | (r = sshbuf_put_string(m, pwent, sizeof(*pwent))) != 0 || |
749 | buffer_put_cstring(m, "*"); | 747 | (r = sshbuf_put_cstring(m, pwent->pw_name)) != 0 || |
748 | (r = sshbuf_put_cstring(m, "*")) != 0 || | ||
750 | #ifdef HAVE_STRUCT_PASSWD_PW_GECOS | 749 | #ifdef HAVE_STRUCT_PASSWD_PW_GECOS |
751 | buffer_put_cstring(m, pwent->pw_gecos); | 750 | (r = sshbuf_put_cstring(m, pwent->pw_gecos)) != 0 || |
752 | #endif | 751 | #endif |
753 | #ifdef HAVE_STRUCT_PASSWD_PW_CLASS | 752 | #ifdef HAVE_STRUCT_PASSWD_PW_CLASS |
754 | buffer_put_cstring(m, pwent->pw_class); | 753 | (r = sshbuf_put_cstring(m, pwent->pw_class)) != 0 || |
755 | #endif | 754 | #endif |
756 | buffer_put_cstring(m, pwent->pw_dir); | 755 | (r = sshbuf_put_cstring(m, pwent->pw_dir)) != 0 || |
757 | buffer_put_cstring(m, pwent->pw_shell); | 756 | (r = sshbuf_put_cstring(m, pwent->pw_shell)) != 0) |
757 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
758 | 758 | ||
759 | out: | 759 | out: |
760 | ssh_packet_set_log_preamble(ssh, "%suser %s", | 760 | ssh_packet_set_log_preamble(ssh, "%suser %s", |
761 | authctxt->valid ? "authenticating" : "invalid ", authctxt->user); | 761 | authctxt->valid ? "authenticating" : "invalid ", authctxt->user); |
762 | buffer_put_string(m, &options, sizeof(options)); | 762 | if ((r = sshbuf_put_string(m, &options, sizeof(options))) != 0) |
763 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
763 | 764 | ||
764 | #define M_CP_STROPT(x) do { \ | 765 | #define M_CP_STROPT(x) do { \ |
765 | if (options.x != NULL) \ | 766 | if (options.x != NULL) { \ |
766 | buffer_put_cstring(m, options.x); \ | 767 | if ((r = sshbuf_put_cstring(m, options.x)) != 0) \ |
768 | fatal("%s: buffer error: %s", \ | ||
769 | __func__, ssh_err(r)); \ | ||
770 | } \ | ||
767 | } while (0) | 771 | } while (0) |
768 | #define M_CP_STRARRAYOPT(x, nx) do { \ | 772 | #define M_CP_STRARRAYOPT(x, nx) do { \ |
769 | for (i = 0; i < options.nx; i++) \ | 773 | for (i = 0; i < options.nx; i++) { \ |
770 | buffer_put_cstring(m, options.x[i]); \ | 774 | if ((r = sshbuf_put_cstring(m, options.x[i])) != 0) \ |
775 | fatal("%s: buffer error: %s", \ | ||
776 | __func__, ssh_err(r)); \ | ||
777 | } \ | ||
771 | } while (0) | 778 | } while (0) |
772 | /* See comment in servconf.h */ | 779 | /* See comment in servconf.h */ |
773 | COPY_MATCH_STRING_OPTS(); | 780 | COPY_MATCH_STRING_OPTS(); |
@@ -799,13 +806,15 @@ mm_answer_pwnamallow(int sock, Buffer *m) | |||
799 | return (0); | 806 | return (0); |
800 | } | 807 | } |
801 | 808 | ||
802 | int mm_answer_auth2_read_banner(int sock, Buffer *m) | 809 | int mm_answer_auth2_read_banner(int sock, struct sshbuf *m) |
803 | { | 810 | { |
804 | char *banner; | 811 | char *banner; |
812 | int r; | ||
805 | 813 | ||
806 | buffer_clear(m); | 814 | sshbuf_reset(m); |
807 | banner = auth2_read_banner(); | 815 | banner = auth2_read_banner(); |
808 | buffer_put_cstring(m, banner != NULL ? banner : ""); | 816 | if ((r = sshbuf_put_cstring(m, banner != NULL ? banner : "")) != 0) |
817 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
809 | mm_request_send(sock, MONITOR_ANS_AUTH2_READ_BANNER, m); | 818 | mm_request_send(sock, MONITOR_ANS_AUTH2_READ_BANNER, m); |
810 | free(banner); | 819 | free(banner); |
811 | 820 | ||
@@ -813,12 +822,15 @@ int mm_answer_auth2_read_banner(int sock, Buffer *m) | |||
813 | } | 822 | } |
814 | 823 | ||
815 | int | 824 | int |
816 | mm_answer_authserv(int sock, Buffer *m) | 825 | mm_answer_authserv(int sock, struct sshbuf *m) |
817 | { | 826 | { |
827 | int r; | ||
828 | |||
818 | monitor_permit_authentications(1); | 829 | monitor_permit_authentications(1); |
819 | 830 | ||
820 | authctxt->service = buffer_get_string(m, NULL); | 831 | if ((r = sshbuf_get_cstring(m, &authctxt->service, NULL)) != 0 || |
821 | authctxt->style = buffer_get_string(m, NULL); | 832 | (r = sshbuf_get_cstring(m, &authctxt->style, NULL)) != 0) |
833 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
822 | debug3("%s: service=%s, style=%s", | 834 | debug3("%s: service=%s, style=%s", |
823 | __func__, authctxt->service, authctxt->style); | 835 | __func__, authctxt->service, authctxt->style); |
824 | 836 | ||
@@ -831,27 +843,30 @@ mm_answer_authserv(int sock, Buffer *m) | |||
831 | } | 843 | } |
832 | 844 | ||
833 | int | 845 | int |
834 | mm_answer_authpassword(int sock, Buffer *m) | 846 | mm_answer_authpassword(int sock, struct sshbuf *m) |
835 | { | 847 | { |
836 | struct ssh *ssh = active_state; /* XXX */ | 848 | struct ssh *ssh = active_state; /* XXX */ |
837 | static int call_count; | 849 | static int call_count; |
838 | char *passwd; | 850 | char *passwd; |
839 | int authenticated; | 851 | int r, authenticated; |
840 | u_int plen; | 852 | size_t plen; |
841 | 853 | ||
842 | if (!options.password_authentication) | 854 | if (!options.password_authentication) |
843 | fatal("%s: password authentication not enabled", __func__); | 855 | fatal("%s: password authentication not enabled", __func__); |
844 | passwd = buffer_get_string(m, &plen); | 856 | if ((r = sshbuf_get_cstring(m, &passwd, &plen)) != 0) |
857 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
845 | /* Only authenticate if the context is valid */ | 858 | /* Only authenticate if the context is valid */ |
846 | authenticated = options.password_authentication && | 859 | authenticated = options.password_authentication && |
847 | auth_password(ssh, passwd); | 860 | auth_password(ssh, passwd); |
848 | explicit_bzero(passwd, strlen(passwd)); | 861 | explicit_bzero(passwd, plen); |
849 | free(passwd); | 862 | free(passwd); |
850 | 863 | ||
851 | buffer_clear(m); | 864 | sshbuf_reset(m); |
852 | buffer_put_int(m, authenticated); | 865 | if ((r = sshbuf_put_u32(m, authenticated)) != 0) |
866 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
853 | #ifdef USE_PAM | 867 | #ifdef USE_PAM |
854 | buffer_put_int(m, sshpam_get_maxtries_reached()); | 868 | if ((r = sshbuf_put_u32(m, sshpam_get_maxtries_reached())) != 0) |
869 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
855 | #endif | 870 | #endif |
856 | 871 | ||
857 | debug3("%s: sending result %d", __func__, authenticated); | 872 | debug3("%s: sending result %d", __func__, authenticated); |
@@ -869,23 +884,25 @@ mm_answer_authpassword(int sock, Buffer *m) | |||
869 | 884 | ||
870 | #ifdef BSD_AUTH | 885 | #ifdef BSD_AUTH |
871 | int | 886 | int |
872 | mm_answer_bsdauthquery(int sock, Buffer *m) | 887 | mm_answer_bsdauthquery(int sock, struct sshbuf *m) |
873 | { | 888 | { |
874 | char *name, *infotxt; | 889 | char *name, *infotxt; |
875 | u_int numprompts; | 890 | u_int numprompts, *echo_on, success; |
876 | u_int *echo_on; | ||
877 | char **prompts; | 891 | char **prompts; |
878 | u_int success; | 892 | int r; |
879 | 893 | ||
880 | if (!options.kbd_interactive_authentication) | 894 | if (!options.kbd_interactive_authentication) |
881 | fatal("%s: kbd-int authentication not enabled", __func__); | 895 | fatal("%s: kbd-int authentication not enabled", __func__); |
882 | success = bsdauth_query(authctxt, &name, &infotxt, &numprompts, | 896 | success = bsdauth_query(authctxt, &name, &infotxt, &numprompts, |
883 | &prompts, &echo_on) < 0 ? 0 : 1; | 897 | &prompts, &echo_on) < 0 ? 0 : 1; |
884 | 898 | ||
885 | buffer_clear(m); | 899 | sshbuf_reset(m); |
886 | buffer_put_int(m, success); | 900 | if ((r = sshbuf_put_u32(m, success)) != 0) |
887 | if (success) | 901 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
888 | buffer_put_cstring(m, prompts[0]); | 902 | if (success) { |
903 | if ((r = sshbuf_put_cstring(m, prompts[0])) != 0) | ||
904 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
905 | } | ||
889 | 906 | ||
890 | debug3("%s: sending challenge success: %u", __func__, success); | 907 | debug3("%s: sending challenge success: %u", __func__, success); |
891 | mm_request_send(sock, MONITOR_ANS_BSDAUTHQUERY, m); | 908 | mm_request_send(sock, MONITOR_ANS_BSDAUTHQUERY, m); |
@@ -901,25 +918,27 @@ mm_answer_bsdauthquery(int sock, Buffer *m) | |||
901 | } | 918 | } |
902 | 919 | ||
903 | int | 920 | int |
904 | mm_answer_bsdauthrespond(int sock, Buffer *m) | 921 | mm_answer_bsdauthrespond(int sock, struct sshbuf *m) |
905 | { | 922 | { |
906 | char *response; | 923 | char *response; |
907 | int authok; | 924 | int r, authok; |
908 | 925 | ||
909 | if (!options.kbd_interactive_authentication) | 926 | if (!options.kbd_interactive_authentication) |
910 | fatal("%s: kbd-int authentication not enabled", __func__); | 927 | fatal("%s: kbd-int authentication not enabled", __func__); |
911 | if (authctxt->as == NULL) | 928 | if (authctxt->as == NULL) |
912 | fatal("%s: no bsd auth session", __func__); | 929 | fatal("%s: no bsd auth session", __func__); |
913 | 930 | ||
914 | response = buffer_get_string(m, NULL); | 931 | if ((r = sshbuf_get_cstring(m, &response, NULL)) != 0) |
932 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
915 | authok = options.challenge_response_authentication && | 933 | authok = options.challenge_response_authentication && |
916 | auth_userresponse(authctxt->as, response, 0); | 934 | auth_userresponse(authctxt->as, response, 0); |
917 | authctxt->as = NULL; | 935 | authctxt->as = NULL; |
918 | debug3("%s: <%s> = <%d>", __func__, response, authok); | 936 | debug3("%s: <%s> = <%d>", __func__, response, authok); |
919 | free(response); | 937 | free(response); |
920 | 938 | ||
921 | buffer_clear(m); | 939 | sshbuf_reset(m); |
922 | buffer_put_int(m, authok); | 940 | if ((r = sshbuf_put_u32(m, authok)) != 0) |
941 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
923 | 942 | ||
924 | debug3("%s: sending authenticated: %d", __func__, authok); | 943 | debug3("%s: sending authenticated: %d", __func__, authok); |
925 | mm_request_send(sock, MONITOR_ANS_BSDAUTHRESPOND, m); | 944 | mm_request_send(sock, MONITOR_ANS_BSDAUTHRESPOND, m); |
@@ -931,59 +950,9 @@ mm_answer_bsdauthrespond(int sock, Buffer *m) | |||
931 | } | 950 | } |
932 | #endif | 951 | #endif |
933 | 952 | ||
934 | #ifdef SKEY | ||
935 | int | ||
936 | mm_answer_skeyquery(int sock, Buffer *m) | ||
937 | { | ||
938 | struct skey skey; | ||
939 | char challenge[1024]; | ||
940 | u_int success; | ||
941 | |||
942 | success = _compat_skeychallenge(&skey, authctxt->user, challenge, | ||
943 | sizeof(challenge)) < 0 ? 0 : 1; | ||
944 | |||
945 | buffer_clear(m); | ||
946 | buffer_put_int(m, success); | ||
947 | if (success) | ||
948 | buffer_put_cstring(m, challenge); | ||
949 | |||
950 | debug3("%s: sending challenge success: %u", __func__, success); | ||
951 | mm_request_send(sock, MONITOR_ANS_SKEYQUERY, m); | ||
952 | |||
953 | return (0); | ||
954 | } | ||
955 | |||
956 | int | ||
957 | mm_answer_skeyrespond(int sock, Buffer *m) | ||
958 | { | ||
959 | char *response; | ||
960 | int authok; | ||
961 | |||
962 | response = buffer_get_string(m, NULL); | ||
963 | |||
964 | authok = (options.challenge_response_authentication && | ||
965 | authctxt->valid && | ||
966 | skey_haskey(authctxt->pw->pw_name) == 0 && | ||
967 | skey_passcheck(authctxt->pw->pw_name, response) != -1); | ||
968 | |||
969 | free(response); | ||
970 | |||
971 | buffer_clear(m); | ||
972 | buffer_put_int(m, authok); | ||
973 | |||
974 | debug3("%s: sending authenticated: %d", __func__, authok); | ||
975 | mm_request_send(sock, MONITOR_ANS_SKEYRESPOND, m); | ||
976 | |||
977 | auth_method = "keyboard-interactive"; | ||
978 | auth_submethod = "skey"; | ||
979 | |||
980 | return (authok != 0); | ||
981 | } | ||
982 | #endif | ||
983 | |||
984 | #ifdef USE_PAM | 953 | #ifdef USE_PAM |
985 | int | 954 | int |
986 | mm_answer_pam_start(int sock, Buffer *m) | 955 | mm_answer_pam_start(int sock, struct sshbuf *m) |
987 | { | 956 | { |
988 | if (!options.use_pam) | 957 | if (!options.use_pam) |
989 | fatal("UsePAM not set, but ended up in %s anyway", __func__); | 958 | fatal("UsePAM not set, but ended up in %s anyway", __func__); |
@@ -998,17 +967,19 @@ mm_answer_pam_start(int sock, Buffer *m) | |||
998 | } | 967 | } |
999 | 968 | ||
1000 | int | 969 | int |
1001 | mm_answer_pam_account(int sock, Buffer *m) | 970 | mm_answer_pam_account(int sock, struct sshbuf *m) |
1002 | { | 971 | { |
1003 | u_int ret; | 972 | u_int ret; |
973 | int r; | ||
1004 | 974 | ||
1005 | if (!options.use_pam) | 975 | if (!options.use_pam) |
1006 | fatal("%s: PAM not enabled", __func__); | 976 | fatal("%s: PAM not enabled", __func__); |
1007 | 977 | ||
1008 | ret = do_pam_account(); | 978 | ret = do_pam_account(); |
1009 | 979 | ||
1010 | buffer_put_int(m, ret); | 980 | if ((r = sshbuf_put_u32(m, ret)) != 0 || |
1011 | buffer_put_string(m, buffer_ptr(&loginmsg), buffer_len(&loginmsg)); | 981 | (r = sshbuf_put_stringb(m, loginmsg)) != 0) |
982 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1012 | 983 | ||
1013 | mm_request_send(sock, MONITOR_ANS_PAM_ACCOUNT, m); | 984 | mm_request_send(sock, MONITOR_ANS_PAM_ACCOUNT, m); |
1014 | 985 | ||
@@ -1019,8 +990,11 @@ static void *sshpam_ctxt, *sshpam_authok; | |||
1019 | extern KbdintDevice sshpam_device; | 990 | extern KbdintDevice sshpam_device; |
1020 | 991 | ||
1021 | int | 992 | int |
1022 | mm_answer_pam_init_ctx(int sock, Buffer *m) | 993 | mm_answer_pam_init_ctx(int sock, struct sshbuf *m) |
1023 | { | 994 | { |
995 | u_int ok = 0; | ||
996 | int r; | ||
997 | |||
1024 | debug3("%s", __func__); | 998 | debug3("%s", __func__); |
1025 | if (!options.kbd_interactive_authentication) | 999 | if (!options.kbd_interactive_authentication) |
1026 | fatal("%s: kbd-int authentication not enabled", __func__); | 1000 | fatal("%s: kbd-int authentication not enabled", __func__); |
@@ -1028,24 +1002,24 @@ mm_answer_pam_init_ctx(int sock, Buffer *m) | |||
1028 | fatal("%s: already called", __func__); | 1002 | fatal("%s: already called", __func__); |
1029 | sshpam_ctxt = (sshpam_device.init_ctx)(authctxt); | 1003 | sshpam_ctxt = (sshpam_device.init_ctx)(authctxt); |
1030 | sshpam_authok = NULL; | 1004 | sshpam_authok = NULL; |
1031 | buffer_clear(m); | 1005 | sshbuf_reset(m); |
1032 | if (sshpam_ctxt != NULL) { | 1006 | if (sshpam_ctxt != NULL) { |
1033 | monitor_permit(mon_dispatch, MONITOR_REQ_PAM_FREE_CTX, 1); | 1007 | monitor_permit(mon_dispatch, MONITOR_REQ_PAM_FREE_CTX, 1); |
1034 | monitor_permit(mon_dispatch, MONITOR_REQ_PAM_QUERY, 1); | 1008 | monitor_permit(mon_dispatch, MONITOR_REQ_PAM_QUERY, 1); |
1035 | buffer_put_int(m, 1); | 1009 | ok = 1; |
1036 | } else { | ||
1037 | buffer_put_int(m, 0); | ||
1038 | } | 1010 | } |
1011 | if ((r = sshbuf_put_u32(m, ok)) != 0) | ||
1012 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1039 | mm_request_send(sock, MONITOR_ANS_PAM_INIT_CTX, m); | 1013 | mm_request_send(sock, MONITOR_ANS_PAM_INIT_CTX, m); |
1040 | return (0); | 1014 | return (0); |
1041 | } | 1015 | } |
1042 | 1016 | ||
1043 | int | 1017 | int |
1044 | mm_answer_pam_query(int sock, Buffer *m) | 1018 | mm_answer_pam_query(int sock, struct sshbuf *m) |
1045 | { | 1019 | { |
1046 | char *name = NULL, *info = NULL, **prompts = NULL; | 1020 | char *name = NULL, *info = NULL, **prompts = NULL; |
1047 | u_int i, num = 0, *echo_on = 0; | 1021 | u_int i, num = 0, *echo_on = 0; |
1048 | int ret; | 1022 | int r, ret; |
1049 | 1023 | ||
1050 | debug3("%s", __func__); | 1024 | debug3("%s", __func__); |
1051 | sshpam_authok = NULL; | 1025 | sshpam_authok = NULL; |
@@ -1058,18 +1032,20 @@ mm_answer_pam_query(int sock, Buffer *m) | |||
1058 | if (num > 1 || name == NULL || info == NULL) | 1032 | if (num > 1 || name == NULL || info == NULL) |
1059 | fatal("sshpam_device.query failed"); | 1033 | fatal("sshpam_device.query failed"); |
1060 | monitor_permit(mon_dispatch, MONITOR_REQ_PAM_RESPOND, 1); | 1034 | monitor_permit(mon_dispatch, MONITOR_REQ_PAM_RESPOND, 1); |
1061 | buffer_clear(m); | 1035 | sshbuf_reset(m); |
1062 | buffer_put_int(m, ret); | 1036 | if ((r = sshbuf_put_u32(m, ret)) != 0 || |
1063 | buffer_put_cstring(m, name); | 1037 | (r = sshbuf_put_cstring(m, name)) != 0 || |
1038 | (r = sshbuf_put_cstring(m, info)) != 0 || | ||
1039 | (r = sshbuf_put_u32(m, sshpam_get_maxtries_reached())) != 0 || | ||
1040 | (r = sshbuf_put_u32(m, num)) != 0) | ||
1041 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1064 | free(name); | 1042 | free(name); |
1065 | buffer_put_cstring(m, info); | ||
1066 | free(info); | 1043 | free(info); |
1067 | buffer_put_int(m, sshpam_get_maxtries_reached()); | ||
1068 | buffer_put_int(m, num); | ||
1069 | for (i = 0; i < num; ++i) { | 1044 | for (i = 0; i < num; ++i) { |
1070 | buffer_put_cstring(m, prompts[i]); | 1045 | if ((r = sshbuf_put_cstring(m, prompts[i])) != 0 || |
1046 | (r = sshbuf_put_u32(m, echo_on[i])) != 0) | ||
1047 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1071 | free(prompts[i]); | 1048 | free(prompts[i]); |
1072 | buffer_put_int(m, echo_on[i]); | ||
1073 | } | 1049 | } |
1074 | free(prompts); | 1050 | free(prompts); |
1075 | free(echo_on); | 1051 | free(echo_on); |
@@ -1080,21 +1056,25 @@ mm_answer_pam_query(int sock, Buffer *m) | |||
1080 | } | 1056 | } |
1081 | 1057 | ||
1082 | int | 1058 | int |
1083 | mm_answer_pam_respond(int sock, Buffer *m) | 1059 | mm_answer_pam_respond(int sock, struct sshbuf *m) |
1084 | { | 1060 | { |
1085 | char **resp; | 1061 | char **resp; |
1086 | u_int i, num; | 1062 | u_int i, num; |
1087 | int ret; | 1063 | int r, ret; |
1088 | 1064 | ||
1089 | debug3("%s", __func__); | 1065 | debug3("%s", __func__); |
1090 | if (sshpam_ctxt == NULL) | 1066 | if (sshpam_ctxt == NULL) |
1091 | fatal("%s: no context", __func__); | 1067 | fatal("%s: no context", __func__); |
1092 | sshpam_authok = NULL; | 1068 | sshpam_authok = NULL; |
1093 | num = buffer_get_int(m); | 1069 | if ((r = sshbuf_get_u32(m, &num)) != 0) |
1070 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1094 | if (num > 0) { | 1071 | if (num > 0) { |
1095 | resp = xcalloc(num, sizeof(char *)); | 1072 | resp = xcalloc(num, sizeof(char *)); |
1096 | for (i = 0; i < num; ++i) | 1073 | for (i = 0; i < num; ++i) { |
1097 | resp[i] = buffer_get_string(m, NULL); | 1074 | if ((r = sshbuf_get_cstring(m, &(resp[i]), NULL)) != 0) |
1075 | fatal("%s: buffer error: %s", | ||
1076 | __func__, ssh_err(r)); | ||
1077 | } | ||
1098 | ret = (sshpam_device.respond)(sshpam_ctxt, num, resp); | 1078 | ret = (sshpam_device.respond)(sshpam_ctxt, num, resp); |
1099 | for (i = 0; i < num; ++i) | 1079 | for (i = 0; i < num; ++i) |
1100 | free(resp[i]); | 1080 | free(resp[i]); |
@@ -1102,8 +1082,9 @@ mm_answer_pam_respond(int sock, Buffer *m) | |||
1102 | } else { | 1082 | } else { |
1103 | ret = (sshpam_device.respond)(sshpam_ctxt, num, NULL); | 1083 | ret = (sshpam_device.respond)(sshpam_ctxt, num, NULL); |
1104 | } | 1084 | } |
1105 | buffer_clear(m); | 1085 | sshbuf_reset(m); |
1106 | buffer_put_int(m, ret); | 1086 | if ((r = sshbuf_put_u32(m, ret)) != 0) |
1087 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1107 | mm_request_send(sock, MONITOR_ANS_PAM_RESPOND, m); | 1088 | mm_request_send(sock, MONITOR_ANS_PAM_RESPOND, m); |
1108 | auth_method = "keyboard-interactive"; | 1089 | auth_method = "keyboard-interactive"; |
1109 | auth_submethod = "pam"; | 1090 | auth_submethod = "pam"; |
@@ -1113,7 +1094,7 @@ mm_answer_pam_respond(int sock, Buffer *m) | |||
1113 | } | 1094 | } |
1114 | 1095 | ||
1115 | int | 1096 | int |
1116 | mm_answer_pam_free_ctx(int sock, Buffer *m) | 1097 | mm_answer_pam_free_ctx(int sock, struct sshbuf *m) |
1117 | { | 1098 | { |
1118 | int r = sshpam_authok != NULL && sshpam_authok == sshpam_ctxt; | 1099 | int r = sshpam_authok != NULL && sshpam_authok == sshpam_ctxt; |
1119 | 1100 | ||
@@ -1122,7 +1103,7 @@ mm_answer_pam_free_ctx(int sock, Buffer *m) | |||
1122 | fatal("%s: no context", __func__); | 1103 | fatal("%s: no context", __func__); |
1123 | (sshpam_device.free_ctx)(sshpam_ctxt); | 1104 | (sshpam_device.free_ctx)(sshpam_ctxt); |
1124 | sshpam_ctxt = sshpam_authok = NULL; | 1105 | sshpam_ctxt = sshpam_authok = NULL; |
1125 | buffer_clear(m); | 1106 | sshbuf_reset(m); |
1126 | mm_request_send(sock, MONITOR_ANS_PAM_FREE_CTX, m); | 1107 | mm_request_send(sock, MONITOR_ANS_PAM_FREE_CTX, m); |
1127 | /* Allow another attempt */ | 1108 | /* Allow another attempt */ |
1128 | monitor_permit(mon_dispatch, MONITOR_REQ_PAM_INIT_CTX, 1); | 1109 | monitor_permit(mon_dispatch, MONITOR_REQ_PAM_INIT_CTX, 1); |
@@ -1133,31 +1114,29 @@ mm_answer_pam_free_ctx(int sock, Buffer *m) | |||
1133 | #endif | 1114 | #endif |
1134 | 1115 | ||
1135 | int | 1116 | int |
1136 | mm_answer_keyallowed(int sock, Buffer *m) | 1117 | mm_answer_keyallowed(int sock, struct sshbuf *m) |
1137 | { | 1118 | { |
1138 | struct ssh *ssh = active_state; /* XXX */ | 1119 | struct ssh *ssh = active_state; /* XXX */ |
1139 | struct sshkey *key; | 1120 | struct sshkey *key = NULL; |
1140 | char *cuser, *chost; | 1121 | char *cuser, *chost; |
1141 | u_char *blob; | 1122 | u_int pubkey_auth_attempt; |
1142 | u_int bloblen, pubkey_auth_attempt; | ||
1143 | enum mm_keytype type = 0; | 1123 | enum mm_keytype type = 0; |
1144 | int r, allowed = 0; | 1124 | int r, allowed = 0; |
1145 | struct sshauthopt *opts = NULL; | 1125 | struct sshauthopt *opts = NULL; |
1146 | 1126 | ||
1147 | debug3("%s entering", __func__); | 1127 | debug3("%s entering", __func__); |
1148 | type = buffer_get_int(m); | 1128 | if ((r = sshbuf_get_u32(m, &type)) != 0 || |
1149 | cuser = buffer_get_string(m, NULL); | 1129 | (r = sshbuf_get_cstring(m, &cuser, NULL)) != 0 || |
1150 | chost = buffer_get_string(m, NULL); | 1130 | (r = sshbuf_get_cstring(m, &chost, NULL)) != 0 || |
1151 | blob = buffer_get_string(m, &bloblen); | 1131 | (r = sshkey_froms(m, &key)) != 0 || |
1152 | pubkey_auth_attempt = buffer_get_int(m); | 1132 | (r = sshbuf_get_u32(m, &pubkey_auth_attempt)) != 0) |
1153 | 1133 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | |
1154 | key = key_from_blob(blob, bloblen); | ||
1155 | 1134 | ||
1156 | debug3("%s: key_from_blob: %p", __func__, key); | 1135 | debug3("%s: key_from_blob: %p", __func__, key); |
1157 | 1136 | ||
1158 | if (key != NULL && authctxt->valid) { | 1137 | if (key != NULL && authctxt->valid) { |
1159 | /* These should not make it past the privsep child */ | 1138 | /* These should not make it past the privsep child */ |
1160 | if (key_type_plain(key->type) == KEY_RSA && | 1139 | if (sshkey_type_plain(key->type) == KEY_RSA && |
1161 | (datafellows & SSH_BUG_RSASIGMD5) != 0) | 1140 | (datafellows & SSH_BUG_RSASIGMD5) != 0) |
1162 | fatal("%s: passed a SSH_BUG_RSASIGMD5 key", __func__); | 1141 | fatal("%s: passed a SSH_BUG_RSASIGMD5 key", __func__); |
1163 | 1142 | ||
@@ -1201,15 +1180,14 @@ mm_answer_keyallowed(int sock, Buffer *m) | |||
1201 | allowed ? "allowed" : "not allowed"); | 1180 | allowed ? "allowed" : "not allowed"); |
1202 | 1181 | ||
1203 | auth2_record_key(authctxt, 0, key); | 1182 | auth2_record_key(authctxt, 0, key); |
1204 | sshkey_free(key); | ||
1205 | 1183 | ||
1206 | /* clear temporarily storage (used by verify) */ | 1184 | /* clear temporarily storage (used by verify) */ |
1207 | monitor_reset_key_state(); | 1185 | monitor_reset_key_state(); |
1208 | 1186 | ||
1209 | if (allowed) { | 1187 | if (allowed) { |
1210 | /* Save temporarily for comparison in verify */ | 1188 | /* Save temporarily for comparison in verify */ |
1211 | key_blob = blob; | 1189 | if ((r = sshkey_to_blob(key, &key_blob, &key_bloblen)) != 0) |
1212 | key_bloblen = bloblen; | 1190 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
1213 | key_blobtype = type; | 1191 | key_blobtype = type; |
1214 | key_opts = opts; | 1192 | key_opts = opts; |
1215 | hostbased_cuser = cuser; | 1193 | hostbased_cuser = cuser; |
@@ -1217,13 +1195,14 @@ mm_answer_keyallowed(int sock, Buffer *m) | |||
1217 | } else { | 1195 | } else { |
1218 | /* Log failed attempt */ | 1196 | /* Log failed attempt */ |
1219 | auth_log(authctxt, 0, 0, auth_method, NULL); | 1197 | auth_log(authctxt, 0, 0, auth_method, NULL); |
1220 | free(blob); | ||
1221 | free(cuser); | 1198 | free(cuser); |
1222 | free(chost); | 1199 | free(chost); |
1223 | } | 1200 | } |
1201 | sshkey_free(key); | ||
1224 | 1202 | ||
1225 | buffer_clear(m); | 1203 | sshbuf_reset(m); |
1226 | buffer_put_int(m, allowed); | 1204 | if ((r = sshbuf_put_u32(m, allowed)) != 0) |
1205 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1227 | if (opts != NULL && (r = sshauthopt_serialise(opts, m, 1)) != 0) | 1206 | if (opts != NULL && (r = sshauthopt_serialise(opts, m, 1)) != 0) |
1228 | fatal("%s: sshauthopt_serialise: %s", __func__, ssh_err(r)); | 1207 | fatal("%s: sshauthopt_serialise: %s", __func__, ssh_err(r)); |
1229 | mm_request_send(sock, MONITOR_ANS_KEYALLOWED, m); | 1208 | mm_request_send(sock, MONITOR_ANS_KEYALLOWED, m); |
@@ -1237,34 +1216,41 @@ mm_answer_keyallowed(int sock, Buffer *m) | |||
1237 | static int | 1216 | static int |
1238 | monitor_valid_userblob(u_char *data, u_int datalen) | 1217 | monitor_valid_userblob(u_char *data, u_int datalen) |
1239 | { | 1218 | { |
1240 | Buffer b; | 1219 | struct sshbuf *b; |
1241 | u_char *p; | 1220 | const u_char *p; |
1242 | char *userstyle, *cp; | 1221 | char *userstyle, *cp; |
1243 | u_int len; | 1222 | size_t len; |
1244 | int fail = 0; | 1223 | u_char type; |
1224 | int r, fail = 0; | ||
1245 | 1225 | ||
1246 | buffer_init(&b); | 1226 | if ((b = sshbuf_new()) == NULL) |
1247 | buffer_append(&b, data, datalen); | 1227 | fatal("%s: sshbuf_new", __func__); |
1228 | if ((r = sshbuf_put(b, data, datalen)) != 0) | ||
1229 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1248 | 1230 | ||
1249 | if (datafellows & SSH_OLD_SESSIONID) { | 1231 | if (datafellows & SSH_OLD_SESSIONID) { |
1250 | p = buffer_ptr(&b); | 1232 | p = sshbuf_ptr(b); |
1251 | len = buffer_len(&b); | 1233 | len = sshbuf_len(b); |
1252 | if ((session_id2 == NULL) || | 1234 | if ((session_id2 == NULL) || |
1253 | (len < session_id2_len) || | 1235 | (len < session_id2_len) || |
1254 | (timingsafe_bcmp(p, session_id2, session_id2_len) != 0)) | 1236 | (timingsafe_bcmp(p, session_id2, session_id2_len) != 0)) |
1255 | fail++; | 1237 | fail++; |
1256 | buffer_consume(&b, session_id2_len); | 1238 | if ((r = sshbuf_consume(b, session_id2_len)) != 0) |
1239 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1257 | } else { | 1240 | } else { |
1258 | p = buffer_get_string(&b, &len); | 1241 | if ((r = sshbuf_get_string_direct(b, &p, &len)) != 0) |
1242 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1259 | if ((session_id2 == NULL) || | 1243 | if ((session_id2 == NULL) || |
1260 | (len != session_id2_len) || | 1244 | (len != session_id2_len) || |
1261 | (timingsafe_bcmp(p, session_id2, session_id2_len) != 0)) | 1245 | (timingsafe_bcmp(p, session_id2, session_id2_len) != 0)) |
1262 | fail++; | 1246 | fail++; |
1263 | free(p); | ||
1264 | } | 1247 | } |
1265 | if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST) | 1248 | if ((r = sshbuf_get_u8(b, &type)) != 0) |
1249 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1250 | if (type != SSH2_MSG_USERAUTH_REQUEST) | ||
1266 | fail++; | 1251 | fail++; |
1267 | cp = buffer_get_cstring(&b, NULL); | 1252 | if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0) |
1253 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1268 | xasprintf(&userstyle, "%s%s%s", authctxt->user, | 1254 | xasprintf(&userstyle, "%s%s%s", authctxt->user, |
1269 | authctxt->style ? ":" : "", | 1255 | authctxt->style ? ":" : "", |
1270 | authctxt->style ? authctxt->style : ""); | 1256 | authctxt->style ? authctxt->style : ""); |
@@ -1275,18 +1261,22 @@ monitor_valid_userblob(u_char *data, u_int datalen) | |||
1275 | } | 1261 | } |
1276 | free(userstyle); | 1262 | free(userstyle); |
1277 | free(cp); | 1263 | free(cp); |
1278 | buffer_skip_string(&b); | 1264 | if ((r = sshbuf_skip_string(b)) != 0 || /* service */ |
1279 | cp = buffer_get_cstring(&b, NULL); | 1265 | (r = sshbuf_get_cstring(b, &cp, NULL)) != 0) |
1266 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1280 | if (strcmp("publickey", cp) != 0) | 1267 | if (strcmp("publickey", cp) != 0) |
1281 | fail++; | 1268 | fail++; |
1282 | free(cp); | 1269 | free(cp); |
1283 | if (!buffer_get_char(&b)) | 1270 | if ((r = sshbuf_get_u8(b, &type)) != 0) |
1271 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1272 | if (type == 0) | ||
1284 | fail++; | 1273 | fail++; |
1285 | buffer_skip_string(&b); | 1274 | if ((r = sshbuf_skip_string(b)) != 0 || /* pkalg */ |
1286 | buffer_skip_string(&b); | 1275 | (r = sshbuf_skip_string(b)) != 0) /* pkblob */ |
1287 | if (buffer_len(&b) != 0) | 1276 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
1277 | if (sshbuf_len(b) != 0) | ||
1288 | fail++; | 1278 | fail++; |
1289 | buffer_free(&b); | 1279 | sshbuf_free(b); |
1290 | return (fail == 0); | 1280 | return (fail == 0); |
1291 | } | 1281 | } |
1292 | 1282 | ||
@@ -1294,59 +1284,69 @@ static int | |||
1294 | monitor_valid_hostbasedblob(u_char *data, u_int datalen, char *cuser, | 1284 | monitor_valid_hostbasedblob(u_char *data, u_int datalen, char *cuser, |
1295 | char *chost) | 1285 | char *chost) |
1296 | { | 1286 | { |
1297 | Buffer b; | 1287 | struct sshbuf *b; |
1298 | char *p, *userstyle; | 1288 | const u_char *p; |
1299 | u_int len; | 1289 | char *cp, *userstyle; |
1300 | int fail = 0; | 1290 | size_t len; |
1291 | int r, fail = 0; | ||
1292 | u_char type; | ||
1301 | 1293 | ||
1302 | buffer_init(&b); | 1294 | if ((b = sshbuf_new()) == NULL) |
1303 | buffer_append(&b, data, datalen); | 1295 | fatal("%s: sshbuf_new", __func__); |
1296 | if ((r = sshbuf_put(b, data, datalen)) != 0 || | ||
1297 | (r = sshbuf_get_string_direct(b, &p, &len)) != 0) | ||
1298 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1304 | 1299 | ||
1305 | p = buffer_get_string(&b, &len); | ||
1306 | if ((session_id2 == NULL) || | 1300 | if ((session_id2 == NULL) || |
1307 | (len != session_id2_len) || | 1301 | (len != session_id2_len) || |
1308 | (timingsafe_bcmp(p, session_id2, session_id2_len) != 0)) | 1302 | (timingsafe_bcmp(p, session_id2, session_id2_len) != 0)) |
1309 | fail++; | 1303 | fail++; |
1310 | free(p); | ||
1311 | 1304 | ||
1312 | if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST) | 1305 | if ((r = sshbuf_get_u8(b, &type)) != 0) |
1306 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1307 | if (type != SSH2_MSG_USERAUTH_REQUEST) | ||
1313 | fail++; | 1308 | fail++; |
1314 | p = buffer_get_cstring(&b, NULL); | 1309 | if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0) |
1310 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1315 | xasprintf(&userstyle, "%s%s%s", authctxt->user, | 1311 | xasprintf(&userstyle, "%s%s%s", authctxt->user, |
1316 | authctxt->style ? ":" : "", | 1312 | authctxt->style ? ":" : "", |
1317 | authctxt->style ? authctxt->style : ""); | 1313 | authctxt->style ? authctxt->style : ""); |
1318 | if (strcmp(userstyle, p) != 0) { | 1314 | if (strcmp(userstyle, cp) != 0) { |
1319 | logit("wrong user name passed to monitor: expected %s != %.100s", | 1315 | logit("wrong user name passed to monitor: " |
1320 | userstyle, p); | 1316 | "expected %s != %.100s", userstyle, cp); |
1321 | fail++; | 1317 | fail++; |
1322 | } | 1318 | } |
1323 | free(userstyle); | 1319 | free(userstyle); |
1324 | free(p); | 1320 | free(cp); |
1325 | buffer_skip_string(&b); /* service */ | 1321 | if ((r = sshbuf_skip_string(b)) != 0 || /* service */ |
1326 | p = buffer_get_cstring(&b, NULL); | 1322 | (r = sshbuf_get_cstring(b, &cp, NULL)) != 0) |
1327 | if (strcmp(p, "hostbased") != 0) | 1323 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
1324 | if (strcmp(cp, "hostbased") != 0) | ||
1328 | fail++; | 1325 | fail++; |
1329 | free(p); | 1326 | free(cp); |
1330 | buffer_skip_string(&b); /* pkalg */ | 1327 | if ((r = sshbuf_skip_string(b)) != 0 || /* pkalg */ |
1331 | buffer_skip_string(&b); /* pkblob */ | 1328 | (r = sshbuf_skip_string(b)) != 0) /* pkblob */ |
1329 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1332 | 1330 | ||
1333 | /* verify client host, strip trailing dot if necessary */ | 1331 | /* verify client host, strip trailing dot if necessary */ |
1334 | p = buffer_get_string(&b, NULL); | 1332 | if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0) |
1335 | if (((len = strlen(p)) > 0) && p[len - 1] == '.') | 1333 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
1336 | p[len - 1] = '\0'; | 1334 | if (((len = strlen(cp)) > 0) && cp[len - 1] == '.') |
1337 | if (strcmp(p, chost) != 0) | 1335 | cp[len - 1] = '\0'; |
1336 | if (strcmp(cp, chost) != 0) | ||
1338 | fail++; | 1337 | fail++; |
1339 | free(p); | 1338 | free(cp); |
1340 | 1339 | ||
1341 | /* verify client user */ | 1340 | /* verify client user */ |
1342 | p = buffer_get_string(&b, NULL); | 1341 | if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0) |
1343 | if (strcmp(p, cuser) != 0) | 1342 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
1343 | if (strcmp(cp, cuser) != 0) | ||
1344 | fail++; | 1344 | fail++; |
1345 | free(p); | 1345 | free(cp); |
1346 | 1346 | ||
1347 | if (buffer_len(&b) != 0) | 1347 | if (sshbuf_len(b) != 0) |
1348 | fail++; | 1348 | fail++; |
1349 | buffer_free(&b); | 1349 | sshbuf_free(b); |
1350 | return (fail == 0); | 1350 | return (fail == 0); |
1351 | } | 1351 | } |
1352 | 1352 | ||
@@ -1462,15 +1462,15 @@ mm_session_close(Session *s) | |||
1462 | } | 1462 | } |
1463 | 1463 | ||
1464 | int | 1464 | int |
1465 | mm_answer_pty(int sock, Buffer *m) | 1465 | mm_answer_pty(int sock, struct sshbuf *m) |
1466 | { | 1466 | { |
1467 | extern struct monitor *pmonitor; | 1467 | extern struct monitor *pmonitor; |
1468 | Session *s; | 1468 | Session *s; |
1469 | int res, fd0; | 1469 | int r, res, fd0; |
1470 | 1470 | ||
1471 | debug3("%s entering", __func__); | 1471 | debug3("%s entering", __func__); |
1472 | 1472 | ||
1473 | buffer_clear(m); | 1473 | sshbuf_reset(m); |
1474 | s = session_new(); | 1474 | s = session_new(); |
1475 | if (s == NULL) | 1475 | if (s == NULL) |
1476 | goto error; | 1476 | goto error; |
@@ -1482,8 +1482,9 @@ mm_answer_pty(int sock, Buffer *m) | |||
1482 | goto error; | 1482 | goto error; |
1483 | pty_setowner(authctxt->pw, s->tty); | 1483 | pty_setowner(authctxt->pw, s->tty); |
1484 | 1484 | ||
1485 | buffer_put_int(m, 1); | 1485 | if ((r = sshbuf_put_u32(m, 1)) != 0 || |
1486 | buffer_put_cstring(m, s->tty); | 1486 | (r = sshbuf_put_cstring(m, s->tty)) != 0) |
1487 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1487 | 1488 | ||
1488 | /* We need to trick ttyslot */ | 1489 | /* We need to trick ttyslot */ |
1489 | if (dup2(s->ttyfd, 0) == -1) | 1490 | if (dup2(s->ttyfd, 0) == -1) |
@@ -1495,8 +1496,9 @@ mm_answer_pty(int sock, Buffer *m) | |||
1495 | close(0); | 1496 | close(0); |
1496 | 1497 | ||
1497 | /* send messages generated by record_login */ | 1498 | /* send messages generated by record_login */ |
1498 | buffer_put_string(m, buffer_ptr(&loginmsg), buffer_len(&loginmsg)); | 1499 | if ((r = sshbuf_put_stringb(m, loginmsg)) != 0) |
1499 | buffer_clear(&loginmsg); | 1500 | fatal("%s: put login message: %s", __func__, ssh_err(r)); |
1501 | sshbuf_reset(loginmsg); | ||
1500 | 1502 | ||
1501 | mm_request_send(sock, MONITOR_ANS_PTY, m); | 1503 | mm_request_send(sock, MONITOR_ANS_PTY, m); |
1502 | 1504 | ||
@@ -1523,29 +1525,32 @@ mm_answer_pty(int sock, Buffer *m) | |||
1523 | error: | 1525 | error: |
1524 | if (s != NULL) | 1526 | if (s != NULL) |
1525 | mm_session_close(s); | 1527 | mm_session_close(s); |
1526 | buffer_put_int(m, 0); | 1528 | if ((r = sshbuf_put_u32(m, 0)) != 0) |
1529 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1527 | mm_request_send(sock, MONITOR_ANS_PTY, m); | 1530 | mm_request_send(sock, MONITOR_ANS_PTY, m); |
1528 | return (0); | 1531 | return (0); |
1529 | } | 1532 | } |
1530 | 1533 | ||
1531 | int | 1534 | int |
1532 | mm_answer_pty_cleanup(int sock, Buffer *m) | 1535 | mm_answer_pty_cleanup(int sock, struct sshbuf *m) |
1533 | { | 1536 | { |
1534 | Session *s; | 1537 | Session *s; |
1535 | char *tty; | 1538 | char *tty; |
1539 | int r; | ||
1536 | 1540 | ||
1537 | debug3("%s entering", __func__); | 1541 | debug3("%s entering", __func__); |
1538 | 1542 | ||
1539 | tty = buffer_get_string(m, NULL); | 1543 | if ((r = sshbuf_get_cstring(m, &tty, NULL)) != 0) |
1544 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1540 | if ((s = session_by_tty(tty)) != NULL) | 1545 | if ((s = session_by_tty(tty)) != NULL) |
1541 | mm_session_close(s); | 1546 | mm_session_close(s); |
1542 | buffer_clear(m); | 1547 | sshbuf_reset(m); |
1543 | free(tty); | 1548 | free(tty); |
1544 | return (0); | 1549 | return (0); |
1545 | } | 1550 | } |
1546 | 1551 | ||
1547 | int | 1552 | int |
1548 | mm_answer_term(int sock, Buffer *req) | 1553 | mm_answer_term(int sock, struct sshbuf *req) |
1549 | { | 1554 | { |
1550 | struct ssh *ssh = active_state; /* XXX */ | 1555 | struct ssh *ssh = active_state; /* XXX */ |
1551 | extern struct monitor *pmonitor; | 1556 | extern struct monitor *pmonitor; |
@@ -1574,14 +1579,18 @@ mm_answer_term(int sock, Buffer *req) | |||
1574 | #ifdef SSH_AUDIT_EVENTS | 1579 | #ifdef SSH_AUDIT_EVENTS |
1575 | /* Report that an audit event occurred */ | 1580 | /* Report that an audit event occurred */ |
1576 | int | 1581 | int |
1577 | mm_answer_audit_event(int socket, Buffer *m) | 1582 | mm_answer_audit_event(int socket, struct sshbuf *m) |
1578 | { | 1583 | { |
1584 | u_int n; | ||
1579 | ssh_audit_event_t event; | 1585 | ssh_audit_event_t event; |
1586 | int r; | ||
1580 | 1587 | ||
1581 | debug3("%s entering", __func__); | 1588 | debug3("%s entering", __func__); |
1582 | 1589 | ||
1583 | event = buffer_get_int(m); | 1590 | if ((r = sshbuf_get_u32(m, &n)) != 0) |
1584 | switch(event) { | 1591 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
1592 | event = (ssh_audit_event_t)n; | ||
1593 | switch (event) { | ||
1585 | case SSH_AUTH_FAIL_PUBKEY: | 1594 | case SSH_AUTH_FAIL_PUBKEY: |
1586 | case SSH_AUTH_FAIL_HOSTBASED: | 1595 | case SSH_AUTH_FAIL_HOSTBASED: |
1587 | case SSH_AUTH_FAIL_GSSAPI: | 1596 | case SSH_AUTH_FAIL_GSSAPI: |
@@ -1599,13 +1608,14 @@ mm_answer_audit_event(int socket, Buffer *m) | |||
1599 | } | 1608 | } |
1600 | 1609 | ||
1601 | int | 1610 | int |
1602 | mm_answer_audit_command(int socket, Buffer *m) | 1611 | mm_answer_audit_command(int socket, struct sshbuf *m) |
1603 | { | 1612 | { |
1604 | u_int len; | ||
1605 | char *cmd; | 1613 | char *cmd; |
1614 | int r; | ||
1606 | 1615 | ||
1607 | debug3("%s entering", __func__); | 1616 | debug3("%s entering", __func__); |
1608 | cmd = buffer_get_string(m, &len); | 1617 | if ((r = sshbuf_get_cstring(m, &cmd, NULL)) != 0) |
1618 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1609 | /* sanity check command, if so how? */ | 1619 | /* sanity check command, if so how? */ |
1610 | audit_run_command(cmd); | 1620 | audit_run_command(cmd); |
1611 | free(cmd); | 1621 | free(cmd); |
@@ -1734,24 +1744,29 @@ monitor_reinit(struct monitor *mon) | |||
1734 | 1744 | ||
1735 | #ifdef GSSAPI | 1745 | #ifdef GSSAPI |
1736 | int | 1746 | int |
1737 | mm_answer_gss_setup_ctx(int sock, Buffer *m) | 1747 | mm_answer_gss_setup_ctx(int sock, struct sshbuf *m) |
1738 | { | 1748 | { |
1739 | gss_OID_desc goid; | 1749 | gss_OID_desc goid; |
1740 | OM_uint32 major; | 1750 | OM_uint32 major; |
1741 | u_int len; | 1751 | size_t len; |
1752 | u_char *p; | ||
1753 | int r; | ||
1742 | 1754 | ||
1743 | if (!options.gss_authentication) | 1755 | if (!options.gss_authentication) |
1744 | fatal("%s: GSSAPI authentication not enabled", __func__); | 1756 | fatal("%s: GSSAPI authentication not enabled", __func__); |
1745 | 1757 | ||
1746 | goid.elements = buffer_get_string(m, &len); | 1758 | if ((r = sshbuf_get_string(m, &p, &len)) != 0) |
1759 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1760 | goid.elements = p; | ||
1747 | goid.length = len; | 1761 | goid.length = len; |
1748 | 1762 | ||
1749 | major = ssh_gssapi_server_ctx(&gsscontext, &goid); | 1763 | major = ssh_gssapi_server_ctx(&gsscontext, &goid); |
1750 | 1764 | ||
1751 | free(goid.elements); | 1765 | free(goid.elements); |
1752 | 1766 | ||
1753 | buffer_clear(m); | 1767 | sshbuf_reset(m); |
1754 | buffer_put_int(m, major); | 1768 | if ((r = sshbuf_put_u32(m, major)) != 0) |
1769 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1755 | 1770 | ||
1756 | mm_request_send(sock, MONITOR_ANS_GSSSETUP, m); | 1771 | mm_request_send(sock, MONITOR_ANS_GSSSETUP, m); |
1757 | 1772 | ||
@@ -1762,26 +1777,27 @@ mm_answer_gss_setup_ctx(int sock, Buffer *m) | |||
1762 | } | 1777 | } |
1763 | 1778 | ||
1764 | int | 1779 | int |
1765 | mm_answer_gss_accept_ctx(int sock, Buffer *m) | 1780 | mm_answer_gss_accept_ctx(int sock, struct sshbuf *m) |
1766 | { | 1781 | { |
1767 | gss_buffer_desc in; | 1782 | gss_buffer_desc in; |
1768 | gss_buffer_desc out = GSS_C_EMPTY_BUFFER; | 1783 | gss_buffer_desc out = GSS_C_EMPTY_BUFFER; |
1769 | OM_uint32 major, minor; | 1784 | OM_uint32 major, minor; |
1770 | OM_uint32 flags = 0; /* GSI needs this */ | 1785 | OM_uint32 flags = 0; /* GSI needs this */ |
1771 | u_int len; | 1786 | int r; |
1772 | 1787 | ||
1773 | if (!options.gss_authentication) | 1788 | if (!options.gss_authentication) |
1774 | fatal("%s: GSSAPI authentication not enabled", __func__); | 1789 | fatal("%s: GSSAPI authentication not enabled", __func__); |
1775 | 1790 | ||
1776 | in.value = buffer_get_string(m, &len); | 1791 | if ((r = ssh_gssapi_get_buffer_desc(m, &in)) != 0) |
1777 | in.length = len; | 1792 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
1778 | major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags); | 1793 | major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags); |
1779 | free(in.value); | 1794 | free(in.value); |
1780 | 1795 | ||
1781 | buffer_clear(m); | 1796 | sshbuf_reset(m); |
1782 | buffer_put_int(m, major); | 1797 | if ((r = sshbuf_put_u32(m, major)) != 0 || |
1783 | buffer_put_string(m, out.value, out.length); | 1798 | (r = sshbuf_put_string(m, out.value, out.length)) != 0 || |
1784 | buffer_put_int(m, flags); | 1799 | (r = sshbuf_put_u32(m, flags)) != 0) |
1800 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1785 | mm_request_send(sock, MONITOR_ANS_GSSSTEP, m); | 1801 | mm_request_send(sock, MONITOR_ANS_GSSSTEP, m); |
1786 | 1802 | ||
1787 | gss_release_buffer(&minor, &out); | 1803 | gss_release_buffer(&minor, &out); |
@@ -1795,27 +1811,27 @@ mm_answer_gss_accept_ctx(int sock, Buffer *m) | |||
1795 | } | 1811 | } |
1796 | 1812 | ||
1797 | int | 1813 | int |
1798 | mm_answer_gss_checkmic(int sock, Buffer *m) | 1814 | mm_answer_gss_checkmic(int sock, struct sshbuf *m) |
1799 | { | 1815 | { |
1800 | gss_buffer_desc gssbuf, mic; | 1816 | gss_buffer_desc gssbuf, mic; |
1801 | OM_uint32 ret; | 1817 | OM_uint32 ret; |
1802 | u_int len; | 1818 | int r; |
1803 | 1819 | ||
1804 | if (!options.gss_authentication) | 1820 | if (!options.gss_authentication) |
1805 | fatal("%s: GSSAPI authentication not enabled", __func__); | 1821 | fatal("%s: GSSAPI authentication not enabled", __func__); |
1806 | 1822 | ||
1807 | gssbuf.value = buffer_get_string(m, &len); | 1823 | if ((r = ssh_gssapi_get_buffer_desc(m, &gssbuf)) != 0 || |
1808 | gssbuf.length = len; | 1824 | (r = ssh_gssapi_get_buffer_desc(m, &mic)) != 0) |
1809 | mic.value = buffer_get_string(m, &len); | 1825 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
1810 | mic.length = len; | ||
1811 | 1826 | ||
1812 | ret = ssh_gssapi_checkmic(gsscontext, &gssbuf, &mic); | 1827 | ret = ssh_gssapi_checkmic(gsscontext, &gssbuf, &mic); |
1813 | 1828 | ||
1814 | free(gssbuf.value); | 1829 | free(gssbuf.value); |
1815 | free(mic.value); | 1830 | free(mic.value); |
1816 | 1831 | ||
1817 | buffer_clear(m); | 1832 | sshbuf_reset(m); |
1818 | buffer_put_int(m, ret); | 1833 | if ((r = sshbuf_put_u32(m, ret)) != 0) |
1834 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1819 | 1835 | ||
1820 | mm_request_send(sock, MONITOR_ANS_GSSCHECKMIC, m); | 1836 | mm_request_send(sock, MONITOR_ANS_GSSCHECKMIC, m); |
1821 | 1837 | ||
@@ -1826,9 +1842,9 @@ mm_answer_gss_checkmic(int sock, Buffer *m) | |||
1826 | } | 1842 | } |
1827 | 1843 | ||
1828 | int | 1844 | int |
1829 | mm_answer_gss_userok(int sock, Buffer *m) | 1845 | mm_answer_gss_userok(int sock, struct sshbuf *m) |
1830 | { | 1846 | { |
1831 | int authenticated; | 1847 | int r, authenticated; |
1832 | const char *displayname; | 1848 | const char *displayname; |
1833 | 1849 | ||
1834 | if (!options.gss_authentication) | 1850 | if (!options.gss_authentication) |
@@ -1836,8 +1852,9 @@ mm_answer_gss_userok(int sock, Buffer *m) | |||
1836 | 1852 | ||
1837 | authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user); | 1853 | authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user); |
1838 | 1854 | ||
1839 | buffer_clear(m); | 1855 | sshbuf_reset(m); |
1840 | buffer_put_int(m, authenticated); | 1856 | if ((r = sshbuf_put_u32(m, authenticated)) != 0) |
1857 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1841 | 1858 | ||
1842 | debug3("%s: sending result %d", __func__, authenticated); | 1859 | debug3("%s: sending result %d", __func__, authenticated); |
1843 | mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); | 1860 | mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); |