diff options
author | markus@openbsd.org <markus@openbsd.org> | 2018-07-09 21:53:45 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2018-07-10 16:40:18 +1000 |
commit | 235c7c4e3bf046982c2d8242f30aacffa01073d1 (patch) | |
tree | fd07c3d2ef2b932e23f26bbfdb4336e1fcfef3a9 /monitor.c | |
parent | b8d9214d969775e409e1408ecdf0d58fad99b344 (diff) |
upstream: sshd: switch monitor to sshbuf API; lots of help & ok
djm@
OpenBSD-Commit-ID: d89bd02d33974fd35ca0b8940d88572227b34a48
Diffstat (limited to 'monitor.c')
-rw-r--r-- | monitor.c | 494 |
1 files changed, 278 insertions, 216 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: monitor.c,v 1.182 2018/07/09 21:35:50 markus Exp $ */ | 1 | /* $OpenBSD: monitor.c,v 1.183 2018/07/09 21:53:45 markus 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> |
@@ -69,7 +69,7 @@ | |||
69 | #include "xmalloc.h" | 69 | #include "xmalloc.h" |
70 | #include "ssh.h" | 70 | #include "ssh.h" |
71 | #include "key.h" | 71 | #include "key.h" |
72 | #include "buffer.h" | 72 | #include "sshbuf.h" |
73 | #include "hostfile.h" | 73 | #include "hostfile.h" |
74 | #include "auth.h" | 74 | #include "auth.h" |
75 | #include "cipher.h" | 75 | #include "cipher.h" |
@@ -121,46 +121,46 @@ static struct sshbuf *child_state; | |||
121 | 121 | ||
122 | /* Functions on the monitor that answer unprivileged requests */ | 122 | /* Functions on the monitor that answer unprivileged requests */ |
123 | 123 | ||
124 | int mm_answer_moduli(int, Buffer *); | 124 | int mm_answer_moduli(int, struct sshbuf *); |
125 | int mm_answer_sign(int, Buffer *); | 125 | int mm_answer_sign(int, struct sshbuf *); |
126 | int mm_answer_pwnamallow(int, Buffer *); | 126 | int mm_answer_pwnamallow(int, struct sshbuf *); |
127 | int mm_answer_auth2_read_banner(int, Buffer *); | 127 | int mm_answer_auth2_read_banner(int, struct sshbuf *); |
128 | int mm_answer_authserv(int, Buffer *); | 128 | int mm_answer_authserv(int, struct sshbuf *); |
129 | int mm_answer_authpassword(int, Buffer *); | 129 | int mm_answer_authpassword(int, struct sshbuf *); |
130 | int mm_answer_bsdauthquery(int, Buffer *); | 130 | int mm_answer_bsdauthquery(int, struct sshbuf *); |
131 | int mm_answer_bsdauthrespond(int, Buffer *); | 131 | int mm_answer_bsdauthrespond(int, struct sshbuf *); |
132 | int mm_answer_skeyquery(int, Buffer *); | 132 | int mm_answer_skeyquery(int, struct sshbuf *); |
133 | int mm_answer_skeyrespond(int, Buffer *); | 133 | int mm_answer_skeyrespond(int, struct sshbuf *); |
134 | int mm_answer_keyallowed(int, Buffer *); | 134 | int mm_answer_keyallowed(int, struct sshbuf *); |
135 | int mm_answer_keyverify(int, Buffer *); | 135 | int mm_answer_keyverify(int, struct sshbuf *); |
136 | int mm_answer_pty(int, Buffer *); | 136 | int mm_answer_pty(int, struct sshbuf *); |
137 | int mm_answer_pty_cleanup(int, Buffer *); | 137 | int mm_answer_pty_cleanup(int, struct sshbuf *); |
138 | int mm_answer_term(int, Buffer *); | 138 | int mm_answer_term(int, struct sshbuf *); |
139 | int mm_answer_rsa_keyallowed(int, Buffer *); | 139 | int mm_answer_rsa_keyallowed(int, struct sshbuf *); |
140 | int mm_answer_rsa_challenge(int, Buffer *); | 140 | int mm_answer_rsa_challenge(int, struct sshbuf *); |
141 | int mm_answer_rsa_response(int, Buffer *); | 141 | int mm_answer_rsa_response(int, struct sshbuf *); |
142 | int mm_answer_sesskey(int, Buffer *); | 142 | int mm_answer_sesskey(int, struct sshbuf *); |
143 | int mm_answer_sessid(int, Buffer *); | 143 | int mm_answer_sessid(int, struct sshbuf *); |
144 | 144 | ||
145 | #ifdef USE_PAM | 145 | #ifdef USE_PAM |
146 | int mm_answer_pam_start(int, Buffer *); | 146 | int mm_answer_pam_start(int, struct sshbuf *); |
147 | int mm_answer_pam_account(int, Buffer *); | 147 | int mm_answer_pam_account(int, struct sshbuf *); |
148 | int mm_answer_pam_init_ctx(int, Buffer *); | 148 | int mm_answer_pam_init_ctx(int, struct sshbuf *); |
149 | int mm_answer_pam_query(int, Buffer *); | 149 | int mm_answer_pam_query(int, struct sshbuf *); |
150 | int mm_answer_pam_respond(int, Buffer *); | 150 | int mm_answer_pam_respond(int, struct sshbuf *); |
151 | int mm_answer_pam_free_ctx(int, Buffer *); | 151 | int mm_answer_pam_free_ctx(int, struct sshbuf *); |
152 | #endif | 152 | #endif |
153 | 153 | ||
154 | #ifdef GSSAPI | 154 | #ifdef GSSAPI |
155 | int mm_answer_gss_setup_ctx(int, Buffer *); | 155 | int mm_answer_gss_setup_ctx(int, struct sshbuf *); |
156 | int mm_answer_gss_accept_ctx(int, Buffer *); | 156 | int mm_answer_gss_accept_ctx(int, struct sshbuf *); |
157 | int mm_answer_gss_userok(int, Buffer *); | 157 | int mm_answer_gss_userok(int, struct sshbuf *); |
158 | int mm_answer_gss_checkmic(int, Buffer *); | 158 | int mm_answer_gss_checkmic(int, struct sshbuf *); |
159 | #endif | 159 | #endif |
160 | 160 | ||
161 | #ifdef SSH_AUDIT_EVENTS | 161 | #ifdef SSH_AUDIT_EVENTS |
162 | int mm_answer_audit_event(int, Buffer *); | 162 | int mm_answer_audit_event(int, struct sshbuf *); |
163 | int mm_answer_audit_command(int, Buffer *); | 163 | int mm_answer_audit_command(int, struct sshbuf *); |
164 | #endif | 164 | #endif |
165 | 165 | ||
166 | static int monitor_read_log(struct monitor *); | 166 | static int monitor_read_log(struct monitor *); |
@@ -169,7 +169,7 @@ static Authctxt *authctxt; | |||
169 | 169 | ||
170 | /* local state for key verify */ | 170 | /* local state for key verify */ |
171 | static u_char *key_blob = NULL; | 171 | static u_char *key_blob = NULL; |
172 | static u_int key_bloblen = 0; | 172 | static size_t key_bloblen = 0; |
173 | static int key_blobtype = MM_NOKEY; | 173 | static int key_blobtype = MM_NOKEY; |
174 | static struct sshauthopt *key_opts = NULL; | 174 | static struct sshauthopt *key_opts = NULL; |
175 | static char *hostbased_cuser = NULL; | 175 | static char *hostbased_cuser = NULL; |
@@ -183,7 +183,7 @@ static pid_t monitor_child_pid; | |||
183 | struct mon_table { | 183 | struct mon_table { |
184 | enum monitor_reqtype type; | 184 | enum monitor_reqtype type; |
185 | int flags; | 185 | int flags; |
186 | int (*f)(int, Buffer *); | 186 | int (*f)(int, struct sshbuf *); |
187 | }; | 187 | }; |
188 | 188 | ||
189 | #define MON_ISAUTH 0x0004 /* Required for Authentication */ | 189 | #define MON_ISAUTH 0x0004 /* Required for Authentication */ |
@@ -426,18 +426,21 @@ monitor_child_postauth(struct monitor *pmonitor) | |||
426 | static int | 426 | static int |
427 | monitor_read_log(struct monitor *pmonitor) | 427 | monitor_read_log(struct monitor *pmonitor) |
428 | { | 428 | { |
429 | Buffer logmsg; | 429 | struct sshbuf *logmsg; |
430 | u_int len, level; | 430 | u_int len, level; |
431 | char *msg; | 431 | char *msg; |
432 | u_char *p; | ||
433 | int r; | ||
432 | 434 | ||
433 | buffer_init(&logmsg); | 435 | if ((logmsg = sshbuf_new()) == NULL) |
436 | fatal("%s: sshbuf_new", __func__); | ||
434 | 437 | ||
435 | /* Read length */ | 438 | /* Read length */ |
436 | buffer_append_space(&logmsg, 4); | 439 | if ((r = sshbuf_reserve(logmsg, 4, &p)) != 0) |
437 | if (atomicio(read, pmonitor->m_log_recvfd, | 440 | fatal("%s: reserve: %s", __func__, ssh_err(r)); |
438 | buffer_ptr(&logmsg), buffer_len(&logmsg)) != buffer_len(&logmsg)) { | 441 | if (atomicio(read, pmonitor->m_log_recvfd, p, 4) != 4) { |
439 | if (errno == EPIPE) { | 442 | if (errno == EPIPE) { |
440 | buffer_free(&logmsg); | 443 | sshbuf_free(logmsg); |
441 | debug("%s: child log fd closed", __func__); | 444 | debug("%s: child log fd closed", __func__); |
442 | close(pmonitor->m_log_recvfd); | 445 | close(pmonitor->m_log_recvfd); |
443 | pmonitor->m_log_recvfd = -1; | 446 | pmonitor->m_log_recvfd = -1; |
@@ -445,26 +448,28 @@ monitor_read_log(struct monitor *pmonitor) | |||
445 | } | 448 | } |
446 | fatal("%s: log fd read: %s", __func__, strerror(errno)); | 449 | fatal("%s: log fd read: %s", __func__, strerror(errno)); |
447 | } | 450 | } |
448 | len = buffer_get_int(&logmsg); | 451 | if ((r = sshbuf_get_u32(logmsg, &len)) != 0) |
452 | fatal("%s: get len: %s", __func__, ssh_err(r)); | ||
449 | if (len <= 4 || len > 8192) | 453 | if (len <= 4 || len > 8192) |
450 | fatal("%s: invalid log message length %u", __func__, len); | 454 | fatal("%s: invalid log message length %u", __func__, len); |
451 | 455 | ||
452 | /* Read severity, message */ | 456 | /* Read severity, message */ |
453 | buffer_clear(&logmsg); | 457 | sshbuf_reset(logmsg); |
454 | buffer_append_space(&logmsg, len); | 458 | if ((r = sshbuf_reserve(logmsg, len, &p)) != 0) |
455 | if (atomicio(read, pmonitor->m_log_recvfd, | 459 | fatal("%s: reserve: %s", __func__, ssh_err(r)); |
456 | buffer_ptr(&logmsg), buffer_len(&logmsg)) != buffer_len(&logmsg)) | 460 | if (atomicio(read, pmonitor->m_log_recvfd, p, len) != len) |
457 | fatal("%s: log fd read: %s", __func__, strerror(errno)); | 461 | fatal("%s: log fd read: %s", __func__, strerror(errno)); |
462 | if ((r = sshbuf_get_u32(logmsg, &level)) != 0 || | ||
463 | (r = sshbuf_get_cstring(logmsg, &msg, NULL)) != 0) | ||
464 | fatal("%s: decode: %s", __func__, ssh_err(r)); | ||
458 | 465 | ||
459 | /* Log it */ | 466 | /* Log it */ |
460 | level = buffer_get_int(&logmsg); | ||
461 | msg = buffer_get_string(&logmsg, NULL); | ||
462 | if (log_level_name(level) == NULL) | 467 | if (log_level_name(level) == NULL) |
463 | fatal("%s: invalid log level %u (corrupted message?)", | 468 | fatal("%s: invalid log level %u (corrupted message?)", |
464 | __func__, level); | 469 | __func__, level); |
465 | do_log2(level, "%s [preauth]", msg); | 470 | do_log2(level, "%s [preauth]", msg); |
466 | 471 | ||
467 | buffer_free(&logmsg); | 472 | sshbuf_free(logmsg); |
468 | free(msg); | 473 | free(msg); |
469 | 474 | ||
470 | return 0; | 475 | return 0; |
@@ -474,8 +479,8 @@ int | |||
474 | monitor_read(struct monitor *pmonitor, struct mon_table *ent, | 479 | monitor_read(struct monitor *pmonitor, struct mon_table *ent, |
475 | struct mon_table **pent) | 480 | struct mon_table **pent) |
476 | { | 481 | { |
477 | Buffer m; | 482 | struct sshbuf *m; |
478 | int ret; | 483 | int r, ret; |
479 | u_char type; | 484 | u_char type; |
480 | struct pollfd pfd[2]; | 485 | struct pollfd pfd[2]; |
481 | 486 | ||
@@ -502,10 +507,12 @@ monitor_read(struct monitor *pmonitor, struct mon_table *ent, | |||
502 | break; /* Continues below */ | 507 | break; /* Continues below */ |
503 | } | 508 | } |
504 | 509 | ||
505 | buffer_init(&m); | 510 | if ((m = sshbuf_new()) == NULL) |
511 | fatal("%s: sshbuf_new", __func__); | ||
506 | 512 | ||
507 | mm_request_receive(pmonitor->m_sendfd, &m); | 513 | mm_request_receive(pmonitor->m_sendfd, m); |
508 | type = buffer_get_char(&m); | 514 | if ((r = sshbuf_get_u8(m, &type)) != 0) |
515 | fatal("%s: decode: %s", __func__, ssh_err(r)); | ||
509 | 516 | ||
510 | debug3("%s: checking request %d", __func__, type); | 517 | debug3("%s: checking request %d", __func__, type); |
511 | 518 | ||
@@ -519,8 +526,8 @@ monitor_read(struct monitor *pmonitor, struct mon_table *ent, | |||
519 | if (!(ent->flags & MON_PERMIT)) | 526 | if (!(ent->flags & MON_PERMIT)) |
520 | fatal("%s: unpermitted request %d", __func__, | 527 | fatal("%s: unpermitted request %d", __func__, |
521 | type); | 528 | type); |
522 | ret = (*ent->f)(pmonitor->m_sendfd, &m); | 529 | ret = (*ent->f)(pmonitor->m_sendfd, m); |
523 | buffer_free(&m); | 530 | sshbuf_free(m); |
524 | 531 | ||
525 | /* The child may use this request only once, disable it */ | 532 | /* The child may use this request only once, disable it */ |
526 | if (ent->flags & MON_ONCE) { | 533 | if (ent->flags & MON_ONCE) { |
@@ -570,14 +577,16 @@ monitor_reset_key_state(void) | |||
570 | 577 | ||
571 | #ifdef WITH_OPENSSL | 578 | #ifdef WITH_OPENSSL |
572 | int | 579 | int |
573 | mm_answer_moduli(int sock, Buffer *m) | 580 | mm_answer_moduli(int sock, struct sshbuf *m) |
574 | { | 581 | { |
575 | DH *dh; | 582 | DH *dh; |
576 | int min, want, max; | 583 | int r; |
584 | u_int min, want, max; | ||
577 | 585 | ||
578 | min = buffer_get_int(m); | 586 | if ((r = sshbuf_get_u32(m, &min)) != 0 || |
579 | want = buffer_get_int(m); | 587 | (r = sshbuf_get_u32(m, &want)) != 0 || |
580 | max = buffer_get_int(m); | 588 | (r = sshbuf_get_u32(m, &max)) != 0) |
589 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
581 | 590 | ||
582 | debug3("%s: got parameters: %d %d %d", | 591 | debug3("%s: got parameters: %d %d %d", |
583 | __func__, min, want, max); | 592 | __func__, min, want, max); |
@@ -586,17 +595,19 @@ mm_answer_moduli(int sock, Buffer *m) | |||
586 | fatal("%s: bad parameters: %d %d %d", | 595 | fatal("%s: bad parameters: %d %d %d", |
587 | __func__, min, want, max); | 596 | __func__, min, want, max); |
588 | 597 | ||
589 | buffer_clear(m); | 598 | sshbuf_reset(m); |
590 | 599 | ||
591 | dh = choose_dh(min, want, max); | 600 | dh = choose_dh(min, want, max); |
592 | if (dh == NULL) { | 601 | if (dh == NULL) { |
593 | buffer_put_char(m, 0); | 602 | if ((r = sshbuf_put_u8(m, 0)) != 0) |
603 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
594 | return (0); | 604 | return (0); |
595 | } else { | 605 | } else { |
596 | /* Send first bignum */ | 606 | /* Send first bignum */ |
597 | buffer_put_char(m, 1); | 607 | if ((r = sshbuf_put_u8(m, 1)) != 0 || |
598 | buffer_put_bignum2(m, dh->p); | 608 | (r = sshbuf_put_bignum2(m, dh->p)) != 0 || |
599 | buffer_put_bignum2(m, dh->g); | 609 | (r = sshbuf_put_bignum2(m, dh->g)) != 0) |
610 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
600 | 611 | ||
601 | DH_free(dh); | 612 | DH_free(dh); |
602 | } | 613 | } |
@@ -606,7 +617,7 @@ mm_answer_moduli(int sock, Buffer *m) | |||
606 | #endif | 617 | #endif |
607 | 618 | ||
608 | int | 619 | int |
609 | mm_answer_sign(int sock, Buffer *m) | 620 | mm_answer_sign(int sock, struct sshbuf *m) |
610 | { | 621 | { |
611 | struct ssh *ssh = active_state; /* XXX */ | 622 | struct ssh *ssh = active_state; /* XXX */ |
612 | extern int auth_sock; /* XXX move to state struct? */ | 623 | extern int auth_sock; /* XXX move to state struct? */ |
@@ -708,12 +719,12 @@ mm_answer_sign(int sock, Buffer *m) | |||
708 | /* Retrieves the password entry and also checks if the user is permitted */ | 719 | /* Retrieves the password entry and also checks if the user is permitted */ |
709 | 720 | ||
710 | int | 721 | int |
711 | mm_answer_pwnamallow(int sock, Buffer *m) | 722 | mm_answer_pwnamallow(int sock, struct sshbuf *m) |
712 | { | 723 | { |
713 | struct ssh *ssh = active_state; /* XXX */ | 724 | struct ssh *ssh = active_state; /* XXX */ |
714 | char *username; | 725 | char *username; |
715 | struct passwd *pwent; | 726 | struct passwd *pwent; |
716 | int allowed = 0; | 727 | int r, allowed = 0; |
717 | u_int i; | 728 | u_int i; |
718 | 729 | ||
719 | debug3("%s", __func__); | 730 | debug3("%s", __func__); |
@@ -721,7 +732,8 @@ mm_answer_pwnamallow(int sock, Buffer *m) | |||
721 | if (authctxt->attempt++ != 0) | 732 | if (authctxt->attempt++ != 0) |
722 | fatal("%s: multiple attempts for getpwnam", __func__); | 733 | fatal("%s: multiple attempts for getpwnam", __func__); |
723 | 734 | ||
724 | username = buffer_get_string(m, NULL); | 735 | if ((r = sshbuf_get_cstring(m, &username, NULL)) != 0) |
736 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
725 | 737 | ||
726 | pwent = getpwnamallow(username); | 738 | pwent = getpwnamallow(username); |
727 | 739 | ||
@@ -729,10 +741,11 @@ mm_answer_pwnamallow(int sock, Buffer *m) | |||
729 | setproctitle("%s [priv]", pwent ? username : "unknown"); | 741 | setproctitle("%s [priv]", pwent ? username : "unknown"); |
730 | free(username); | 742 | free(username); |
731 | 743 | ||
732 | buffer_clear(m); | 744 | sshbuf_reset(m); |
733 | 745 | ||
734 | if (pwent == NULL) { | 746 | if (pwent == NULL) { |
735 | buffer_put_char(m, 0); | 747 | if ((r = sshbuf_put_u8(m, 0)) != 0) |
748 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
736 | authctxt->pw = fakepw(); | 749 | authctxt->pw = fakepw(); |
737 | goto out; | 750 | goto out; |
738 | } | 751 | } |
@@ -741,31 +754,40 @@ mm_answer_pwnamallow(int sock, Buffer *m) | |||
741 | authctxt->pw = pwent; | 754 | authctxt->pw = pwent; |
742 | authctxt->valid = 1; | 755 | authctxt->valid = 1; |
743 | 756 | ||
744 | buffer_put_char(m, 1); | 757 | /* XXX don't sent pwent to unpriv; send fake class/dir/shell too */ |
745 | buffer_put_string(m, pwent, sizeof(struct passwd)); | 758 | if ((r = sshbuf_put_u8(m, 1)) != 0 || |
746 | buffer_put_cstring(m, pwent->pw_name); | 759 | (r = sshbuf_put_string(m, pwent, sizeof(*pwent))) != 0 || |
747 | buffer_put_cstring(m, "*"); | 760 | (r = sshbuf_put_cstring(m, pwent->pw_name)) != 0 || |
761 | (r = sshbuf_put_cstring(m, "*")) != 0 || | ||
748 | #ifdef HAVE_STRUCT_PASSWD_PW_GECOS | 762 | #ifdef HAVE_STRUCT_PASSWD_PW_GECOS |
749 | buffer_put_cstring(m, pwent->pw_gecos); | 763 | (r = sshbuf_put_cstring(m, pwent->pw_gecos)) != 0 || |
750 | #endif | 764 | #endif |
751 | #ifdef HAVE_STRUCT_PASSWD_PW_CLASS | 765 | #ifdef HAVE_STRUCT_PASSWD_PW_CLASS |
752 | buffer_put_cstring(m, pwent->pw_class); | 766 | (r = sshbuf_put_cstring(m, pwent->pw_class)) != 0 || |
753 | #endif | 767 | #endif |
754 | buffer_put_cstring(m, pwent->pw_dir); | 768 | (r = sshbuf_put_cstring(m, pwent->pw_dir)) != 0 || |
755 | buffer_put_cstring(m, pwent->pw_shell); | 769 | (r = sshbuf_put_cstring(m, pwent->pw_shell)) != 0) |
770 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
756 | 771 | ||
757 | out: | 772 | out: |
758 | ssh_packet_set_log_preamble(ssh, "%suser %s", | 773 | ssh_packet_set_log_preamble(ssh, "%suser %s", |
759 | authctxt->valid ? "authenticating" : "invalid ", authctxt->user); | 774 | authctxt->valid ? "authenticating" : "invalid ", authctxt->user); |
760 | buffer_put_string(m, &options, sizeof(options)); | 775 | if ((r = sshbuf_put_string(m, &options, sizeof(options))) != 0) |
776 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
761 | 777 | ||
762 | #define M_CP_STROPT(x) do { \ | 778 | #define M_CP_STROPT(x) do { \ |
763 | if (options.x != NULL) \ | 779 | if (options.x != NULL) { \ |
764 | buffer_put_cstring(m, options.x); \ | 780 | if ((r = sshbuf_put_cstring(m, options.x)) != 0) \ |
781 | fatal("%s: buffer error: %s", \ | ||
782 | __func__, ssh_err(r)); \ | ||
783 | } \ | ||
765 | } while (0) | 784 | } while (0) |
766 | #define M_CP_STRARRAYOPT(x, nx) do { \ | 785 | #define M_CP_STRARRAYOPT(x, nx) do { \ |
767 | for (i = 0; i < options.nx; i++) \ | 786 | for (i = 0; i < options.nx; i++) { \ |
768 | buffer_put_cstring(m, options.x[i]); \ | 787 | if ((r = sshbuf_put_cstring(m, options.x[i])) != 0) \ |
788 | fatal("%s: buffer error: %s", \ | ||
789 | __func__, ssh_err(r)); \ | ||
790 | } \ | ||
769 | } while (0) | 791 | } while (0) |
770 | /* See comment in servconf.h */ | 792 | /* See comment in servconf.h */ |
771 | COPY_MATCH_STRING_OPTS(); | 793 | COPY_MATCH_STRING_OPTS(); |
@@ -797,13 +819,15 @@ mm_answer_pwnamallow(int sock, Buffer *m) | |||
797 | return (0); | 819 | return (0); |
798 | } | 820 | } |
799 | 821 | ||
800 | int mm_answer_auth2_read_banner(int sock, Buffer *m) | 822 | int mm_answer_auth2_read_banner(int sock, struct sshbuf *m) |
801 | { | 823 | { |
802 | char *banner; | 824 | char *banner; |
825 | int r; | ||
803 | 826 | ||
804 | buffer_clear(m); | 827 | sshbuf_reset(m); |
805 | banner = auth2_read_banner(); | 828 | banner = auth2_read_banner(); |
806 | buffer_put_cstring(m, banner != NULL ? banner : ""); | 829 | if ((r = sshbuf_put_cstring(m, banner != NULL ? banner : "")) != 0) |
830 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
807 | mm_request_send(sock, MONITOR_ANS_AUTH2_READ_BANNER, m); | 831 | mm_request_send(sock, MONITOR_ANS_AUTH2_READ_BANNER, m); |
808 | free(banner); | 832 | free(banner); |
809 | 833 | ||
@@ -811,12 +835,15 @@ int mm_answer_auth2_read_banner(int sock, Buffer *m) | |||
811 | } | 835 | } |
812 | 836 | ||
813 | int | 837 | int |
814 | mm_answer_authserv(int sock, Buffer *m) | 838 | mm_answer_authserv(int sock, struct sshbuf *m) |
815 | { | 839 | { |
840 | int r; | ||
841 | |||
816 | monitor_permit_authentications(1); | 842 | monitor_permit_authentications(1); |
817 | 843 | ||
818 | authctxt->service = buffer_get_string(m, NULL); | 844 | if ((r = sshbuf_get_cstring(m, &authctxt->service, NULL)) != 0 || |
819 | authctxt->style = buffer_get_string(m, NULL); | 845 | (r = sshbuf_get_cstring(m, &authctxt->style, NULL)) != 0) |
846 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
820 | debug3("%s: service=%s, style=%s", | 847 | debug3("%s: service=%s, style=%s", |
821 | __func__, authctxt->service, authctxt->style); | 848 | __func__, authctxt->service, authctxt->style); |
822 | 849 | ||
@@ -829,27 +856,30 @@ mm_answer_authserv(int sock, Buffer *m) | |||
829 | } | 856 | } |
830 | 857 | ||
831 | int | 858 | int |
832 | mm_answer_authpassword(int sock, Buffer *m) | 859 | mm_answer_authpassword(int sock, struct sshbuf *m) |
833 | { | 860 | { |
834 | struct ssh *ssh = active_state; /* XXX */ | 861 | struct ssh *ssh = active_state; /* XXX */ |
835 | static int call_count; | 862 | static int call_count; |
836 | char *passwd; | 863 | char *passwd; |
837 | int authenticated; | 864 | int r, authenticated; |
838 | u_int plen; | 865 | size_t plen; |
839 | 866 | ||
840 | if (!options.password_authentication) | 867 | if (!options.password_authentication) |
841 | fatal("%s: password authentication not enabled", __func__); | 868 | fatal("%s: password authentication not enabled", __func__); |
842 | passwd = buffer_get_string(m, &plen); | 869 | if ((r = sshbuf_get_cstring(m, &passwd, &plen)) != 0) |
870 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
843 | /* Only authenticate if the context is valid */ | 871 | /* Only authenticate if the context is valid */ |
844 | authenticated = options.password_authentication && | 872 | authenticated = options.password_authentication && |
845 | auth_password(ssh, passwd); | 873 | auth_password(ssh, passwd); |
846 | explicit_bzero(passwd, strlen(passwd)); | 874 | explicit_bzero(passwd, plen); |
847 | free(passwd); | 875 | free(passwd); |
848 | 876 | ||
849 | buffer_clear(m); | 877 | sshbuf_reset(m); |
850 | buffer_put_int(m, authenticated); | 878 | if ((r = sshbuf_put_u32(m, authenticated)) != 0) |
879 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
851 | #ifdef USE_PAM | 880 | #ifdef USE_PAM |
852 | buffer_put_int(m, sshpam_get_maxtries_reached()); | 881 | if ((r = sshbuf_put_u32(m, sshpam_get_maxtries_reached())) != 0) |
882 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
853 | #endif | 883 | #endif |
854 | 884 | ||
855 | debug3("%s: sending result %d", __func__, authenticated); | 885 | debug3("%s: sending result %d", __func__, authenticated); |
@@ -867,23 +897,25 @@ mm_answer_authpassword(int sock, Buffer *m) | |||
867 | 897 | ||
868 | #ifdef BSD_AUTH | 898 | #ifdef BSD_AUTH |
869 | int | 899 | int |
870 | mm_answer_bsdauthquery(int sock, Buffer *m) | 900 | mm_answer_bsdauthquery(int sock, struct sshbuf *m) |
871 | { | 901 | { |
872 | char *name, *infotxt; | 902 | char *name, *infotxt; |
873 | u_int numprompts; | 903 | u_int numprompts, *echo_on, success; |
874 | u_int *echo_on; | ||
875 | char **prompts; | 904 | char **prompts; |
876 | u_int success; | 905 | int r; |
877 | 906 | ||
878 | if (!options.kbd_interactive_authentication) | 907 | if (!options.kbd_interactive_authentication) |
879 | fatal("%s: kbd-int authentication not enabled", __func__); | 908 | fatal("%s: kbd-int authentication not enabled", __func__); |
880 | success = bsdauth_query(authctxt, &name, &infotxt, &numprompts, | 909 | success = bsdauth_query(authctxt, &name, &infotxt, &numprompts, |
881 | &prompts, &echo_on) < 0 ? 0 : 1; | 910 | &prompts, &echo_on) < 0 ? 0 : 1; |
882 | 911 | ||
883 | buffer_clear(m); | 912 | sshbuf_reset(m); |
884 | buffer_put_int(m, success); | 913 | if ((r = sshbuf_put_u32(m, success)) != 0) |
885 | if (success) | 914 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
886 | buffer_put_cstring(m, prompts[0]); | 915 | if (success) { |
916 | if ((r = sshbuf_put_cstring(m, prompts[0])) != 0) | ||
917 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
918 | } | ||
887 | 919 | ||
888 | debug3("%s: sending challenge success: %u", __func__, success); | 920 | debug3("%s: sending challenge success: %u", __func__, success); |
889 | mm_request_send(sock, MONITOR_ANS_BSDAUTHQUERY, m); | 921 | mm_request_send(sock, MONITOR_ANS_BSDAUTHQUERY, m); |
@@ -899,25 +931,27 @@ mm_answer_bsdauthquery(int sock, Buffer *m) | |||
899 | } | 931 | } |
900 | 932 | ||
901 | int | 933 | int |
902 | mm_answer_bsdauthrespond(int sock, Buffer *m) | 934 | mm_answer_bsdauthrespond(int sock, struct sshbuf *m) |
903 | { | 935 | { |
904 | char *response; | 936 | char *response; |
905 | int authok; | 937 | int r, authok; |
906 | 938 | ||
907 | if (!options.kbd_interactive_authentication) | 939 | if (!options.kbd_interactive_authentication) |
908 | fatal("%s: kbd-int authentication not enabled", __func__); | 940 | fatal("%s: kbd-int authentication not enabled", __func__); |
909 | if (authctxt->as == NULL) | 941 | if (authctxt->as == NULL) |
910 | fatal("%s: no bsd auth session", __func__); | 942 | fatal("%s: no bsd auth session", __func__); |
911 | 943 | ||
912 | response = buffer_get_string(m, NULL); | 944 | if ((r = sshbuf_get_cstring(m, &response, NULL)) != 0) |
945 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
913 | authok = options.challenge_response_authentication && | 946 | authok = options.challenge_response_authentication && |
914 | auth_userresponse(authctxt->as, response, 0); | 947 | auth_userresponse(authctxt->as, response, 0); |
915 | authctxt->as = NULL; | 948 | authctxt->as = NULL; |
916 | debug3("%s: <%s> = <%d>", __func__, response, authok); | 949 | debug3("%s: <%s> = <%d>", __func__, response, authok); |
917 | free(response); | 950 | free(response); |
918 | 951 | ||
919 | buffer_clear(m); | 952 | sshbuf_reset(m); |
920 | buffer_put_int(m, authok); | 953 | if ((r = sshbuf_put_u32(m, authok)) != 0) |
954 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
921 | 955 | ||
922 | debug3("%s: sending authenticated: %d", __func__, authok); | 956 | debug3("%s: sending authenticated: %d", __func__, authok); |
923 | mm_request_send(sock, MONITOR_ANS_BSDAUTHRESPOND, m); | 957 | mm_request_send(sock, MONITOR_ANS_BSDAUTHRESPOND, m); |
@@ -1131,25 +1165,23 @@ mm_answer_pam_free_ctx(int sock, Buffer *m) | |||
1131 | #endif | 1165 | #endif |
1132 | 1166 | ||
1133 | int | 1167 | int |
1134 | mm_answer_keyallowed(int sock, Buffer *m) | 1168 | mm_answer_keyallowed(int sock, struct sshbuf *m) |
1135 | { | 1169 | { |
1136 | struct ssh *ssh = active_state; /* XXX */ | 1170 | struct ssh *ssh = active_state; /* XXX */ |
1137 | struct sshkey *key; | 1171 | struct sshkey *key = NULL; |
1138 | char *cuser, *chost; | 1172 | char *cuser, *chost; |
1139 | u_char *blob; | 1173 | u_int pubkey_auth_attempt; |
1140 | u_int bloblen, pubkey_auth_attempt; | ||
1141 | enum mm_keytype type = 0; | 1174 | enum mm_keytype type = 0; |
1142 | int r, allowed = 0; | 1175 | int r, allowed = 0; |
1143 | struct sshauthopt *opts = NULL; | 1176 | struct sshauthopt *opts = NULL; |
1144 | 1177 | ||
1145 | debug3("%s entering", __func__); | 1178 | debug3("%s entering", __func__); |
1146 | type = buffer_get_int(m); | 1179 | if ((r = sshbuf_get_u32(m, &type)) != 0 || |
1147 | cuser = buffer_get_string(m, NULL); | 1180 | (r = sshbuf_get_cstring(m, &cuser, NULL)) != 0 || |
1148 | chost = buffer_get_string(m, NULL); | 1181 | (r = sshbuf_get_cstring(m, &chost, NULL)) != 0 || |
1149 | blob = buffer_get_string(m, &bloblen); | 1182 | (r = sshkey_froms(m, &key)) != 0 || |
1150 | pubkey_auth_attempt = buffer_get_int(m); | 1183 | (r = sshbuf_get_u32(m, &pubkey_auth_attempt)) != 0) |
1151 | 1184 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | |
1152 | key = key_from_blob(blob, bloblen); | ||
1153 | 1185 | ||
1154 | debug3("%s: key_from_blob: %p", __func__, key); | 1186 | debug3("%s: key_from_blob: %p", __func__, key); |
1155 | 1187 | ||
@@ -1199,15 +1231,14 @@ mm_answer_keyallowed(int sock, Buffer *m) | |||
1199 | allowed ? "allowed" : "not allowed"); | 1231 | allowed ? "allowed" : "not allowed"); |
1200 | 1232 | ||
1201 | auth2_record_key(authctxt, 0, key); | 1233 | auth2_record_key(authctxt, 0, key); |
1202 | sshkey_free(key); | ||
1203 | 1234 | ||
1204 | /* clear temporarily storage (used by verify) */ | 1235 | /* clear temporarily storage (used by verify) */ |
1205 | monitor_reset_key_state(); | 1236 | monitor_reset_key_state(); |
1206 | 1237 | ||
1207 | if (allowed) { | 1238 | if (allowed) { |
1208 | /* Save temporarily for comparison in verify */ | 1239 | /* Save temporarily for comparison in verify */ |
1209 | key_blob = blob; | 1240 | if ((r = sshkey_to_blob(key, &key_blob, &key_bloblen)) != 0) |
1210 | key_bloblen = bloblen; | 1241 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
1211 | key_blobtype = type; | 1242 | key_blobtype = type; |
1212 | key_opts = opts; | 1243 | key_opts = opts; |
1213 | hostbased_cuser = cuser; | 1244 | hostbased_cuser = cuser; |
@@ -1215,13 +1246,14 @@ mm_answer_keyallowed(int sock, Buffer *m) | |||
1215 | } else { | 1246 | } else { |
1216 | /* Log failed attempt */ | 1247 | /* Log failed attempt */ |
1217 | auth_log(authctxt, 0, 0, auth_method, NULL); | 1248 | auth_log(authctxt, 0, 0, auth_method, NULL); |
1218 | free(blob); | ||
1219 | free(cuser); | 1249 | free(cuser); |
1220 | free(chost); | 1250 | free(chost); |
1221 | } | 1251 | } |
1252 | sshkey_free(key); | ||
1222 | 1253 | ||
1223 | buffer_clear(m); | 1254 | sshbuf_reset(m); |
1224 | buffer_put_int(m, allowed); | 1255 | if ((r = sshbuf_put_u32(m, allowed)) != 0) |
1256 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1225 | if (opts != NULL && (r = sshauthopt_serialise(opts, m, 1)) != 0) | 1257 | if (opts != NULL && (r = sshauthopt_serialise(opts, m, 1)) != 0) |
1226 | fatal("%s: sshauthopt_serialise: %s", __func__, ssh_err(r)); | 1258 | fatal("%s: sshauthopt_serialise: %s", __func__, ssh_err(r)); |
1227 | mm_request_send(sock, MONITOR_ANS_KEYALLOWED, m); | 1259 | mm_request_send(sock, MONITOR_ANS_KEYALLOWED, m); |
@@ -1235,34 +1267,41 @@ mm_answer_keyallowed(int sock, Buffer *m) | |||
1235 | static int | 1267 | static int |
1236 | monitor_valid_userblob(u_char *data, u_int datalen) | 1268 | monitor_valid_userblob(u_char *data, u_int datalen) |
1237 | { | 1269 | { |
1238 | Buffer b; | 1270 | struct sshbuf *b; |
1239 | u_char *p; | 1271 | const u_char *p; |
1240 | char *userstyle, *cp; | 1272 | char *userstyle, *cp; |
1241 | u_int len; | 1273 | size_t len; |
1242 | int fail = 0; | 1274 | u_char type; |
1275 | int r, fail = 0; | ||
1243 | 1276 | ||
1244 | buffer_init(&b); | 1277 | if ((b = sshbuf_new()) == NULL) |
1245 | buffer_append(&b, data, datalen); | 1278 | fatal("%s: sshbuf_new", __func__); |
1279 | if ((r = sshbuf_put(b, data, datalen)) != 0) | ||
1280 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1246 | 1281 | ||
1247 | if (datafellows & SSH_OLD_SESSIONID) { | 1282 | if (datafellows & SSH_OLD_SESSIONID) { |
1248 | p = buffer_ptr(&b); | 1283 | p = sshbuf_ptr(b); |
1249 | len = buffer_len(&b); | 1284 | len = sshbuf_len(b); |
1250 | if ((session_id2 == NULL) || | 1285 | if ((session_id2 == NULL) || |
1251 | (len < session_id2_len) || | 1286 | (len < session_id2_len) || |
1252 | (timingsafe_bcmp(p, session_id2, session_id2_len) != 0)) | 1287 | (timingsafe_bcmp(p, session_id2, session_id2_len) != 0)) |
1253 | fail++; | 1288 | fail++; |
1254 | buffer_consume(&b, session_id2_len); | 1289 | if ((r = sshbuf_consume(b, session_id2_len)) != 0) |
1290 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1255 | } else { | 1291 | } else { |
1256 | p = buffer_get_string(&b, &len); | 1292 | if ((r = sshbuf_get_string_direct(b, &p, &len)) != 0) |
1293 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1257 | if ((session_id2 == NULL) || | 1294 | if ((session_id2 == NULL) || |
1258 | (len != session_id2_len) || | 1295 | (len != session_id2_len) || |
1259 | (timingsafe_bcmp(p, session_id2, session_id2_len) != 0)) | 1296 | (timingsafe_bcmp(p, session_id2, session_id2_len) != 0)) |
1260 | fail++; | 1297 | fail++; |
1261 | free(p); | ||
1262 | } | 1298 | } |
1263 | if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST) | 1299 | if ((r = sshbuf_get_u8(b, &type)) != 0) |
1300 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1301 | if (type != SSH2_MSG_USERAUTH_REQUEST) | ||
1264 | fail++; | 1302 | fail++; |
1265 | cp = buffer_get_cstring(&b, NULL); | 1303 | if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0) |
1304 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1266 | xasprintf(&userstyle, "%s%s%s", authctxt->user, | 1305 | xasprintf(&userstyle, "%s%s%s", authctxt->user, |
1267 | authctxt->style ? ":" : "", | 1306 | authctxt->style ? ":" : "", |
1268 | authctxt->style ? authctxt->style : ""); | 1307 | authctxt->style ? authctxt->style : ""); |
@@ -1273,18 +1312,22 @@ monitor_valid_userblob(u_char *data, u_int datalen) | |||
1273 | } | 1312 | } |
1274 | free(userstyle); | 1313 | free(userstyle); |
1275 | free(cp); | 1314 | free(cp); |
1276 | buffer_skip_string(&b); | 1315 | if ((r = sshbuf_skip_string(b)) != 0 || /* service */ |
1277 | cp = buffer_get_cstring(&b, NULL); | 1316 | (r = sshbuf_get_cstring(b, &cp, NULL)) != 0) |
1317 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1278 | if (strcmp("publickey", cp) != 0) | 1318 | if (strcmp("publickey", cp) != 0) |
1279 | fail++; | 1319 | fail++; |
1280 | free(cp); | 1320 | free(cp); |
1281 | if (!buffer_get_char(&b)) | 1321 | if ((r = sshbuf_get_u8(b, &type)) != 0) |
1322 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1323 | if (type == 0) | ||
1282 | fail++; | 1324 | fail++; |
1283 | buffer_skip_string(&b); | 1325 | if ((r = sshbuf_skip_string(b)) != 0 || /* pkalg */ |
1284 | buffer_skip_string(&b); | 1326 | (r = sshbuf_skip_string(b)) != 0) /* pkblob */ |
1285 | if (buffer_len(&b) != 0) | 1327 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
1328 | if (sshbuf_len(b) != 0) | ||
1286 | fail++; | 1329 | fail++; |
1287 | buffer_free(&b); | 1330 | sshbuf_free(b); |
1288 | return (fail == 0); | 1331 | return (fail == 0); |
1289 | } | 1332 | } |
1290 | 1333 | ||
@@ -1292,59 +1335,69 @@ static int | |||
1292 | monitor_valid_hostbasedblob(u_char *data, u_int datalen, char *cuser, | 1335 | monitor_valid_hostbasedblob(u_char *data, u_int datalen, char *cuser, |
1293 | char *chost) | 1336 | char *chost) |
1294 | { | 1337 | { |
1295 | Buffer b; | 1338 | struct sshbuf *b; |
1296 | char *p, *userstyle; | 1339 | const u_char *p; |
1297 | u_int len; | 1340 | char *cp, *userstyle; |
1298 | int fail = 0; | 1341 | size_t len; |
1342 | int r, fail = 0; | ||
1343 | u_char type; | ||
1299 | 1344 | ||
1300 | buffer_init(&b); | 1345 | if ((b = sshbuf_new()) == NULL) |
1301 | buffer_append(&b, data, datalen); | 1346 | fatal("%s: sshbuf_new", __func__); |
1347 | if ((r = sshbuf_put(b, data, datalen)) != 0 || | ||
1348 | (r = sshbuf_get_string_direct(b, &p, &len)) != 0) | ||
1349 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1302 | 1350 | ||
1303 | p = buffer_get_string(&b, &len); | ||
1304 | if ((session_id2 == NULL) || | 1351 | if ((session_id2 == NULL) || |
1305 | (len != session_id2_len) || | 1352 | (len != session_id2_len) || |
1306 | (timingsafe_bcmp(p, session_id2, session_id2_len) != 0)) | 1353 | (timingsafe_bcmp(p, session_id2, session_id2_len) != 0)) |
1307 | fail++; | 1354 | fail++; |
1308 | free(p); | ||
1309 | 1355 | ||
1310 | if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST) | 1356 | if ((r = sshbuf_get_u8(b, &type)) != 0) |
1357 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1358 | if (type != SSH2_MSG_USERAUTH_REQUEST) | ||
1311 | fail++; | 1359 | fail++; |
1312 | p = buffer_get_cstring(&b, NULL); | 1360 | if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0) |
1361 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1313 | xasprintf(&userstyle, "%s%s%s", authctxt->user, | 1362 | xasprintf(&userstyle, "%s%s%s", authctxt->user, |
1314 | authctxt->style ? ":" : "", | 1363 | authctxt->style ? ":" : "", |
1315 | authctxt->style ? authctxt->style : ""); | 1364 | authctxt->style ? authctxt->style : ""); |
1316 | if (strcmp(userstyle, p) != 0) { | 1365 | if (strcmp(userstyle, cp) != 0) { |
1317 | logit("wrong user name passed to monitor: expected %s != %.100s", | 1366 | logit("wrong user name passed to monitor: " |
1318 | userstyle, p); | 1367 | "expected %s != %.100s", userstyle, cp); |
1319 | fail++; | 1368 | fail++; |
1320 | } | 1369 | } |
1321 | free(userstyle); | 1370 | free(userstyle); |
1322 | free(p); | 1371 | free(cp); |
1323 | buffer_skip_string(&b); /* service */ | 1372 | if ((r = sshbuf_skip_string(b)) != 0 || /* service */ |
1324 | p = buffer_get_cstring(&b, NULL); | 1373 | (r = sshbuf_get_cstring(b, &cp, NULL)) != 0) |
1325 | if (strcmp(p, "hostbased") != 0) | 1374 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
1375 | if (strcmp(cp, "hostbased") != 0) | ||
1326 | fail++; | 1376 | fail++; |
1327 | free(p); | 1377 | free(cp); |
1328 | buffer_skip_string(&b); /* pkalg */ | 1378 | if ((r = sshbuf_skip_string(b)) != 0 || /* pkalg */ |
1329 | buffer_skip_string(&b); /* pkblob */ | 1379 | (r = sshbuf_skip_string(b)) != 0) /* pkblob */ |
1380 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1330 | 1381 | ||
1331 | /* verify client host, strip trailing dot if necessary */ | 1382 | /* verify client host, strip trailing dot if necessary */ |
1332 | p = buffer_get_string(&b, NULL); | 1383 | if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0) |
1333 | if (((len = strlen(p)) > 0) && p[len - 1] == '.') | 1384 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
1334 | p[len - 1] = '\0'; | 1385 | if (((len = strlen(cp)) > 0) && cp[len - 1] == '.') |
1335 | if (strcmp(p, chost) != 0) | 1386 | cp[len - 1] = '\0'; |
1387 | if (strcmp(cp, chost) != 0) | ||
1336 | fail++; | 1388 | fail++; |
1337 | free(p); | 1389 | free(cp); |
1338 | 1390 | ||
1339 | /* verify client user */ | 1391 | /* verify client user */ |
1340 | p = buffer_get_string(&b, NULL); | 1392 | if ((r = sshbuf_get_cstring(b, &cp, NULL)) != 0) |
1341 | if (strcmp(p, cuser) != 0) | 1393 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
1394 | if (strcmp(cp, cuser) != 0) | ||
1342 | fail++; | 1395 | fail++; |
1343 | free(p); | 1396 | free(cp); |
1344 | 1397 | ||
1345 | if (buffer_len(&b) != 0) | 1398 | if (sshbuf_len(b) != 0) |
1346 | fail++; | 1399 | fail++; |
1347 | buffer_free(&b); | 1400 | sshbuf_free(b); |
1348 | return (fail == 0); | 1401 | return (fail == 0); |
1349 | } | 1402 | } |
1350 | 1403 | ||
@@ -1460,15 +1513,15 @@ mm_session_close(Session *s) | |||
1460 | } | 1513 | } |
1461 | 1514 | ||
1462 | int | 1515 | int |
1463 | mm_answer_pty(int sock, Buffer *m) | 1516 | mm_answer_pty(int sock, struct sshbuf *m) |
1464 | { | 1517 | { |
1465 | extern struct monitor *pmonitor; | 1518 | extern struct monitor *pmonitor; |
1466 | Session *s; | 1519 | Session *s; |
1467 | int res, fd0; | 1520 | int r, res, fd0; |
1468 | 1521 | ||
1469 | debug3("%s entering", __func__); | 1522 | debug3("%s entering", __func__); |
1470 | 1523 | ||
1471 | buffer_clear(m); | 1524 | sshbuf_reset(m); |
1472 | s = session_new(); | 1525 | s = session_new(); |
1473 | if (s == NULL) | 1526 | if (s == NULL) |
1474 | goto error; | 1527 | goto error; |
@@ -1480,8 +1533,9 @@ mm_answer_pty(int sock, Buffer *m) | |||
1480 | goto error; | 1533 | goto error; |
1481 | pty_setowner(authctxt->pw, s->tty); | 1534 | pty_setowner(authctxt->pw, s->tty); |
1482 | 1535 | ||
1483 | buffer_put_int(m, 1); | 1536 | if ((r = sshbuf_put_u32(m, 1)) != 0 || |
1484 | buffer_put_cstring(m, s->tty); | 1537 | (r = sshbuf_put_cstring(m, s->tty)) != 0) |
1538 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1485 | 1539 | ||
1486 | /* We need to trick ttyslot */ | 1540 | /* We need to trick ttyslot */ |
1487 | if (dup2(s->ttyfd, 0) == -1) | 1541 | if (dup2(s->ttyfd, 0) == -1) |
@@ -1493,8 +1547,9 @@ mm_answer_pty(int sock, Buffer *m) | |||
1493 | close(0); | 1547 | close(0); |
1494 | 1548 | ||
1495 | /* send messages generated by record_login */ | 1549 | /* send messages generated by record_login */ |
1496 | buffer_put_string(m, buffer_ptr(loginmsg), buffer_len(loginmsg)); | 1550 | if ((r = sshbuf_put_stringb(m, loginmsg)) != 0) |
1497 | buffer_clear(loginmsg); | 1551 | fatal("%s: put login message: %s", __func__, ssh_err(r)); |
1552 | sshbuf_reset(loginmsg); | ||
1498 | 1553 | ||
1499 | mm_request_send(sock, MONITOR_ANS_PTY, m); | 1554 | mm_request_send(sock, MONITOR_ANS_PTY, m); |
1500 | 1555 | ||
@@ -1521,29 +1576,32 @@ mm_answer_pty(int sock, Buffer *m) | |||
1521 | error: | 1576 | error: |
1522 | if (s != NULL) | 1577 | if (s != NULL) |
1523 | mm_session_close(s); | 1578 | mm_session_close(s); |
1524 | buffer_put_int(m, 0); | 1579 | if ((r = sshbuf_put_u32(m, 0)) != 0) |
1580 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1525 | mm_request_send(sock, MONITOR_ANS_PTY, m); | 1581 | mm_request_send(sock, MONITOR_ANS_PTY, m); |
1526 | return (0); | 1582 | return (0); |
1527 | } | 1583 | } |
1528 | 1584 | ||
1529 | int | 1585 | int |
1530 | mm_answer_pty_cleanup(int sock, Buffer *m) | 1586 | mm_answer_pty_cleanup(int sock, struct sshbuf *m) |
1531 | { | 1587 | { |
1532 | Session *s; | 1588 | Session *s; |
1533 | char *tty; | 1589 | char *tty; |
1590 | int r; | ||
1534 | 1591 | ||
1535 | debug3("%s entering", __func__); | 1592 | debug3("%s entering", __func__); |
1536 | 1593 | ||
1537 | tty = buffer_get_string(m, NULL); | 1594 | if ((r = sshbuf_get_cstring(m, &tty, NULL)) != 0) |
1595 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1538 | if ((s = session_by_tty(tty)) != NULL) | 1596 | if ((s = session_by_tty(tty)) != NULL) |
1539 | mm_session_close(s); | 1597 | mm_session_close(s); |
1540 | buffer_clear(m); | 1598 | sshbuf_reset(m); |
1541 | free(tty); | 1599 | free(tty); |
1542 | return (0); | 1600 | return (0); |
1543 | } | 1601 | } |
1544 | 1602 | ||
1545 | int | 1603 | int |
1546 | mm_answer_term(int sock, Buffer *req) | 1604 | mm_answer_term(int sock, struct sshbuf *req) |
1547 | { | 1605 | { |
1548 | struct ssh *ssh = active_state; /* XXX */ | 1606 | struct ssh *ssh = active_state; /* XXX */ |
1549 | extern struct monitor *pmonitor; | 1607 | extern struct monitor *pmonitor; |
@@ -1732,24 +1790,27 @@ monitor_reinit(struct monitor *mon) | |||
1732 | 1790 | ||
1733 | #ifdef GSSAPI | 1791 | #ifdef GSSAPI |
1734 | int | 1792 | int |
1735 | mm_answer_gss_setup_ctx(int sock, Buffer *m) | 1793 | mm_answer_gss_setup_ctx(int sock, struct sshbuf *m) |
1736 | { | 1794 | { |
1737 | gss_OID_desc goid; | 1795 | gss_OID_desc goid; |
1738 | OM_uint32 major; | 1796 | OM_uint32 major; |
1739 | u_int len; | 1797 | size_t len; |
1798 | int r; | ||
1740 | 1799 | ||
1741 | if (!options.gss_authentication) | 1800 | if (!options.gss_authentication) |
1742 | fatal("%s: GSSAPI authentication not enabled", __func__); | 1801 | fatal("%s: GSSAPI authentication not enabled", __func__); |
1743 | 1802 | ||
1744 | goid.elements = buffer_get_string(m, &len); | 1803 | if ((r = sshbuf_get_string(m, &goid.elements, &len)) != 0) |
1804 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1745 | goid.length = len; | 1805 | goid.length = len; |
1746 | 1806 | ||
1747 | major = ssh_gssapi_server_ctx(&gsscontext, &goid); | 1807 | major = ssh_gssapi_server_ctx(&gsscontext, &goid); |
1748 | 1808 | ||
1749 | free(goid.elements); | 1809 | free(goid.elements); |
1750 | 1810 | ||
1751 | buffer_clear(m); | 1811 | sshbuf_reset(m); |
1752 | buffer_put_int(m, major); | 1812 | if ((r = sshbuf_put_u32(m, major)) != 0) |
1813 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1753 | 1814 | ||
1754 | mm_request_send(sock, MONITOR_ANS_GSSSETUP, m); | 1815 | mm_request_send(sock, MONITOR_ANS_GSSSETUP, m); |
1755 | 1816 | ||
@@ -1760,26 +1821,27 @@ mm_answer_gss_setup_ctx(int sock, Buffer *m) | |||
1760 | } | 1821 | } |
1761 | 1822 | ||
1762 | int | 1823 | int |
1763 | mm_answer_gss_accept_ctx(int sock, Buffer *m) | 1824 | mm_answer_gss_accept_ctx(int sock, struct sshbuf *m) |
1764 | { | 1825 | { |
1765 | gss_buffer_desc in; | 1826 | gss_buffer_desc in; |
1766 | gss_buffer_desc out = GSS_C_EMPTY_BUFFER; | 1827 | gss_buffer_desc out = GSS_C_EMPTY_BUFFER; |
1767 | OM_uint32 major, minor; | 1828 | OM_uint32 major, minor; |
1768 | OM_uint32 flags = 0; /* GSI needs this */ | 1829 | OM_uint32 flags = 0; /* GSI needs this */ |
1769 | u_int len; | 1830 | int r; |
1770 | 1831 | ||
1771 | if (!options.gss_authentication) | 1832 | if (!options.gss_authentication) |
1772 | fatal("%s: GSSAPI authentication not enabled", __func__); | 1833 | fatal("%s: GSSAPI authentication not enabled", __func__); |
1773 | 1834 | ||
1774 | in.value = buffer_get_string(m, &len); | 1835 | if ((r = sshbuf_get_string(m, &in.value, &in.length)) != 0) |
1775 | in.length = len; | 1836 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
1776 | major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags); | 1837 | major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags); |
1777 | free(in.value); | 1838 | free(in.value); |
1778 | 1839 | ||
1779 | buffer_clear(m); | 1840 | sshbuf_reset(m); |
1780 | buffer_put_int(m, major); | 1841 | if ((r = sshbuf_put_u32(m, major)) != 0 || |
1781 | buffer_put_string(m, out.value, out.length); | 1842 | (r = sshbuf_put_string(m, out.value, out.length)) != 0 || |
1782 | buffer_put_int(m, flags); | 1843 | (r = sshbuf_put_u32(m, flags)) != 0) |
1844 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1783 | mm_request_send(sock, MONITOR_ANS_GSSSTEP, m); | 1845 | mm_request_send(sock, MONITOR_ANS_GSSSTEP, m); |
1784 | 1846 | ||
1785 | gss_release_buffer(&minor, &out); | 1847 | gss_release_buffer(&minor, &out); |
@@ -1793,27 +1855,26 @@ mm_answer_gss_accept_ctx(int sock, Buffer *m) | |||
1793 | } | 1855 | } |
1794 | 1856 | ||
1795 | int | 1857 | int |
1796 | mm_answer_gss_checkmic(int sock, Buffer *m) | 1858 | mm_answer_gss_checkmic(int sock, struct sshbuf *m) |
1797 | { | 1859 | { |
1798 | gss_buffer_desc gssbuf, mic; | 1860 | gss_buffer_desc gssbuf, mic; |
1799 | OM_uint32 ret; | 1861 | OM_uint32 ret; |
1800 | u_int len; | ||
1801 | 1862 | ||
1802 | if (!options.gss_authentication) | 1863 | if (!options.gss_authentication) |
1803 | fatal("%s: GSSAPI authentication not enabled", __func__); | 1864 | fatal("%s: GSSAPI authentication not enabled", __func__); |
1804 | 1865 | ||
1805 | gssbuf.value = buffer_get_string(m, &len); | 1866 | if ((r = sshbuf_get_string(m, &gssbuf.value, &gssbuf.length)) != 0 || |
1806 | gssbuf.length = len; | 1867 | (r = sshbuf_get_string(m, &mic.value, &mic.length)) != 0) |
1807 | mic.value = buffer_get_string(m, &len); | 1868 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
1808 | mic.length = len; | ||
1809 | 1869 | ||
1810 | ret = ssh_gssapi_checkmic(gsscontext, &gssbuf, &mic); | 1870 | ret = ssh_gssapi_checkmic(gsscontext, &gssbuf, &mic); |
1811 | 1871 | ||
1812 | free(gssbuf.value); | 1872 | free(gssbuf.value); |
1813 | free(mic.value); | 1873 | free(mic.value); |
1814 | 1874 | ||
1815 | buffer_clear(m); | 1875 | sshbuf_reset(m); |
1816 | buffer_put_int(m, ret); | 1876 | if ((r = sshbuf_put_u32(m, ret)) != 0) |
1877 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1817 | 1878 | ||
1818 | mm_request_send(sock, MONITOR_ANS_GSSCHECKMIC, m); | 1879 | mm_request_send(sock, MONITOR_ANS_GSSCHECKMIC, m); |
1819 | 1880 | ||
@@ -1824,7 +1885,7 @@ mm_answer_gss_checkmic(int sock, Buffer *m) | |||
1824 | } | 1885 | } |
1825 | 1886 | ||
1826 | int | 1887 | int |
1827 | mm_answer_gss_userok(int sock, Buffer *m) | 1888 | mm_answer_gss_userok(int sock, struct sshbuf *m) |
1828 | { | 1889 | { |
1829 | int authenticated; | 1890 | int authenticated; |
1830 | const char *displayname; | 1891 | const char *displayname; |
@@ -1834,8 +1895,9 @@ mm_answer_gss_userok(int sock, Buffer *m) | |||
1834 | 1895 | ||
1835 | authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user); | 1896 | authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user); |
1836 | 1897 | ||
1837 | buffer_clear(m); | 1898 | sshbuf_reset(m); |
1838 | buffer_put_int(m, authenticated); | 1899 | if ((r = sshbuf_put_u32(m, authenticated)) != 0) |
1900 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1839 | 1901 | ||
1840 | debug3("%s: sending result %d", __func__, authenticated); | 1902 | debug3("%s: sending result %d", __func__, authenticated); |
1841 | mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); | 1903 | mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); |