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 | |
parent | b8d9214d969775e409e1408ecdf0d58fad99b344 (diff) |
upstream: sshd: switch monitor to sshbuf API; lots of help & ok
djm@
OpenBSD-Commit-ID: d89bd02d33974fd35ca0b8940d88572227b34a48
-rw-r--r-- | monitor.c | 494 | ||||
-rw-r--r-- | monitor.h | 8 | ||||
-rw-r--r-- | monitor_wrap.c | 485 |
3 files changed, 566 insertions, 421 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); |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: monitor.h,v 1.20 2016/09/28 16:33:07 djm Exp $ */ | 1 | /* $OpenBSD: monitor.h,v 1.21 2018/07/09 21:53:45 markus Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright 2002 Niels Provos <provos@citi.umich.edu> | 4 | * Copyright 2002 Niels Provos <provos@citi.umich.edu> |
@@ -87,8 +87,8 @@ struct mon_table; | |||
87 | int monitor_read(struct monitor*, struct mon_table *, struct mon_table **); | 87 | int monitor_read(struct monitor*, struct mon_table *, struct mon_table **); |
88 | 88 | ||
89 | /* Prototypes for request sending and receiving */ | 89 | /* Prototypes for request sending and receiving */ |
90 | void mm_request_send(int, enum monitor_reqtype, Buffer *); | 90 | void mm_request_send(int, enum monitor_reqtype, struct sshbuf *); |
91 | void mm_request_receive(int, Buffer *); | 91 | void mm_request_receive(int, struct sshbuf *); |
92 | void mm_request_receive_expect(int, enum monitor_reqtype, Buffer *); | 92 | void mm_request_receive_expect(int, enum monitor_reqtype, struct sshbuf *); |
93 | 93 | ||
94 | #endif /* _MONITOR_H_ */ | 94 | #endif /* _MONITOR_H_ */ |
diff --git a/monitor_wrap.c b/monitor_wrap.c index 6bf041093..cf38b230b 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: monitor_wrap.c,v 1.102 2018/07/09 21:26:02 markus Exp $ */ | 1 | /* $OpenBSD: monitor_wrap.c,v 1.103 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> |
@@ -50,7 +50,7 @@ | |||
50 | #ifdef WITH_OPENSSL | 50 | #ifdef WITH_OPENSSL |
51 | #include "dh.h" | 51 | #include "dh.h" |
52 | #endif | 52 | #endif |
53 | #include "buffer.h" | 53 | #include "sshbuf.h" |
54 | #include "key.h" | 54 | #include "key.h" |
55 | #include "cipher.h" | 55 | #include "cipher.h" |
56 | #include "kex.h" | 56 | #include "kex.h" |
@@ -93,27 +93,28 @@ extern ServerOptions options; | |||
93 | void | 93 | void |
94 | mm_log_handler(LogLevel level, const char *msg, void *ctx) | 94 | mm_log_handler(LogLevel level, const char *msg, void *ctx) |
95 | { | 95 | { |
96 | Buffer log_msg; | 96 | struct sshbuf *log_msg; |
97 | struct monitor *mon = (struct monitor *)ctx; | 97 | struct monitor *mon = (struct monitor *)ctx; |
98 | int r; | ||
99 | size_t len; | ||
98 | 100 | ||
99 | if (mon->m_log_sendfd == -1) | 101 | if (mon->m_log_sendfd == -1) |
100 | fatal("%s: no log channel", __func__); | 102 | fatal("%s: no log channel", __func__); |
101 | 103 | ||
102 | buffer_init(&log_msg); | 104 | if ((log_msg = sshbuf_new()) == NULL) |
103 | /* | 105 | fatal("%s: sshbuf_new failed", __func__); |
104 | * Placeholder for packet length. Will be filled in with the actual | ||
105 | * packet length once the packet has been constucted. This saves | ||
106 | * fragile math. | ||
107 | */ | ||
108 | buffer_put_int(&log_msg, 0); | ||
109 | 106 | ||
110 | buffer_put_int(&log_msg, level); | 107 | if ((r = sshbuf_put_u32(log_msg, 0)) != 0 || /* length; filled below */ |
111 | buffer_put_cstring(&log_msg, msg); | 108 | (r = sshbuf_put_u32(log_msg, level)) != 0 || |
112 | put_u32(buffer_ptr(&log_msg), buffer_len(&log_msg) - 4); | 109 | (r = sshbuf_put_cstring(log_msg, msg)) != 0) |
113 | if (atomicio(vwrite, mon->m_log_sendfd, buffer_ptr(&log_msg), | 110 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
114 | buffer_len(&log_msg)) != buffer_len(&log_msg)) | 111 | if ((len = sshbuf_len(log_msg)) < 4 || len > 0xffffffff) |
112 | fatal("%s: bad length %zu", __func__, len); | ||
113 | POKE_U32(sshbuf_mutable_ptr(log_msg), len - 4); | ||
114 | if (atomicio(vwrite, mon->m_log_sendfd, | ||
115 | sshbuf_mutable_ptr(log_msg), len) != len) | ||
115 | fatal("%s: write: %s", __func__, strerror(errno)); | 116 | fatal("%s: write: %s", __func__, strerror(errno)); |
116 | buffer_free(&log_msg); | 117 | sshbuf_free(log_msg); |
117 | } | 118 | } |
118 | 119 | ||
119 | int | 120 | int |
@@ -127,26 +128,29 @@ mm_is_monitor(void) | |||
127 | } | 128 | } |
128 | 129 | ||
129 | void | 130 | void |
130 | mm_request_send(int sock, enum monitor_reqtype type, Buffer *m) | 131 | mm_request_send(int sock, enum monitor_reqtype type, struct sshbuf *m) |
131 | { | 132 | { |
132 | u_int mlen = buffer_len(m); | 133 | size_t mlen = sshbuf_len(m); |
133 | u_char buf[5]; | 134 | u_char buf[5]; |
134 | 135 | ||
135 | debug3("%s entering: type %d", __func__, type); | 136 | debug3("%s entering: type %d", __func__, type); |
136 | 137 | ||
137 | put_u32(buf, mlen + 1); | 138 | if (mlen >= 0xffffffff) |
139 | fatal("%s: bad length %zu", __func__, mlen); | ||
140 | POKE_U32(buf, mlen + 1); | ||
138 | buf[4] = (u_char) type; /* 1st byte of payload is mesg-type */ | 141 | buf[4] = (u_char) type; /* 1st byte of payload is mesg-type */ |
139 | if (atomicio(vwrite, sock, buf, sizeof(buf)) != sizeof(buf)) | 142 | if (atomicio(vwrite, sock, buf, sizeof(buf)) != sizeof(buf)) |
140 | fatal("%s: write: %s", __func__, strerror(errno)); | 143 | fatal("%s: write: %s", __func__, strerror(errno)); |
141 | if (atomicio(vwrite, sock, buffer_ptr(m), mlen) != mlen) | 144 | if (atomicio(vwrite, sock, sshbuf_mutable_ptr(m), mlen) != mlen) |
142 | fatal("%s: write: %s", __func__, strerror(errno)); | 145 | fatal("%s: write: %s", __func__, strerror(errno)); |
143 | } | 146 | } |
144 | 147 | ||
145 | void | 148 | void |
146 | mm_request_receive(int sock, Buffer *m) | 149 | mm_request_receive(int sock, struct sshbuf *m) |
147 | { | 150 | { |
148 | u_char buf[4]; | 151 | u_char buf[4], *p = NULL; |
149 | u_int msg_len; | 152 | u_int msg_len; |
153 | int r; | ||
150 | 154 | ||
151 | debug3("%s entering", __func__); | 155 | debug3("%s entering", __func__); |
152 | 156 | ||
@@ -155,24 +159,27 @@ mm_request_receive(int sock, Buffer *m) | |||
155 | cleanup_exit(255); | 159 | cleanup_exit(255); |
156 | fatal("%s: read: %s", __func__, strerror(errno)); | 160 | fatal("%s: read: %s", __func__, strerror(errno)); |
157 | } | 161 | } |
158 | msg_len = get_u32(buf); | 162 | msg_len = PEEK_U32(buf); |
159 | if (msg_len > 256 * 1024) | 163 | if (msg_len > 256 * 1024) |
160 | fatal("%s: read: bad msg_len %d", __func__, msg_len); | 164 | fatal("%s: read: bad msg_len %d", __func__, msg_len); |
161 | buffer_clear(m); | 165 | sshbuf_reset(m); |
162 | buffer_append_space(m, msg_len); | 166 | if ((r = sshbuf_reserve(m, msg_len, &p)) != 0) |
163 | if (atomicio(read, sock, buffer_ptr(m), msg_len) != msg_len) | 167 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
168 | if (atomicio(read, sock, p, msg_len) != msg_len) | ||
164 | fatal("%s: read: %s", __func__, strerror(errno)); | 169 | fatal("%s: read: %s", __func__, strerror(errno)); |
165 | } | 170 | } |
166 | 171 | ||
167 | void | 172 | void |
168 | mm_request_receive_expect(int sock, enum monitor_reqtype type, Buffer *m) | 173 | mm_request_receive_expect(int sock, enum monitor_reqtype type, struct sshbuf *m) |
169 | { | 174 | { |
170 | u_char rtype; | 175 | u_char rtype; |
176 | int r; | ||
171 | 177 | ||
172 | debug3("%s entering: type %d", __func__, type); | 178 | debug3("%s entering: type %d", __func__, type); |
173 | 179 | ||
174 | mm_request_receive(sock, m); | 180 | mm_request_receive(sock, m); |
175 | rtype = buffer_get_char(m); | 181 | if ((r = sshbuf_get_u8(m, &rtype)) != 0) |
182 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
176 | if (rtype != type) | 183 | if (rtype != type) |
177 | fatal("%s: read: rtype %d != type %d", __func__, | 184 | fatal("%s: read: rtype %d != type %d", __func__, |
178 | rtype, type); | 185 | rtype, type); |
@@ -183,20 +190,24 @@ DH * | |||
183 | mm_choose_dh(int min, int nbits, int max) | 190 | mm_choose_dh(int min, int nbits, int max) |
184 | { | 191 | { |
185 | BIGNUM *p, *g; | 192 | BIGNUM *p, *g; |
186 | int success = 0; | 193 | int r; |
187 | Buffer m; | 194 | u_char success = 0; |
195 | struct sshbuf *m; | ||
188 | 196 | ||
189 | buffer_init(&m); | 197 | if ((m = sshbuf_new()) == NULL) |
190 | buffer_put_int(&m, min); | 198 | fatal("%s: sshbuf_new failed", __func__); |
191 | buffer_put_int(&m, nbits); | 199 | if ((r = sshbuf_put_u32(m, min)) != 0 || |
192 | buffer_put_int(&m, max); | 200 | (r = sshbuf_put_u32(m, nbits)) != 0 || |
201 | (r = sshbuf_put_u32(m, max)) != 0) | ||
202 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
193 | 203 | ||
194 | mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_MODULI, &m); | 204 | mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_MODULI, m); |
195 | 205 | ||
196 | debug3("%s: waiting for MONITOR_ANS_MODULI", __func__); | 206 | debug3("%s: waiting for MONITOR_ANS_MODULI", __func__); |
197 | mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_MODULI, &m); | 207 | mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_MODULI, m); |
198 | 208 | ||
199 | success = buffer_get_char(&m); | 209 | if ((r = sshbuf_get_u8(m, &success)) != 0) |
210 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
200 | if (success == 0) | 211 | if (success == 0) |
201 | fatal("%s: MONITOR_ANS_MODULI failed", __func__); | 212 | fatal("%s: MONITOR_ANS_MODULI failed", __func__); |
202 | 213 | ||
@@ -204,11 +215,12 @@ mm_choose_dh(int min, int nbits, int max) | |||
204 | fatal("%s: BN_new failed", __func__); | 215 | fatal("%s: BN_new failed", __func__); |
205 | if ((g = BN_new()) == NULL) | 216 | if ((g = BN_new()) == NULL) |
206 | fatal("%s: BN_new failed", __func__); | 217 | fatal("%s: BN_new failed", __func__); |
207 | buffer_get_bignum2(&m, p); | 218 | if ((r = sshbuf_get_bignum2(m, p)) != 0 || |
208 | buffer_get_bignum2(&m, g); | 219 | (r = sshbuf_get_bignum2(m, g)) != 0) |
220 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
209 | 221 | ||
210 | debug3("%s: remaining %d", __func__, buffer_len(&m)); | 222 | debug3("%s: remaining %zu", __func__, sshbuf_len(m)); |
211 | buffer_free(&m); | 223 | sshbuf_free(m); |
212 | 224 | ||
213 | return (dh_new_group(g, p)); | 225 | return (dh_new_group(g, p)); |
214 | } | 226 | } |
@@ -219,21 +231,30 @@ mm_key_sign(struct sshkey *key, u_char **sigp, u_int *lenp, | |||
219 | const u_char *data, u_int datalen, const char *hostkey_alg) | 231 | const u_char *data, u_int datalen, const char *hostkey_alg) |
220 | { | 232 | { |
221 | struct kex *kex = *pmonitor->m_pkex; | 233 | struct kex *kex = *pmonitor->m_pkex; |
222 | Buffer m; | 234 | struct sshbuf *m; |
235 | size_t xxxlen; | ||
236 | u_int ndx = kex->host_key_index(key, 0, active_state); | ||
237 | int r; | ||
223 | 238 | ||
224 | debug3("%s entering", __func__); | 239 | debug3("%s entering", __func__); |
225 | 240 | ||
226 | buffer_init(&m); | 241 | if ((m = sshbuf_new()) == NULL) |
227 | buffer_put_int(&m, kex->host_key_index(key, 0, active_state)); | 242 | fatal("%s: sshbuf_new failed", __func__); |
228 | buffer_put_string(&m, data, datalen); | 243 | if ((r = sshbuf_put_u32(m, ndx)) != 0 || |
229 | buffer_put_cstring(&m, hostkey_alg); | 244 | (r = sshbuf_put_string(m, data, datalen)) != 0 || |
245 | (r = sshbuf_put_cstring(m, hostkey_alg)) != 0) | ||
246 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
230 | 247 | ||
231 | mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SIGN, &m); | 248 | mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SIGN, m); |
232 | 249 | ||
233 | debug3("%s: waiting for MONITOR_ANS_SIGN", __func__); | 250 | debug3("%s: waiting for MONITOR_ANS_SIGN", __func__); |
234 | mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SIGN, &m); | 251 | mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SIGN, m); |
235 | *sigp = buffer_get_string(&m, lenp); | 252 | if ((r = sshbuf_get_string(m, sigp, &xxxlen)) != 0) |
236 | buffer_free(&m); | 253 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
254 | if (xxxlen > 0xffffffff) | ||
255 | fatal("%s: bad length %zu", __func__, xxxlen); | ||
256 | *lenp = xxxlen; /* XXX fix API: size_t vs u_int */ | ||
257 | sshbuf_free(m); | ||
237 | 258 | ||
238 | return (0); | 259 | return (0); |
239 | } | 260 | } |
@@ -242,54 +263,80 @@ struct passwd * | |||
242 | mm_getpwnamallow(const char *username) | 263 | mm_getpwnamallow(const char *username) |
243 | { | 264 | { |
244 | struct ssh *ssh = active_state; /* XXX */ | 265 | struct ssh *ssh = active_state; /* XXX */ |
245 | Buffer m; | 266 | struct sshbuf *m; |
246 | struct passwd *pw; | 267 | struct passwd *pw; |
247 | u_int len, i; | 268 | size_t len; |
269 | u_int i; | ||
248 | ServerOptions *newopts; | 270 | ServerOptions *newopts; |
271 | int r; | ||
272 | u_char ok; | ||
273 | const u_char *p; | ||
249 | 274 | ||
250 | debug3("%s entering", __func__); | 275 | debug3("%s entering", __func__); |
251 | 276 | ||
252 | buffer_init(&m); | 277 | if ((m = sshbuf_new()) == NULL) |
253 | buffer_put_cstring(&m, username); | 278 | fatal("%s: sshbuf_new failed", __func__); |
279 | if ((r = sshbuf_put_cstring(m, username)) != 0) | ||
280 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
254 | 281 | ||
255 | mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PWNAM, &m); | 282 | mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PWNAM, m); |
256 | 283 | ||
257 | debug3("%s: waiting for MONITOR_ANS_PWNAM", __func__); | 284 | debug3("%s: waiting for MONITOR_ANS_PWNAM", __func__); |
258 | mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PWNAM, &m); | 285 | mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PWNAM, m); |
259 | 286 | ||
260 | if (buffer_get_char(&m) == 0) { | 287 | if ((r = sshbuf_get_u8(m, &ok)) != 0) |
288 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
289 | if (ok == 0) { | ||
261 | pw = NULL; | 290 | pw = NULL; |
262 | goto out; | 291 | goto out; |
263 | } | 292 | } |
264 | pw = buffer_get_string(&m, &len); | 293 | |
265 | if (len != sizeof(struct passwd)) | 294 | /* XXX don't like passing struct passwd like this */ |
295 | pw = xcalloc(sizeof(*pw), 1); | ||
296 | if ((r = sshbuf_get_string_direct(m, &p, &len)) != 0) | ||
297 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
298 | if (len != sizeof(*pw)) | ||
266 | fatal("%s: struct passwd size mismatch", __func__); | 299 | fatal("%s: struct passwd size mismatch", __func__); |
267 | pw->pw_name = buffer_get_string(&m, NULL); | 300 | memcpy(pw, p, sizeof(*pw)); |
268 | pw->pw_passwd = buffer_get_string(&m, NULL); | 301 | |
302 | if ((r = sshbuf_get_cstring(m, &pw->pw_name, NULL)) != 0 || | ||
303 | (r = sshbuf_get_cstring(m, &pw->pw_passwd, NULL)) != 0 || | ||
269 | #ifdef HAVE_STRUCT_PASSWD_PW_GECOS | 304 | #ifdef HAVE_STRUCT_PASSWD_PW_GECOS |
270 | pw->pw_gecos = buffer_get_string(&m, NULL); | 305 | (r = sshbuf_get_cstring(m, &pw->pw_gecos, NULL)) != 0 || |
271 | #endif | 306 | #endif |
272 | #ifdef HAVE_STRUCT_PASSWD_PW_CLASS | 307 | #ifdef HAVE_STRUCT_PASSWD_PW_CLASS |
273 | pw->pw_class = buffer_get_string(&m, NULL); | 308 | (r = sshbuf_get_cstring(m, &pw->pw_class, NULL)) != 0 || |
274 | #endif | 309 | #endif |
275 | pw->pw_dir = buffer_get_string(&m, NULL); | 310 | (r = sshbuf_get_cstring(m, &pw->pw_dir, NULL)) != 0 || |
276 | pw->pw_shell = buffer_get_string(&m, NULL); | 311 | (r = sshbuf_get_cstring(m, &pw->pw_shell, NULL)) != 0) |
312 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
277 | 313 | ||
278 | out: | 314 | out: |
279 | /* copy options block as a Match directive may have changed some */ | 315 | /* copy options block as a Match directive may have changed some */ |
280 | newopts = buffer_get_string(&m, &len); | 316 | if ((r = sshbuf_get_string_direct(m, &p, &len)) != 0) |
317 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
281 | if (len != sizeof(*newopts)) | 318 | if (len != sizeof(*newopts)) |
282 | fatal("%s: option block size mismatch", __func__); | 319 | fatal("%s: option block size mismatch", __func__); |
320 | newopts = xcalloc(sizeof(*newopts), 1); | ||
321 | memcpy(newopts, p, sizeof(*newopts)); | ||
283 | 322 | ||
284 | #define M_CP_STROPT(x) do { \ | 323 | #define M_CP_STROPT(x) do { \ |
285 | if (newopts->x != NULL) \ | 324 | if (newopts->x != NULL) { \ |
286 | newopts->x = buffer_get_string(&m, NULL); \ | 325 | if ((r = sshbuf_get_cstring(m, \ |
326 | &newopts->x, NULL)) != 0) \ | ||
327 | fatal("%s: buffer error: %s", \ | ||
328 | __func__, ssh_err(r)); \ | ||
329 | } \ | ||
287 | } while (0) | 330 | } while (0) |
288 | #define M_CP_STRARRAYOPT(x, nx) do { \ | 331 | #define M_CP_STRARRAYOPT(x, nx) do { \ |
289 | newopts->x = newopts->nx == 0 ? \ | 332 | newopts->x = newopts->nx == 0 ? \ |
290 | NULL : xcalloc(newopts->nx, sizeof(*newopts->x)); \ | 333 | NULL : xcalloc(newopts->nx, sizeof(*newopts->x)); \ |
291 | for (i = 0; i < newopts->nx; i++) \ | 334 | for (i = 0; i < newopts->nx; i++) { \ |
292 | newopts->x[i] = buffer_get_string(&m, NULL); \ | 335 | if ((r = sshbuf_get_cstring(m, \ |
336 | &newopts->x[i], NULL)) != 0) \ | ||
337 | fatal("%s: buffer error: %s", \ | ||
338 | __func__, ssh_err(r)); \ | ||
339 | } \ | ||
293 | } while (0) | 340 | } while (0) |
294 | /* See comment in servconf.h */ | 341 | /* See comment in servconf.h */ |
295 | COPY_MATCH_STRING_OPTS(); | 342 | COPY_MATCH_STRING_OPTS(); |
@@ -301,7 +348,7 @@ out: | |||
301 | process_permitopen(ssh, &options); | 348 | process_permitopen(ssh, &options); |
302 | free(newopts); | 349 | free(newopts); |
303 | 350 | ||
304 | buffer_free(&m); | 351 | sshbuf_free(m); |
305 | 352 | ||
306 | return (pw); | 353 | return (pw); |
307 | } | 354 | } |
@@ -309,19 +356,22 @@ out: | |||
309 | char * | 356 | char * |
310 | mm_auth2_read_banner(void) | 357 | mm_auth2_read_banner(void) |
311 | { | 358 | { |
312 | Buffer m; | 359 | struct sshbuf *m; |
313 | char *banner; | 360 | char *banner; |
361 | int r; | ||
314 | 362 | ||
315 | debug3("%s entering", __func__); | 363 | debug3("%s entering", __func__); |
316 | 364 | ||
317 | buffer_init(&m); | 365 | if ((m = sshbuf_new()) == NULL) |
318 | mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTH2_READ_BANNER, &m); | 366 | fatal("%s: sshbuf_new failed", __func__); |
319 | buffer_clear(&m); | 367 | mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTH2_READ_BANNER, m); |
368 | sshbuf_reset(m); | ||
320 | 369 | ||
321 | mm_request_receive_expect(pmonitor->m_recvfd, | 370 | mm_request_receive_expect(pmonitor->m_recvfd, |
322 | MONITOR_ANS_AUTH2_READ_BANNER, &m); | 371 | MONITOR_ANS_AUTH2_READ_BANNER, m); |
323 | banner = buffer_get_string(&m, NULL); | 372 | if ((r = sshbuf_get_cstring(m, &banner, NULL)) != 0) |
324 | buffer_free(&m); | 373 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
374 | sshbuf_free(m); | ||
325 | 375 | ||
326 | /* treat empty banner as missing banner */ | 376 | /* treat empty banner as missing banner */ |
327 | if (strlen(banner) == 0) { | 377 | if (strlen(banner) == 0) { |
@@ -336,41 +386,50 @@ mm_auth2_read_banner(void) | |||
336 | void | 386 | void |
337 | mm_inform_authserv(char *service, char *style) | 387 | mm_inform_authserv(char *service, char *style) |
338 | { | 388 | { |
339 | Buffer m; | 389 | struct sshbuf *m; |
390 | int r; | ||
340 | 391 | ||
341 | debug3("%s entering", __func__); | 392 | debug3("%s entering", __func__); |
342 | 393 | ||
343 | buffer_init(&m); | 394 | if ((m = sshbuf_new()) == NULL) |
344 | buffer_put_cstring(&m, service); | 395 | fatal("%s: sshbuf_new failed", __func__); |
345 | buffer_put_cstring(&m, style ? style : ""); | 396 | if ((r = sshbuf_put_cstring(m, service)) != 0 || |
397 | (r = sshbuf_put_cstring(m, style ? style : "")) != 0) | ||
398 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
346 | 399 | ||
347 | mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHSERV, &m); | 400 | mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHSERV, m); |
348 | 401 | ||
349 | buffer_free(&m); | 402 | sshbuf_free(m); |
350 | } | 403 | } |
351 | 404 | ||
352 | /* Do the password authentication */ | 405 | /* Do the password authentication */ |
353 | int | 406 | int |
354 | mm_auth_password(struct ssh *ssh, char *password) | 407 | mm_auth_password(struct ssh *ssh, char *password) |
355 | { | 408 | { |
356 | Buffer m; | 409 | struct sshbuf *m; |
357 | int authenticated = 0; | 410 | int r, maxtries = 0, authenticated = 0; |
358 | 411 | ||
359 | debug3("%s entering", __func__); | 412 | debug3("%s entering", __func__); |
360 | 413 | ||
361 | buffer_init(&m); | 414 | if ((m = sshbuf_new()) == NULL) |
362 | buffer_put_cstring(&m, password); | 415 | fatal("%s: sshbuf_new failed", __func__); |
363 | mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHPASSWORD, &m); | 416 | if ((r = sshbuf_put_cstring(m, password)) != 0) |
417 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
418 | mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHPASSWORD, m); | ||
364 | 419 | ||
365 | debug3("%s: waiting for MONITOR_ANS_AUTHPASSWORD", __func__); | 420 | debug3("%s: waiting for MONITOR_ANS_AUTHPASSWORD", __func__); |
366 | mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUTHPASSWORD, &m); | 421 | mm_request_receive_expect(pmonitor->m_recvfd, |
422 | MONITOR_ANS_AUTHPASSWORD, m); | ||
367 | 423 | ||
368 | authenticated = buffer_get_int(&m); | 424 | if ((r = sshbuf_get_u32(m, &authenticated)) != 0) |
425 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
369 | #ifdef USE_PAM | 426 | #ifdef USE_PAM |
370 | sshpam_set_maxtries_reached(buffer_get_int(&m)); | 427 | if ((r = sshbuf_get_u32(m, &maxtries)) != 0) |
428 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
429 | sshpam_set_maxtries_reached(maxtries); | ||
371 | #endif | 430 | #endif |
372 | 431 | ||
373 | buffer_free(&m); | 432 | sshbuf_free(m); |
374 | 433 | ||
375 | debug3("%s: user %sauthenticated", | 434 | debug3("%s: user %sauthenticated", |
376 | __func__, authenticated ? "" : "not "); | 435 | __func__, authenticated ? "" : "not "); |
@@ -396,9 +455,7 @@ int | |||
396 | mm_key_allowed(enum mm_keytype type, const char *user, const char *host, | 455 | mm_key_allowed(enum mm_keytype type, const char *user, const char *host, |
397 | struct sshkey *key, int pubkey_auth_attempt, struct sshauthopt **authoptp) | 456 | struct sshkey *key, int pubkey_auth_attempt, struct sshauthopt **authoptp) |
398 | { | 457 | { |
399 | Buffer m; | 458 | struct sshbuf *m; |
400 | u_char *blob; | ||
401 | u_int len; | ||
402 | int r, allowed = 0; | 459 | int r, allowed = 0; |
403 | struct sshauthopt *opts = NULL; | 460 | struct sshauthopt *opts = NULL; |
404 | 461 | ||
@@ -407,31 +464,29 @@ mm_key_allowed(enum mm_keytype type, const char *user, const char *host, | |||
407 | if (authoptp != NULL) | 464 | if (authoptp != NULL) |
408 | *authoptp = NULL; | 465 | *authoptp = NULL; |
409 | 466 | ||
410 | /* Convert the key to a blob and the pass it over */ | 467 | if ((m = sshbuf_new()) == NULL) |
411 | if (!key_to_blob(key, &blob, &len)) | 468 | fatal("%s: sshbuf_new failed", __func__); |
412 | return 0; | 469 | if ((r = sshbuf_put_u32(m, type)) != 0 || |
413 | 470 | (r = sshbuf_put_cstring(m, user ? user : "")) != 0 || | |
414 | buffer_init(&m); | 471 | (r = sshbuf_put_cstring(m, host ? host : "")) != 0 || |
415 | buffer_put_int(&m, type); | 472 | (r = sshkey_puts(key, m)) != 0 || |
416 | buffer_put_cstring(&m, user ? user : ""); | 473 | (r = sshbuf_put_u32(m, pubkey_auth_attempt)) != 0) |
417 | buffer_put_cstring(&m, host ? host : ""); | 474 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
418 | buffer_put_string(&m, blob, len); | ||
419 | buffer_put_int(&m, pubkey_auth_attempt); | ||
420 | free(blob); | ||
421 | 475 | ||
422 | mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYALLOWED, &m); | 476 | mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYALLOWED, m); |
423 | 477 | ||
424 | debug3("%s: waiting for MONITOR_ANS_KEYALLOWED", __func__); | 478 | debug3("%s: waiting for MONITOR_ANS_KEYALLOWED", __func__); |
425 | mm_request_receive_expect(pmonitor->m_recvfd, | 479 | mm_request_receive_expect(pmonitor->m_recvfd, |
426 | MONITOR_ANS_KEYALLOWED, &m); | 480 | MONITOR_ANS_KEYALLOWED, m); |
427 | 481 | ||
428 | allowed = buffer_get_int(&m); | 482 | if ((r = sshbuf_get_u32(m, &allowed)) != 0) |
483 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
429 | if (allowed && type == MM_USERKEY) { | 484 | if (allowed && type == MM_USERKEY) { |
430 | if ((r = sshauthopt_deserialise(&m, &opts)) != 0) | 485 | if ((r = sshauthopt_deserialise(m, &opts)) != 0) |
431 | fatal("%s: sshauthopt_deserialise: %s", | 486 | fatal("%s: sshauthopt_deserialise: %s", |
432 | __func__, ssh_err(r)); | 487 | __func__, ssh_err(r)); |
433 | } | 488 | } |
434 | buffer_free(&m); | 489 | sshbuf_free(m); |
435 | 490 | ||
436 | if (authoptp != NULL) { | 491 | if (authoptp != NULL) { |
437 | *authoptp = opts; | 492 | *authoptp = opts; |
@@ -452,32 +507,31 @@ int | |||
452 | mm_sshkey_verify(const struct sshkey *key, const u_char *sig, size_t siglen, | 507 | mm_sshkey_verify(const struct sshkey *key, const u_char *sig, size_t siglen, |
453 | const u_char *data, size_t datalen, const char *sigalg, u_int compat) | 508 | const u_char *data, size_t datalen, const char *sigalg, u_int compat) |
454 | { | 509 | { |
455 | Buffer m; | 510 | struct sshbuf *m; |
456 | u_char *blob; | ||
457 | u_int len; | ||
458 | u_int encoded_ret = 0; | 511 | u_int encoded_ret = 0; |
512 | int r; | ||
459 | 513 | ||
460 | debug3("%s entering", __func__); | 514 | debug3("%s entering", __func__); |
461 | 515 | ||
462 | /* Convert the key to a blob and the pass it over */ | ||
463 | if (!key_to_blob(key, &blob, &len)) | ||
464 | return (0); | ||
465 | 516 | ||
466 | buffer_init(&m); | 517 | if ((m = sshbuf_new()) == NULL) |
467 | buffer_put_string(&m, blob, len); | 518 | fatal("%s: sshbuf_new failed", __func__); |
468 | buffer_put_string(&m, sig, siglen); | 519 | if ((r = sshkey_puts(key, m)) != 0 || |
469 | buffer_put_string(&m, data, datalen); | 520 | (r = sshbuf_put_string(m, sig, siglen)) != 0 || |
470 | buffer_put_cstring(&m, sigalg == NULL ? "" : sigalg); | 521 | (r = sshbuf_put_string(m, data, datalen)) != 0 || |
471 | free(blob); | 522 | (r = sshbuf_put_cstring(m, sigalg == NULL ? "" : sigalg)) != 0) |
523 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
472 | 524 | ||
473 | mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYVERIFY, &m); | 525 | mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYVERIFY, m); |
474 | 526 | ||
475 | debug3("%s: waiting for MONITOR_ANS_KEYVERIFY", __func__); | 527 | debug3("%s: waiting for MONITOR_ANS_KEYVERIFY", __func__); |
476 | mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYVERIFY, &m); | 528 | mm_request_receive_expect(pmonitor->m_recvfd, |
529 | MONITOR_ANS_KEYVERIFY, m); | ||
477 | 530 | ||
478 | encoded_ret = buffer_get_int(&m); | 531 | if ((r = sshbuf_get_u32(m, &encoded_ret)) != 0) |
532 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
479 | 533 | ||
480 | buffer_free(&m); | 534 | sshbuf_free(m); |
481 | 535 | ||
482 | if (encoded_ret != 0) | 536 | if (encoded_ret != 0) |
483 | return SSH_ERR_SIGNATURE_INVALID; | 537 | return SSH_ERR_SIGNATURE_INVALID; |
@@ -504,7 +558,7 @@ mm_send_keystate(struct monitor *monitor) | |||
504 | int | 558 | int |
505 | mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen) | 559 | mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen) |
506 | { | 560 | { |
507 | Buffer m; | 561 | struct sshbuf *m; |
508 | char *p, *msg; | 562 | char *p, *msg; |
509 | int success = 0, tmp1 = -1, tmp2 = -1, r; | 563 | int success = 0, tmp1 = -1, tmp2 = -1, r; |
510 | 564 | ||
@@ -521,21 +575,24 @@ mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen) | |||
521 | close(tmp1); | 575 | close(tmp1); |
522 | close(tmp2); | 576 | close(tmp2); |
523 | 577 | ||
524 | buffer_init(&m); | 578 | if ((m = sshbuf_new()) == NULL) |
525 | mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTY, &m); | 579 | fatal("%s: sshbuf_new failed", __func__); |
580 | mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTY, m); | ||
526 | 581 | ||
527 | debug3("%s: waiting for MONITOR_ANS_PTY", __func__); | 582 | debug3("%s: waiting for MONITOR_ANS_PTY", __func__); |
528 | mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PTY, &m); | 583 | mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PTY, m); |
529 | 584 | ||
530 | success = buffer_get_int(&m); | 585 | if ((r = sshbuf_get_u32(m, &success)) != 0) |
586 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
531 | if (success == 0) { | 587 | if (success == 0) { |
532 | debug3("%s: pty alloc failed", __func__); | 588 | debug3("%s: pty alloc failed", __func__); |
533 | buffer_free(&m); | 589 | sshbuf_free(m); |
534 | return (0); | 590 | return (0); |
535 | } | 591 | } |
536 | p = buffer_get_string(&m, NULL); | 592 | if ((r = sshbuf_get_cstring(m, &p, NULL)) != 0 || |
537 | msg = buffer_get_string(&m, NULL); | 593 | (r = sshbuf_get_cstring(m, &msg, NULL)) != 0) |
538 | buffer_free(&m); | 594 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
595 | sshbuf_free(m); | ||
539 | 596 | ||
540 | strlcpy(namebuf, p, namebuflen); /* Possible truncation */ | 597 | strlcpy(namebuf, p, namebuflen); /* Possible truncation */ |
541 | free(p); | 598 | free(p); |
@@ -555,14 +612,17 @@ mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen) | |||
555 | void | 612 | void |
556 | mm_session_pty_cleanup2(Session *s) | 613 | mm_session_pty_cleanup2(Session *s) |
557 | { | 614 | { |
558 | Buffer m; | 615 | struct sshbuf *m; |
616 | int r; | ||
559 | 617 | ||
560 | if (s->ttyfd == -1) | 618 | if (s->ttyfd == -1) |
561 | return; | 619 | return; |
562 | buffer_init(&m); | 620 | if ((m = sshbuf_new()) == NULL) |
563 | buffer_put_cstring(&m, s->tty); | 621 | fatal("%s: sshbuf_new failed", __func__); |
564 | mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTYCLEANUP, &m); | 622 | if ((r = sshbuf_put_cstring(m, s->tty)) != 0) |
565 | buffer_free(&m); | 623 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
624 | mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTYCLEANUP, m); | ||
625 | sshbuf_free(m); | ||
566 | 626 | ||
567 | /* closed dup'ed master */ | 627 | /* closed dup'ed master */ |
568 | if (s->ptymaster != -1 && close(s->ptymaster) < 0) | 628 | if (s->ptymaster != -1 && close(s->ptymaster) < 0) |
@@ -710,11 +770,12 @@ mm_sshpam_free_ctx(void *ctxtp) | |||
710 | void | 770 | void |
711 | mm_terminate(void) | 771 | mm_terminate(void) |
712 | { | 772 | { |
713 | Buffer m; | 773 | struct sshbuf *m; |
714 | 774 | ||
715 | buffer_init(&m); | 775 | if ((m = sshbuf_new()) == NULL) |
716 | mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_TERM, &m); | 776 | fatal("%s: sshbuf_new failed", __func__); |
717 | buffer_free(&m); | 777 | mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_TERM, m); |
778 | sshbuf_free(m); | ||
718 | } | 779 | } |
719 | 780 | ||
720 | static void | 781 | static void |
@@ -733,27 +794,31 @@ int | |||
733 | mm_bsdauth_query(void *ctx, char **name, char **infotxt, | 794 | mm_bsdauth_query(void *ctx, char **name, char **infotxt, |
734 | u_int *numprompts, char ***prompts, u_int **echo_on) | 795 | u_int *numprompts, char ***prompts, u_int **echo_on) |
735 | { | 796 | { |
736 | Buffer m; | 797 | struct sshbuf *m; |
737 | u_int success; | 798 | u_int success; |
738 | char *challenge; | 799 | char *challenge; |
800 | int r; | ||
739 | 801 | ||
740 | debug3("%s: entering", __func__); | 802 | debug3("%s: entering", __func__); |
741 | 803 | ||
742 | buffer_init(&m); | 804 | if ((m = sshbuf_new()) == NULL) |
743 | mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHQUERY, &m); | 805 | fatal("%s: sshbuf_new failed", __func__); |
806 | mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHQUERY, m); | ||
744 | 807 | ||
745 | mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_BSDAUTHQUERY, | 808 | mm_request_receive_expect(pmonitor->m_recvfd, |
746 | &m); | 809 | MONITOR_ANS_BSDAUTHQUERY, m); |
747 | success = buffer_get_int(&m); | 810 | if ((r = sshbuf_get_u32(m, &success)) != 0) |
811 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
748 | if (success == 0) { | 812 | if (success == 0) { |
749 | debug3("%s: no challenge", __func__); | 813 | debug3("%s: no challenge", __func__); |
750 | buffer_free(&m); | 814 | sshbuf_free(m); |
751 | return (-1); | 815 | return (-1); |
752 | } | 816 | } |
753 | 817 | ||
754 | /* Get the challenge, and format the response */ | 818 | /* Get the challenge, and format the response */ |
755 | challenge = buffer_get_string(&m, NULL); | 819 | if ((r = sshbuf_get_cstring(m, &challenge, NULL)) != 0) |
756 | buffer_free(&m); | 820 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
821 | sshbuf_free(m); | ||
757 | 822 | ||
758 | mm_chall_setup(name, infotxt, numprompts, prompts, echo_on); | 823 | mm_chall_setup(name, infotxt, numprompts, prompts, echo_on); |
759 | (*prompts)[0] = challenge; | 824 | (*prompts)[0] = challenge; |
@@ -766,22 +831,25 @@ mm_bsdauth_query(void *ctx, char **name, char **infotxt, | |||
766 | int | 831 | int |
767 | mm_bsdauth_respond(void *ctx, u_int numresponses, char **responses) | 832 | mm_bsdauth_respond(void *ctx, u_int numresponses, char **responses) |
768 | { | 833 | { |
769 | Buffer m; | 834 | struct sshbuf *m; |
770 | int authok; | 835 | int r, authok; |
771 | 836 | ||
772 | debug3("%s: entering", __func__); | 837 | debug3("%s: entering", __func__); |
773 | if (numresponses != 1) | 838 | if (numresponses != 1) |
774 | return (-1); | 839 | return (-1); |
775 | 840 | ||
776 | buffer_init(&m); | 841 | if ((m = sshbuf_new()) == NULL) |
777 | buffer_put_cstring(&m, responses[0]); | 842 | fatal("%s: sshbuf_new failed", __func__); |
778 | mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHRESPOND, &m); | 843 | if ((r = sshbuf_put_cstring(m, responses[0])) != 0) |
844 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
845 | mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHRESPOND, m); | ||
779 | 846 | ||
780 | mm_request_receive_expect(pmonitor->m_recvfd, | 847 | mm_request_receive_expect(pmonitor->m_recvfd, |
781 | MONITOR_ANS_BSDAUTHRESPOND, &m); | 848 | MONITOR_ANS_BSDAUTHRESPOND, m); |
782 | 849 | ||
783 | authok = buffer_get_int(&m); | 850 | if ((r = sshbuf_get_u32(m, &authok)) != 0) |
784 | buffer_free(&m); | 851 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
852 | sshbuf_free(m); | ||
785 | 853 | ||
786 | return ((authok == 0) ? -1 : 0); | 854 | return ((authok == 0) ? -1 : 0); |
787 | } | 855 | } |
@@ -881,45 +949,55 @@ mm_audit_run_command(const char *command) | |||
881 | OM_uint32 | 949 | OM_uint32 |
882 | mm_ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID goid) | 950 | mm_ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID goid) |
883 | { | 951 | { |
884 | Buffer m; | 952 | struct sshbuf *m; |
885 | OM_uint32 major; | 953 | OM_uint32 major; |
954 | int r; | ||
886 | 955 | ||
887 | /* Client doesn't get to see the context */ | 956 | /* Client doesn't get to see the context */ |
888 | *ctx = NULL; | 957 | *ctx = NULL; |
889 | 958 | ||
890 | buffer_init(&m); | 959 | if ((m = sshbuf_new()) == NULL) |
891 | buffer_put_string(&m, goid->elements, goid->length); | 960 | fatal("%s: sshbuf_new failed", __func__); |
961 | if ((r = sshbuf_put_string(m, goid->elements, goid->length)) != 0) | ||
962 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
892 | 963 | ||
893 | mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSETUP, &m); | 964 | mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSETUP, m); |
894 | mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSETUP, &m); | 965 | mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSETUP, m); |
895 | 966 | ||
896 | major = buffer_get_int(&m); | 967 | if ((r = sshbuf_get_u32(m, &major)) != 0) |
968 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
897 | 969 | ||
898 | buffer_free(&m); | 970 | sshbuf_free(m); |
899 | return (major); | 971 | return (major); |
900 | } | 972 | } |
901 | 973 | ||
902 | OM_uint32 | 974 | OM_uint32 |
903 | mm_ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *in, | 975 | mm_ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *in, |
904 | gss_buffer_desc *out, OM_uint32 *flags) | 976 | gss_buffer_desc *out, OM_uint32 *flagsp) |
905 | { | 977 | { |
906 | Buffer m; | 978 | struct sshbuf *m; |
907 | OM_uint32 major; | 979 | OM_uint32 major; |
908 | u_int len; | 980 | u_int flags; |
981 | int r; | ||
909 | 982 | ||
910 | buffer_init(&m); | 983 | if ((m = sshbuf_new()) == NULL) |
911 | buffer_put_string(&m, in->value, in->length); | 984 | fatal("%s: sshbuf_new failed", __func__); |
985 | if ((r = sshbuf_put_string(m, in->value, in->length)) != 0) | ||
986 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
912 | 987 | ||
913 | mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSTEP, &m); | 988 | mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSTEP, m); |
914 | mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSTEP, &m); | 989 | mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSTEP, m); |
915 | 990 | ||
916 | major = buffer_get_int(&m); | 991 | if ((r = sshbuf_get_u32(m, &major)) != 0 || |
917 | out->value = buffer_get_string(&m, &len); | 992 | (r = sshbuf_get_string(m, &out->value, &out->length)) != 0) |
918 | out->length = len; | 993 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
919 | if (flags) | 994 | if (flagsp != NULL) { |
920 | *flags = buffer_get_int(&m); | 995 | if ((r = sshbuf_get_u32(m, &flags)) != 0) |
996 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
997 | *flagsp = flags; | ||
998 | } | ||
921 | 999 | ||
922 | buffer_free(&m); | 1000 | sshbuf_free(m); |
923 | 1001 | ||
924 | return (major); | 1002 | return (major); |
925 | } | 1003 | } |
@@ -927,39 +1005,44 @@ mm_ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *in, | |||
927 | OM_uint32 | 1005 | OM_uint32 |
928 | mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) | 1006 | mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) |
929 | { | 1007 | { |
930 | Buffer m; | 1008 | struct sshbuf *m; |
931 | OM_uint32 major; | 1009 | OM_uint32 major; |
1010 | int r; | ||
932 | 1011 | ||
933 | buffer_init(&m); | 1012 | if ((m = sshbuf_new()) == NULL) |
934 | buffer_put_string(&m, gssbuf->value, gssbuf->length); | 1013 | fatal("%s: sshbuf_new failed", __func__); |
935 | buffer_put_string(&m, gssmic->value, gssmic->length); | 1014 | if ((r = sshbuf_put_string(m, gssbuf->value, gssbuf->length)) != 0 || |
1015 | (r = sshbuf_put_string(m, gssmic->value, gssmic->length)) != 0) | ||
1016 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
936 | 1017 | ||
937 | mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSCHECKMIC, &m); | 1018 | mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSCHECKMIC, m); |
938 | mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSCHECKMIC, | 1019 | mm_request_receive_expect(pmonitor->m_recvfd, |
939 | &m); | 1020 | MONITOR_ANS_GSSCHECKMIC, m); |
940 | 1021 | ||
941 | major = buffer_get_int(&m); | 1022 | if ((r = sshbuf_get_u32(m, &major)) != 0) |
942 | buffer_free(&m); | 1023 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
1024 | sshbuf_free(m); | ||
943 | return(major); | 1025 | return(major); |
944 | } | 1026 | } |
945 | 1027 | ||
946 | int | 1028 | int |
947 | mm_ssh_gssapi_userok(char *user) | 1029 | mm_ssh_gssapi_userok(char *user) |
948 | { | 1030 | { |
949 | Buffer m; | 1031 | struct sshbuf *m; |
950 | int authenticated = 0; | 1032 | int r, authenticated = 0; |
951 | 1033 | ||
952 | buffer_init(&m); | 1034 | if ((m = sshbuf_new()) == NULL) |
1035 | fatal("%s: sshbuf_new failed", __func__); | ||
953 | 1036 | ||
954 | mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, &m); | 1037 | mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, m); |
955 | mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUSEROK, | 1038 | mm_request_receive_expect(pmonitor->m_recvfd, |
956 | &m); | 1039 | MONITOR_ANS_GSSUSEROK, m); |
957 | 1040 | ||
958 | authenticated = buffer_get_int(&m); | 1041 | if ((r = sshbuf_get_u32(m, &authenticated)) != 0) |
1042 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
959 | 1043 | ||
960 | buffer_free(&m); | 1044 | sshbuf_free(m); |
961 | debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not "); | 1045 | debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not "); |
962 | return (authenticated); | 1046 | return (authenticated); |
963 | } | 1047 | } |
964 | #endif /* GSSAPI */ | 1048 | #endif /* GSSAPI */ |
965 | |||