1*a0ee8cc6SDag-Erling Smørgrav /* $OpenBSD: monitor_wrap.c,v 1.80 2014/04/29 18:01:49 markus Exp $ */ 2545d5ecaSDag-Erling Smørgrav /* 3545d5ecaSDag-Erling Smørgrav * Copyright 2002 Niels Provos <provos@citi.umich.edu> 4545d5ecaSDag-Erling Smørgrav * Copyright 2002 Markus Friedl <markus@openbsd.org> 5545d5ecaSDag-Erling Smørgrav * All rights reserved. 6545d5ecaSDag-Erling Smørgrav * 7545d5ecaSDag-Erling Smørgrav * Redistribution and use in source and binary forms, with or without 8545d5ecaSDag-Erling Smørgrav * modification, are permitted provided that the following conditions 9545d5ecaSDag-Erling Smørgrav * are met: 10545d5ecaSDag-Erling Smørgrav * 1. Redistributions of source code must retain the above copyright 11545d5ecaSDag-Erling Smørgrav * notice, this list of conditions and the following disclaimer. 12545d5ecaSDag-Erling Smørgrav * 2. Redistributions in binary form must reproduce the above copyright 13545d5ecaSDag-Erling Smørgrav * notice, this list of conditions and the following disclaimer in the 14545d5ecaSDag-Erling Smørgrav * documentation and/or other materials provided with the distribution. 15545d5ecaSDag-Erling Smørgrav * 16545d5ecaSDag-Erling Smørgrav * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17545d5ecaSDag-Erling Smørgrav * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18545d5ecaSDag-Erling Smørgrav * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19545d5ecaSDag-Erling Smørgrav * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20545d5ecaSDag-Erling Smørgrav * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21545d5ecaSDag-Erling Smørgrav * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22545d5ecaSDag-Erling Smørgrav * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23545d5ecaSDag-Erling Smørgrav * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24545d5ecaSDag-Erling Smørgrav * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25545d5ecaSDag-Erling Smørgrav * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26545d5ecaSDag-Erling Smørgrav */ 27545d5ecaSDag-Erling Smørgrav 28545d5ecaSDag-Erling Smørgrav #include "includes.h" 29333ee039SDag-Erling Smørgrav 30333ee039SDag-Erling Smørgrav #include <sys/types.h> 31333ee039SDag-Erling Smørgrav #include <sys/uio.h> 32333ee039SDag-Erling Smørgrav 33333ee039SDag-Erling Smørgrav #include <errno.h> 34333ee039SDag-Erling Smørgrav #include <pwd.h> 35333ee039SDag-Erling Smørgrav #include <signal.h> 36333ee039SDag-Erling Smørgrav #include <stdarg.h> 37333ee039SDag-Erling Smørgrav #include <stdio.h> 38333ee039SDag-Erling Smørgrav #include <string.h> 39333ee039SDag-Erling Smørgrav #include <unistd.h> 40545d5ecaSDag-Erling Smørgrav 41*a0ee8cc6SDag-Erling Smørgrav #ifdef WITH_OPENSSL 42545d5ecaSDag-Erling Smørgrav #include <openssl/bn.h> 43545d5ecaSDag-Erling Smørgrav #include <openssl/dh.h> 44cce7d346SDag-Erling Smørgrav #include <openssl/evp.h> 45*a0ee8cc6SDag-Erling Smørgrav #endif 46545d5ecaSDag-Erling Smørgrav 47d4af9e69SDag-Erling Smørgrav #include "openbsd-compat/sys-queue.h" 48333ee039SDag-Erling Smørgrav #include "xmalloc.h" 49545d5ecaSDag-Erling Smørgrav #include "ssh.h" 50*a0ee8cc6SDag-Erling Smørgrav #ifdef WITH_OPENSSL 51545d5ecaSDag-Erling Smørgrav #include "dh.h" 52*a0ee8cc6SDag-Erling Smørgrav #endif 53333ee039SDag-Erling Smørgrav #include "buffer.h" 54333ee039SDag-Erling Smørgrav #include "key.h" 55333ee039SDag-Erling Smørgrav #include "cipher.h" 56545d5ecaSDag-Erling Smørgrav #include "kex.h" 57333ee039SDag-Erling Smørgrav #include "hostfile.h" 58545d5ecaSDag-Erling Smørgrav #include "auth.h" 59e73e9afaSDag-Erling Smørgrav #include "auth-options.h" 60545d5ecaSDag-Erling Smørgrav #include "packet.h" 61545d5ecaSDag-Erling Smørgrav #include "mac.h" 62545d5ecaSDag-Erling Smørgrav #include "log.h" 635962c0e9SDag-Erling Smørgrav #ifdef TARGET_OS_MAC /* XXX Broken krb5 headers on Mac */ 645962c0e9SDag-Erling Smørgrav #undef TARGET_OS_MAC 65545d5ecaSDag-Erling Smørgrav #include "zlib.h" 665962c0e9SDag-Erling Smørgrav #define TARGET_OS_MAC 1 675962c0e9SDag-Erling Smørgrav #else 685962c0e9SDag-Erling Smørgrav #include "zlib.h" 695962c0e9SDag-Erling Smørgrav #endif 70545d5ecaSDag-Erling Smørgrav #include "monitor.h" 71cf2b5f3bSDag-Erling Smørgrav #ifdef GSSAPI 72cf2b5f3bSDag-Erling Smørgrav #include "ssh-gss.h" 73cf2b5f3bSDag-Erling Smørgrav #endif 74333ee039SDag-Erling Smørgrav #include "monitor_wrap.h" 75333ee039SDag-Erling Smørgrav #include "atomicio.h" 76333ee039SDag-Erling Smørgrav #include "monitor_fdpass.h" 77333ee039SDag-Erling Smørgrav #include "misc.h" 784a421b63SDag-Erling Smørgrav #include "uuencode.h" 79333ee039SDag-Erling Smørgrav 80333ee039SDag-Erling Smørgrav #include "channels.h" 81333ee039SDag-Erling Smørgrav #include "session.h" 82d4af9e69SDag-Erling Smørgrav #include "servconf.h" 837aee6ffeSDag-Erling Smørgrav #include "roaming.h" 84cf2b5f3bSDag-Erling Smørgrav 85545d5ecaSDag-Erling Smørgrav /* Imports */ 86545d5ecaSDag-Erling Smørgrav extern int compat20; 87545d5ecaSDag-Erling Smørgrav extern z_stream incoming_stream; 88545d5ecaSDag-Erling Smørgrav extern z_stream outgoing_stream; 89545d5ecaSDag-Erling Smørgrav extern struct monitor *pmonitor; 9021e764dfSDag-Erling Smørgrav extern Buffer loginmsg; 91cf2b5f3bSDag-Erling Smørgrav extern ServerOptions options; 92545d5ecaSDag-Erling Smørgrav 93e146993eSDag-Erling Smørgrav void 94e146993eSDag-Erling Smørgrav mm_log_handler(LogLevel level, const char *msg, void *ctx) 95e146993eSDag-Erling Smørgrav { 96e146993eSDag-Erling Smørgrav Buffer log_msg; 97e146993eSDag-Erling Smørgrav struct monitor *mon = (struct monitor *)ctx; 98e146993eSDag-Erling Smørgrav 99e146993eSDag-Erling Smørgrav if (mon->m_log_sendfd == -1) 100e146993eSDag-Erling Smørgrav fatal("%s: no log channel", __func__); 101e146993eSDag-Erling Smørgrav 102e146993eSDag-Erling Smørgrav buffer_init(&log_msg); 103e146993eSDag-Erling Smørgrav /* 104e146993eSDag-Erling Smørgrav * Placeholder for packet length. Will be filled in with the actual 105e146993eSDag-Erling Smørgrav * packet length once the packet has been constucted. This saves 106e146993eSDag-Erling Smørgrav * fragile math. 107e146993eSDag-Erling Smørgrav */ 108e146993eSDag-Erling Smørgrav buffer_put_int(&log_msg, 0); 109e146993eSDag-Erling Smørgrav 110e146993eSDag-Erling Smørgrav buffer_put_int(&log_msg, level); 111e146993eSDag-Erling Smørgrav buffer_put_cstring(&log_msg, msg); 112e146993eSDag-Erling Smørgrav put_u32(buffer_ptr(&log_msg), buffer_len(&log_msg) - 4); 113e146993eSDag-Erling Smørgrav if (atomicio(vwrite, mon->m_log_sendfd, buffer_ptr(&log_msg), 114e146993eSDag-Erling Smørgrav buffer_len(&log_msg)) != buffer_len(&log_msg)) 115e146993eSDag-Erling Smørgrav fatal("%s: write: %s", __func__, strerror(errno)); 116e146993eSDag-Erling Smørgrav buffer_free(&log_msg); 117e146993eSDag-Erling Smørgrav } 118e146993eSDag-Erling Smørgrav 1191ec0d754SDag-Erling Smørgrav int 1201ec0d754SDag-Erling Smørgrav mm_is_monitor(void) 1211ec0d754SDag-Erling Smørgrav { 1221ec0d754SDag-Erling Smørgrav /* 1231ec0d754SDag-Erling Smørgrav * m_pid is only set in the privileged part, and 1241ec0d754SDag-Erling Smørgrav * points to the unprivileged child. 1251ec0d754SDag-Erling Smørgrav */ 1261ec0d754SDag-Erling Smørgrav return (pmonitor && pmonitor->m_pid > 0); 1271ec0d754SDag-Erling Smørgrav } 1281ec0d754SDag-Erling Smørgrav 129545d5ecaSDag-Erling Smørgrav void 13021e764dfSDag-Erling Smørgrav mm_request_send(int sock, enum monitor_reqtype type, Buffer *m) 131545d5ecaSDag-Erling Smørgrav { 132545d5ecaSDag-Erling Smørgrav u_int mlen = buffer_len(m); 133f388f5efSDag-Erling Smørgrav u_char buf[5]; 134545d5ecaSDag-Erling Smørgrav 135545d5ecaSDag-Erling Smørgrav debug3("%s entering: type %d", __func__, type); 136545d5ecaSDag-Erling Smørgrav 137333ee039SDag-Erling Smørgrav put_u32(buf, mlen + 1); 138545d5ecaSDag-Erling Smørgrav buf[4] = (u_char) type; /* 1st byte of payload is mesg-type */ 13921e764dfSDag-Erling Smørgrav if (atomicio(vwrite, sock, buf, sizeof(buf)) != sizeof(buf)) 140d4ecd108SDag-Erling Smørgrav fatal("%s: write: %s", __func__, strerror(errno)); 14121e764dfSDag-Erling Smørgrav if (atomicio(vwrite, sock, buffer_ptr(m), mlen) != mlen) 142d4ecd108SDag-Erling Smørgrav fatal("%s: write: %s", __func__, strerror(errno)); 143545d5ecaSDag-Erling Smørgrav } 144545d5ecaSDag-Erling Smørgrav 145545d5ecaSDag-Erling Smørgrav void 14621e764dfSDag-Erling Smørgrav mm_request_receive(int sock, Buffer *m) 147545d5ecaSDag-Erling Smørgrav { 148545d5ecaSDag-Erling Smørgrav u_char buf[4]; 149545d5ecaSDag-Erling Smørgrav u_int msg_len; 150545d5ecaSDag-Erling Smørgrav 151545d5ecaSDag-Erling Smørgrav debug3("%s entering", __func__); 152545d5ecaSDag-Erling Smørgrav 153d4ecd108SDag-Erling Smørgrav if (atomicio(read, sock, buf, sizeof(buf)) != sizeof(buf)) { 154d4ecd108SDag-Erling Smørgrav if (errno == EPIPE) 1551ec0d754SDag-Erling Smørgrav cleanup_exit(255); 156d4ecd108SDag-Erling Smørgrav fatal("%s: read: %s", __func__, strerror(errno)); 157545d5ecaSDag-Erling Smørgrav } 158333ee039SDag-Erling Smørgrav msg_len = get_u32(buf); 159545d5ecaSDag-Erling Smørgrav if (msg_len > 256 * 1024) 160545d5ecaSDag-Erling Smørgrav fatal("%s: read: bad msg_len %d", __func__, msg_len); 161545d5ecaSDag-Erling Smørgrav buffer_clear(m); 162545d5ecaSDag-Erling Smørgrav buffer_append_space(m, msg_len); 163d4ecd108SDag-Erling Smørgrav if (atomicio(read, sock, buffer_ptr(m), msg_len) != msg_len) 164d4ecd108SDag-Erling Smørgrav fatal("%s: read: %s", __func__, strerror(errno)); 165545d5ecaSDag-Erling Smørgrav } 166545d5ecaSDag-Erling Smørgrav 167545d5ecaSDag-Erling Smørgrav void 16821e764dfSDag-Erling Smørgrav mm_request_receive_expect(int sock, enum monitor_reqtype type, Buffer *m) 169545d5ecaSDag-Erling Smørgrav { 170545d5ecaSDag-Erling Smørgrav u_char rtype; 171545d5ecaSDag-Erling Smørgrav 172545d5ecaSDag-Erling Smørgrav debug3("%s entering: type %d", __func__, type); 173545d5ecaSDag-Erling Smørgrav 17421e764dfSDag-Erling Smørgrav mm_request_receive(sock, m); 175545d5ecaSDag-Erling Smørgrav rtype = buffer_get_char(m); 176545d5ecaSDag-Erling Smørgrav if (rtype != type) 177545d5ecaSDag-Erling Smørgrav fatal("%s: read: rtype %d != type %d", __func__, 178545d5ecaSDag-Erling Smørgrav rtype, type); 179545d5ecaSDag-Erling Smørgrav } 180545d5ecaSDag-Erling Smørgrav 181*a0ee8cc6SDag-Erling Smørgrav #ifdef WITH_OPENSSL 182545d5ecaSDag-Erling Smørgrav DH * 183545d5ecaSDag-Erling Smørgrav mm_choose_dh(int min, int nbits, int max) 184545d5ecaSDag-Erling Smørgrav { 185545d5ecaSDag-Erling Smørgrav BIGNUM *p, *g; 186545d5ecaSDag-Erling Smørgrav int success = 0; 187545d5ecaSDag-Erling Smørgrav Buffer m; 188545d5ecaSDag-Erling Smørgrav 189545d5ecaSDag-Erling Smørgrav buffer_init(&m); 190545d5ecaSDag-Erling Smørgrav buffer_put_int(&m, min); 191545d5ecaSDag-Erling Smørgrav buffer_put_int(&m, nbits); 192545d5ecaSDag-Erling Smørgrav buffer_put_int(&m, max); 193545d5ecaSDag-Erling Smørgrav 194545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_MODULI, &m); 195545d5ecaSDag-Erling Smørgrav 196545d5ecaSDag-Erling Smørgrav debug3("%s: waiting for MONITOR_ANS_MODULI", __func__); 197545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_MODULI, &m); 198545d5ecaSDag-Erling Smørgrav 199545d5ecaSDag-Erling Smørgrav success = buffer_get_char(&m); 200545d5ecaSDag-Erling Smørgrav if (success == 0) 201545d5ecaSDag-Erling Smørgrav fatal("%s: MONITOR_ANS_MODULI failed", __func__); 202545d5ecaSDag-Erling Smørgrav 203545d5ecaSDag-Erling Smørgrav if ((p = BN_new()) == NULL) 204545d5ecaSDag-Erling Smørgrav fatal("%s: BN_new failed", __func__); 205545d5ecaSDag-Erling Smørgrav if ((g = BN_new()) == NULL) 206545d5ecaSDag-Erling Smørgrav fatal("%s: BN_new failed", __func__); 207545d5ecaSDag-Erling Smørgrav buffer_get_bignum2(&m, p); 208545d5ecaSDag-Erling Smørgrav buffer_get_bignum2(&m, g); 209545d5ecaSDag-Erling Smørgrav 210545d5ecaSDag-Erling Smørgrav debug3("%s: remaining %d", __func__, buffer_len(&m)); 211545d5ecaSDag-Erling Smørgrav buffer_free(&m); 212545d5ecaSDag-Erling Smørgrav 213545d5ecaSDag-Erling Smørgrav return (dh_new_group(g, p)); 214545d5ecaSDag-Erling Smørgrav } 215*a0ee8cc6SDag-Erling Smørgrav #endif 216545d5ecaSDag-Erling Smørgrav 217545d5ecaSDag-Erling Smørgrav int 218545d5ecaSDag-Erling Smørgrav mm_key_sign(Key *key, u_char **sigp, u_int *lenp, u_char *data, u_int datalen) 219545d5ecaSDag-Erling Smørgrav { 220545d5ecaSDag-Erling Smørgrav Kex *kex = *pmonitor->m_pkex; 221545d5ecaSDag-Erling Smørgrav Buffer m; 222545d5ecaSDag-Erling Smørgrav 223545d5ecaSDag-Erling Smørgrav debug3("%s entering", __func__); 224545d5ecaSDag-Erling Smørgrav 225545d5ecaSDag-Erling Smørgrav buffer_init(&m); 226545d5ecaSDag-Erling Smørgrav buffer_put_int(&m, kex->host_key_index(key)); 227545d5ecaSDag-Erling Smørgrav buffer_put_string(&m, data, datalen); 228545d5ecaSDag-Erling Smørgrav 229545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SIGN, &m); 230545d5ecaSDag-Erling Smørgrav 231545d5ecaSDag-Erling Smørgrav debug3("%s: waiting for MONITOR_ANS_SIGN", __func__); 232545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SIGN, &m); 233545d5ecaSDag-Erling Smørgrav *sigp = buffer_get_string(&m, lenp); 234545d5ecaSDag-Erling Smørgrav buffer_free(&m); 235545d5ecaSDag-Erling Smørgrav 236545d5ecaSDag-Erling Smørgrav return (0); 237545d5ecaSDag-Erling Smørgrav } 238545d5ecaSDag-Erling Smørgrav 239545d5ecaSDag-Erling Smørgrav struct passwd * 24021e764dfSDag-Erling Smørgrav mm_getpwnamallow(const char *username) 241545d5ecaSDag-Erling Smørgrav { 242545d5ecaSDag-Erling Smørgrav Buffer m; 243545d5ecaSDag-Erling Smørgrav struct passwd *pw; 244e146993eSDag-Erling Smørgrav u_int len, i; 245d4af9e69SDag-Erling Smørgrav ServerOptions *newopts; 246545d5ecaSDag-Erling Smørgrav 247545d5ecaSDag-Erling Smørgrav debug3("%s entering", __func__); 248545d5ecaSDag-Erling Smørgrav 249545d5ecaSDag-Erling Smørgrav buffer_init(&m); 25021e764dfSDag-Erling Smørgrav buffer_put_cstring(&m, username); 251545d5ecaSDag-Erling Smørgrav 252545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PWNAM, &m); 253545d5ecaSDag-Erling Smørgrav 254545d5ecaSDag-Erling Smørgrav debug3("%s: waiting for MONITOR_ANS_PWNAM", __func__); 255545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PWNAM, &m); 256545d5ecaSDag-Erling Smørgrav 257545d5ecaSDag-Erling Smørgrav if (buffer_get_char(&m) == 0) { 258d4af9e69SDag-Erling Smørgrav pw = NULL; 259d4af9e69SDag-Erling Smørgrav goto out; 260545d5ecaSDag-Erling Smørgrav } 261d4af9e69SDag-Erling Smørgrav pw = buffer_get_string(&m, &len); 262d4af9e69SDag-Erling Smørgrav if (len != sizeof(struct passwd)) 263545d5ecaSDag-Erling Smørgrav fatal("%s: struct passwd size mismatch", __func__); 264545d5ecaSDag-Erling Smørgrav pw->pw_name = buffer_get_string(&m, NULL); 265545d5ecaSDag-Erling Smørgrav pw->pw_passwd = buffer_get_string(&m, NULL); 266e4a9863fSDag-Erling Smørgrav #ifdef HAVE_STRUCT_PASSWD_PW_GECOS 267545d5ecaSDag-Erling Smørgrav pw->pw_gecos = buffer_get_string(&m, NULL); 268e4a9863fSDag-Erling Smørgrav #endif 269e4a9863fSDag-Erling Smørgrav #ifdef HAVE_STRUCT_PASSWD_PW_CLASS 270545d5ecaSDag-Erling Smørgrav pw->pw_class = buffer_get_string(&m, NULL); 27183d2307dSDag-Erling Smørgrav #endif 272545d5ecaSDag-Erling Smørgrav pw->pw_dir = buffer_get_string(&m, NULL); 273545d5ecaSDag-Erling Smørgrav pw->pw_shell = buffer_get_string(&m, NULL); 274d4af9e69SDag-Erling Smørgrav 275d4af9e69SDag-Erling Smørgrav out: 276d4af9e69SDag-Erling Smørgrav /* copy options block as a Match directive may have changed some */ 277d4af9e69SDag-Erling Smørgrav newopts = buffer_get_string(&m, &len); 278d4af9e69SDag-Erling Smørgrav if (len != sizeof(*newopts)) 279d4af9e69SDag-Erling Smørgrav fatal("%s: option block size mismatch", __func__); 280e146993eSDag-Erling Smørgrav 281e146993eSDag-Erling Smørgrav #define M_CP_STROPT(x) do { \ 282e146993eSDag-Erling Smørgrav if (newopts->x != NULL) \ 283e146993eSDag-Erling Smørgrav newopts->x = buffer_get_string(&m, NULL); \ 284e146993eSDag-Erling Smørgrav } while (0) 285e146993eSDag-Erling Smørgrav #define M_CP_STRARRAYOPT(x, nx) do { \ 286e146993eSDag-Erling Smørgrav for (i = 0; i < newopts->nx; i++) \ 287e146993eSDag-Erling Smørgrav newopts->x[i] = buffer_get_string(&m, NULL); \ 288e146993eSDag-Erling Smørgrav } while (0) 289e146993eSDag-Erling Smørgrav /* See comment in servconf.h */ 290e146993eSDag-Erling Smørgrav COPY_MATCH_STRING_OPTS(); 291e146993eSDag-Erling Smørgrav #undef M_CP_STROPT 292e146993eSDag-Erling Smørgrav #undef M_CP_STRARRAYOPT 293e146993eSDag-Erling Smørgrav 294d4af9e69SDag-Erling Smørgrav copy_set_server_options(&options, newopts, 1); 295e4a9863fSDag-Erling Smørgrav free(newopts); 296d4af9e69SDag-Erling Smørgrav 297545d5ecaSDag-Erling Smørgrav buffer_free(&m); 298545d5ecaSDag-Erling Smørgrav 299545d5ecaSDag-Erling Smørgrav return (pw); 300545d5ecaSDag-Erling Smørgrav } 301545d5ecaSDag-Erling Smørgrav 3021ec0d754SDag-Erling Smørgrav char * 3031ec0d754SDag-Erling Smørgrav mm_auth2_read_banner(void) 304545d5ecaSDag-Erling Smørgrav { 305545d5ecaSDag-Erling Smørgrav Buffer m; 306545d5ecaSDag-Erling Smørgrav char *banner; 307545d5ecaSDag-Erling Smørgrav 308545d5ecaSDag-Erling Smørgrav debug3("%s entering", __func__); 309545d5ecaSDag-Erling Smørgrav 310545d5ecaSDag-Erling Smørgrav buffer_init(&m); 311545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTH2_READ_BANNER, &m); 312545d5ecaSDag-Erling Smørgrav buffer_clear(&m); 313545d5ecaSDag-Erling Smørgrav 3141ec0d754SDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, 3151ec0d754SDag-Erling Smørgrav MONITOR_ANS_AUTH2_READ_BANNER, &m); 316545d5ecaSDag-Erling Smørgrav banner = buffer_get_string(&m, NULL); 317545d5ecaSDag-Erling Smørgrav buffer_free(&m); 318545d5ecaSDag-Erling Smørgrav 3191ec0d754SDag-Erling Smørgrav /* treat empty banner as missing banner */ 3201ec0d754SDag-Erling Smørgrav if (strlen(banner) == 0) { 321e4a9863fSDag-Erling Smørgrav free(banner); 3221ec0d754SDag-Erling Smørgrav banner = NULL; 3231ec0d754SDag-Erling Smørgrav } 324545d5ecaSDag-Erling Smørgrav return (banner); 325545d5ecaSDag-Erling Smørgrav } 326545d5ecaSDag-Erling Smørgrav 327545d5ecaSDag-Erling Smørgrav /* Inform the privileged process about service and style */ 328545d5ecaSDag-Erling Smørgrav 329545d5ecaSDag-Erling Smørgrav void 330545d5ecaSDag-Erling Smørgrav mm_inform_authserv(char *service, char *style) 331545d5ecaSDag-Erling Smørgrav { 332545d5ecaSDag-Erling Smørgrav Buffer m; 333545d5ecaSDag-Erling Smørgrav 334545d5ecaSDag-Erling Smørgrav debug3("%s entering", __func__); 335545d5ecaSDag-Erling Smørgrav 336545d5ecaSDag-Erling Smørgrav buffer_init(&m); 337545d5ecaSDag-Erling Smørgrav buffer_put_cstring(&m, service); 338545d5ecaSDag-Erling Smørgrav buffer_put_cstring(&m, style ? style : ""); 339545d5ecaSDag-Erling Smørgrav 340545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHSERV, &m); 341545d5ecaSDag-Erling Smørgrav 342545d5ecaSDag-Erling Smørgrav buffer_free(&m); 343545d5ecaSDag-Erling Smørgrav } 344545d5ecaSDag-Erling Smørgrav 345545d5ecaSDag-Erling Smørgrav /* Do the password authentication */ 346545d5ecaSDag-Erling Smørgrav int 347545d5ecaSDag-Erling Smørgrav mm_auth_password(Authctxt *authctxt, char *password) 348545d5ecaSDag-Erling Smørgrav { 349545d5ecaSDag-Erling Smørgrav Buffer m; 350545d5ecaSDag-Erling Smørgrav int authenticated = 0; 351545d5ecaSDag-Erling Smørgrav 352545d5ecaSDag-Erling Smørgrav debug3("%s entering", __func__); 353545d5ecaSDag-Erling Smørgrav 354545d5ecaSDag-Erling Smørgrav buffer_init(&m); 355545d5ecaSDag-Erling Smørgrav buffer_put_cstring(&m, password); 356545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHPASSWORD, &m); 357545d5ecaSDag-Erling Smørgrav 358545d5ecaSDag-Erling Smørgrav debug3("%s: waiting for MONITOR_ANS_AUTHPASSWORD", __func__); 359545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUTHPASSWORD, &m); 360545d5ecaSDag-Erling Smørgrav 361545d5ecaSDag-Erling Smørgrav authenticated = buffer_get_int(&m); 362545d5ecaSDag-Erling Smørgrav 363545d5ecaSDag-Erling Smørgrav buffer_free(&m); 364545d5ecaSDag-Erling Smørgrav 365545d5ecaSDag-Erling Smørgrav debug3("%s: user %sauthenticated", 366545d5ecaSDag-Erling Smørgrav __func__, authenticated ? "" : "not "); 367545d5ecaSDag-Erling Smørgrav return (authenticated); 368545d5ecaSDag-Erling Smørgrav } 369545d5ecaSDag-Erling Smørgrav 370545d5ecaSDag-Erling Smørgrav int 371545d5ecaSDag-Erling Smørgrav mm_user_key_allowed(struct passwd *pw, Key *key) 372545d5ecaSDag-Erling Smørgrav { 373545d5ecaSDag-Erling Smørgrav return (mm_key_allowed(MM_USERKEY, NULL, NULL, key)); 374545d5ecaSDag-Erling Smørgrav } 375545d5ecaSDag-Erling Smørgrav 376545d5ecaSDag-Erling Smørgrav int 377545d5ecaSDag-Erling Smørgrav mm_hostbased_key_allowed(struct passwd *pw, char *user, char *host, 378545d5ecaSDag-Erling Smørgrav Key *key) 379545d5ecaSDag-Erling Smørgrav { 380545d5ecaSDag-Erling Smørgrav return (mm_key_allowed(MM_HOSTKEY, user, host, key)); 381545d5ecaSDag-Erling Smørgrav } 382545d5ecaSDag-Erling Smørgrav 383545d5ecaSDag-Erling Smørgrav int 384545d5ecaSDag-Erling Smørgrav mm_auth_rhosts_rsa_key_allowed(struct passwd *pw, char *user, 385545d5ecaSDag-Erling Smørgrav char *host, Key *key) 386545d5ecaSDag-Erling Smørgrav { 387545d5ecaSDag-Erling Smørgrav int ret; 388545d5ecaSDag-Erling Smørgrav 389545d5ecaSDag-Erling Smørgrav key->type = KEY_RSA; /* XXX hack for key_to_blob */ 390545d5ecaSDag-Erling Smørgrav ret = mm_key_allowed(MM_RSAHOSTKEY, user, host, key); 391545d5ecaSDag-Erling Smørgrav key->type = KEY_RSA1; 392545d5ecaSDag-Erling Smørgrav return (ret); 393545d5ecaSDag-Erling Smørgrav } 394545d5ecaSDag-Erling Smørgrav 395545d5ecaSDag-Erling Smørgrav int 396545d5ecaSDag-Erling Smørgrav mm_key_allowed(enum mm_keytype type, char *user, char *host, Key *key) 397545d5ecaSDag-Erling Smørgrav { 398545d5ecaSDag-Erling Smørgrav Buffer m; 399545d5ecaSDag-Erling Smørgrav u_char *blob; 400545d5ecaSDag-Erling Smørgrav u_int len; 401e73e9afaSDag-Erling Smørgrav int allowed = 0, have_forced = 0; 402545d5ecaSDag-Erling Smørgrav 403545d5ecaSDag-Erling Smørgrav debug3("%s entering", __func__); 404545d5ecaSDag-Erling Smørgrav 405545d5ecaSDag-Erling Smørgrav /* Convert the key to a blob and the pass it over */ 406545d5ecaSDag-Erling Smørgrav if (!key_to_blob(key, &blob, &len)) 407545d5ecaSDag-Erling Smørgrav return (0); 408545d5ecaSDag-Erling Smørgrav 409545d5ecaSDag-Erling Smørgrav buffer_init(&m); 410545d5ecaSDag-Erling Smørgrav buffer_put_int(&m, type); 411545d5ecaSDag-Erling Smørgrav buffer_put_cstring(&m, user ? user : ""); 412545d5ecaSDag-Erling Smørgrav buffer_put_cstring(&m, host ? host : ""); 413545d5ecaSDag-Erling Smørgrav buffer_put_string(&m, blob, len); 414e4a9863fSDag-Erling Smørgrav free(blob); 415545d5ecaSDag-Erling Smørgrav 416545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYALLOWED, &m); 417545d5ecaSDag-Erling Smørgrav 418545d5ecaSDag-Erling Smørgrav debug3("%s: waiting for MONITOR_ANS_KEYALLOWED", __func__); 419545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYALLOWED, &m); 420545d5ecaSDag-Erling Smørgrav 421545d5ecaSDag-Erling Smørgrav allowed = buffer_get_int(&m); 422545d5ecaSDag-Erling Smørgrav 423e73e9afaSDag-Erling Smørgrav /* fake forced command */ 424e73e9afaSDag-Erling Smørgrav auth_clear_options(); 425e73e9afaSDag-Erling Smørgrav have_forced = buffer_get_int(&m); 426e73e9afaSDag-Erling Smørgrav forced_command = have_forced ? xstrdup("true") : NULL; 427e73e9afaSDag-Erling Smørgrav 428545d5ecaSDag-Erling Smørgrav buffer_free(&m); 429545d5ecaSDag-Erling Smørgrav 430545d5ecaSDag-Erling Smørgrav return (allowed); 431545d5ecaSDag-Erling Smørgrav } 432545d5ecaSDag-Erling Smørgrav 433545d5ecaSDag-Erling Smørgrav /* 434545d5ecaSDag-Erling Smørgrav * This key verify needs to send the key type along, because the 435545d5ecaSDag-Erling Smørgrav * privileged parent makes the decision if the key is allowed 436545d5ecaSDag-Erling Smørgrav * for authentication. 437545d5ecaSDag-Erling Smørgrav */ 438545d5ecaSDag-Erling Smørgrav 439545d5ecaSDag-Erling Smørgrav int 440545d5ecaSDag-Erling Smørgrav mm_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen) 441545d5ecaSDag-Erling Smørgrav { 442545d5ecaSDag-Erling Smørgrav Buffer m; 443545d5ecaSDag-Erling Smørgrav u_char *blob; 444545d5ecaSDag-Erling Smørgrav u_int len; 445545d5ecaSDag-Erling Smørgrav int verified = 0; 446545d5ecaSDag-Erling Smørgrav 447545d5ecaSDag-Erling Smørgrav debug3("%s entering", __func__); 448545d5ecaSDag-Erling Smørgrav 449545d5ecaSDag-Erling Smørgrav /* Convert the key to a blob and the pass it over */ 450545d5ecaSDag-Erling Smørgrav if (!key_to_blob(key, &blob, &len)) 451545d5ecaSDag-Erling Smørgrav return (0); 452545d5ecaSDag-Erling Smørgrav 453545d5ecaSDag-Erling Smørgrav buffer_init(&m); 454545d5ecaSDag-Erling Smørgrav buffer_put_string(&m, blob, len); 455545d5ecaSDag-Erling Smørgrav buffer_put_string(&m, sig, siglen); 456545d5ecaSDag-Erling Smørgrav buffer_put_string(&m, data, datalen); 457e4a9863fSDag-Erling Smørgrav free(blob); 458545d5ecaSDag-Erling Smørgrav 459545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYVERIFY, &m); 460545d5ecaSDag-Erling Smørgrav 461545d5ecaSDag-Erling Smørgrav debug3("%s: waiting for MONITOR_ANS_KEYVERIFY", __func__); 462545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYVERIFY, &m); 463545d5ecaSDag-Erling Smørgrav 464545d5ecaSDag-Erling Smørgrav verified = buffer_get_int(&m); 465545d5ecaSDag-Erling Smørgrav 466545d5ecaSDag-Erling Smørgrav buffer_free(&m); 467545d5ecaSDag-Erling Smørgrav 468545d5ecaSDag-Erling Smørgrav return (verified); 469545d5ecaSDag-Erling Smørgrav } 470545d5ecaSDag-Erling Smørgrav 471545d5ecaSDag-Erling Smørgrav /* Export key state after authentication */ 472545d5ecaSDag-Erling Smørgrav Newkeys * 473545d5ecaSDag-Erling Smørgrav mm_newkeys_from_blob(u_char *blob, int blen) 474545d5ecaSDag-Erling Smørgrav { 475545d5ecaSDag-Erling Smørgrav Buffer b; 476545d5ecaSDag-Erling Smørgrav u_int len; 477545d5ecaSDag-Erling Smørgrav Newkeys *newkey = NULL; 478545d5ecaSDag-Erling Smørgrav Enc *enc; 479545d5ecaSDag-Erling Smørgrav Mac *mac; 480545d5ecaSDag-Erling Smørgrav Comp *comp; 481545d5ecaSDag-Erling Smørgrav 482545d5ecaSDag-Erling Smørgrav debug3("%s: %p(%d)", __func__, blob, blen); 483545d5ecaSDag-Erling Smørgrav #ifdef DEBUG_PK 484545d5ecaSDag-Erling Smørgrav dump_base64(stderr, blob, blen); 485545d5ecaSDag-Erling Smørgrav #endif 486545d5ecaSDag-Erling Smørgrav buffer_init(&b); 487545d5ecaSDag-Erling Smørgrav buffer_append(&b, blob, blen); 488545d5ecaSDag-Erling Smørgrav 4890a37d4a3SXin LI newkey = xcalloc(1, sizeof(*newkey)); 490545d5ecaSDag-Erling Smørgrav enc = &newkey->enc; 491545d5ecaSDag-Erling Smørgrav mac = &newkey->mac; 492545d5ecaSDag-Erling Smørgrav comp = &newkey->comp; 493545d5ecaSDag-Erling Smørgrav 494545d5ecaSDag-Erling Smørgrav /* Enc structure */ 495545d5ecaSDag-Erling Smørgrav enc->name = buffer_get_string(&b, NULL); 496545d5ecaSDag-Erling Smørgrav buffer_get(&b, &enc->cipher, sizeof(enc->cipher)); 497545d5ecaSDag-Erling Smørgrav enc->enabled = buffer_get_int(&b); 498545d5ecaSDag-Erling Smørgrav enc->block_size = buffer_get_int(&b); 499545d5ecaSDag-Erling Smørgrav enc->key = buffer_get_string(&b, &enc->key_len); 5006888a9beSDag-Erling Smørgrav enc->iv = buffer_get_string(&b, &enc->iv_len); 501545d5ecaSDag-Erling Smørgrav 502545d5ecaSDag-Erling Smørgrav if (enc->name == NULL || cipher_by_name(enc->name) != enc->cipher) 503545d5ecaSDag-Erling Smørgrav fatal("%s: bad cipher name %s or pointer %p", __func__, 504545d5ecaSDag-Erling Smørgrav enc->name, enc->cipher); 505545d5ecaSDag-Erling Smørgrav 506545d5ecaSDag-Erling Smørgrav /* Mac structure */ 5076888a9beSDag-Erling Smørgrav if (cipher_authlen(enc->cipher) == 0) { 508545d5ecaSDag-Erling Smørgrav mac->name = buffer_get_string(&b, NULL); 509d4af9e69SDag-Erling Smørgrav if (mac->name == NULL || mac_setup(mac, mac->name) == -1) 510d4af9e69SDag-Erling Smørgrav fatal("%s: can not setup mac %s", __func__, mac->name); 511545d5ecaSDag-Erling Smørgrav mac->enabled = buffer_get_int(&b); 512545d5ecaSDag-Erling Smørgrav mac->key = buffer_get_string(&b, &len); 513545d5ecaSDag-Erling Smørgrav if (len > mac->key_len) 514f388f5efSDag-Erling Smørgrav fatal("%s: bad mac key length: %u > %d", __func__, len, 515545d5ecaSDag-Erling Smørgrav mac->key_len); 516545d5ecaSDag-Erling Smørgrav mac->key_len = len; 5176888a9beSDag-Erling Smørgrav } 518545d5ecaSDag-Erling Smørgrav 519545d5ecaSDag-Erling Smørgrav /* Comp structure */ 520545d5ecaSDag-Erling Smørgrav comp->type = buffer_get_int(&b); 521545d5ecaSDag-Erling Smørgrav comp->enabled = buffer_get_int(&b); 522545d5ecaSDag-Erling Smørgrav comp->name = buffer_get_string(&b, NULL); 523545d5ecaSDag-Erling Smørgrav 524545d5ecaSDag-Erling Smørgrav len = buffer_len(&b); 525545d5ecaSDag-Erling Smørgrav if (len != 0) 526f388f5efSDag-Erling Smørgrav error("newkeys_from_blob: remaining bytes in blob %u", len); 527545d5ecaSDag-Erling Smørgrav buffer_free(&b); 528545d5ecaSDag-Erling Smørgrav return (newkey); 529545d5ecaSDag-Erling Smørgrav } 530545d5ecaSDag-Erling Smørgrav 531545d5ecaSDag-Erling Smørgrav int 532545d5ecaSDag-Erling Smørgrav mm_newkeys_to_blob(int mode, u_char **blobp, u_int *lenp) 533545d5ecaSDag-Erling Smørgrav { 534545d5ecaSDag-Erling Smørgrav Buffer b; 535545d5ecaSDag-Erling Smørgrav int len; 536545d5ecaSDag-Erling Smørgrav Enc *enc; 537545d5ecaSDag-Erling Smørgrav Mac *mac; 538545d5ecaSDag-Erling Smørgrav Comp *comp; 5397aee6ffeSDag-Erling Smørgrav Newkeys *newkey = (Newkeys *)packet_get_newkeys(mode); 540545d5ecaSDag-Erling Smørgrav 541545d5ecaSDag-Erling Smørgrav debug3("%s: converting %p", __func__, newkey); 542545d5ecaSDag-Erling Smørgrav 543545d5ecaSDag-Erling Smørgrav if (newkey == NULL) { 544545d5ecaSDag-Erling Smørgrav error("%s: newkey == NULL", __func__); 545545d5ecaSDag-Erling Smørgrav return 0; 546545d5ecaSDag-Erling Smørgrav } 547545d5ecaSDag-Erling Smørgrav enc = &newkey->enc; 548545d5ecaSDag-Erling Smørgrav mac = &newkey->mac; 549545d5ecaSDag-Erling Smørgrav comp = &newkey->comp; 550545d5ecaSDag-Erling Smørgrav 551545d5ecaSDag-Erling Smørgrav buffer_init(&b); 552545d5ecaSDag-Erling Smørgrav /* Enc structure */ 553545d5ecaSDag-Erling Smørgrav buffer_put_cstring(&b, enc->name); 554545d5ecaSDag-Erling Smørgrav /* The cipher struct is constant and shared, you export pointer */ 555545d5ecaSDag-Erling Smørgrav buffer_append(&b, &enc->cipher, sizeof(enc->cipher)); 556545d5ecaSDag-Erling Smørgrav buffer_put_int(&b, enc->enabled); 557545d5ecaSDag-Erling Smørgrav buffer_put_int(&b, enc->block_size); 558545d5ecaSDag-Erling Smørgrav buffer_put_string(&b, enc->key, enc->key_len); 5596888a9beSDag-Erling Smørgrav packet_get_keyiv(mode, enc->iv, enc->iv_len); 5606888a9beSDag-Erling Smørgrav buffer_put_string(&b, enc->iv, enc->iv_len); 561545d5ecaSDag-Erling Smørgrav 562545d5ecaSDag-Erling Smørgrav /* Mac structure */ 5636888a9beSDag-Erling Smørgrav if (cipher_authlen(enc->cipher) == 0) { 564545d5ecaSDag-Erling Smørgrav buffer_put_cstring(&b, mac->name); 565545d5ecaSDag-Erling Smørgrav buffer_put_int(&b, mac->enabled); 566545d5ecaSDag-Erling Smørgrav buffer_put_string(&b, mac->key, mac->key_len); 5676888a9beSDag-Erling Smørgrav } 568545d5ecaSDag-Erling Smørgrav 569545d5ecaSDag-Erling Smørgrav /* Comp structure */ 570545d5ecaSDag-Erling Smørgrav buffer_put_int(&b, comp->type); 571545d5ecaSDag-Erling Smørgrav buffer_put_int(&b, comp->enabled); 572545d5ecaSDag-Erling Smørgrav buffer_put_cstring(&b, comp->name); 573545d5ecaSDag-Erling Smørgrav 574545d5ecaSDag-Erling Smørgrav len = buffer_len(&b); 575545d5ecaSDag-Erling Smørgrav if (lenp != NULL) 576545d5ecaSDag-Erling Smørgrav *lenp = len; 577f388f5efSDag-Erling Smørgrav if (blobp != NULL) { 578f388f5efSDag-Erling Smørgrav *blobp = xmalloc(len); 579f388f5efSDag-Erling Smørgrav memcpy(*blobp, buffer_ptr(&b), len); 580f388f5efSDag-Erling Smørgrav } 581b83788ffSDag-Erling Smørgrav explicit_bzero(buffer_ptr(&b), len); 582f388f5efSDag-Erling Smørgrav buffer_free(&b); 583545d5ecaSDag-Erling Smørgrav return len; 584545d5ecaSDag-Erling Smørgrav } 585545d5ecaSDag-Erling Smørgrav 586545d5ecaSDag-Erling Smørgrav static void 587545d5ecaSDag-Erling Smørgrav mm_send_kex(Buffer *m, Kex *kex) 588545d5ecaSDag-Erling Smørgrav { 589545d5ecaSDag-Erling Smørgrav buffer_put_string(m, kex->session_id, kex->session_id_len); 590545d5ecaSDag-Erling Smørgrav buffer_put_int(m, kex->we_need); 591545d5ecaSDag-Erling Smørgrav buffer_put_int(m, kex->hostkey_type); 592545d5ecaSDag-Erling Smørgrav buffer_put_int(m, kex->kex_type); 593545d5ecaSDag-Erling Smørgrav buffer_put_string(m, buffer_ptr(&kex->my), buffer_len(&kex->my)); 594545d5ecaSDag-Erling Smørgrav buffer_put_string(m, buffer_ptr(&kex->peer), buffer_len(&kex->peer)); 595545d5ecaSDag-Erling Smørgrav buffer_put_int(m, kex->flags); 596545d5ecaSDag-Erling Smørgrav buffer_put_cstring(m, kex->client_version_string); 597545d5ecaSDag-Erling Smørgrav buffer_put_cstring(m, kex->server_version_string); 598545d5ecaSDag-Erling Smørgrav } 599545d5ecaSDag-Erling Smørgrav 600545d5ecaSDag-Erling Smørgrav void 60121e764dfSDag-Erling Smørgrav mm_send_keystate(struct monitor *monitor) 602545d5ecaSDag-Erling Smørgrav { 6037aee6ffeSDag-Erling Smørgrav Buffer m, *input, *output; 604545d5ecaSDag-Erling Smørgrav u_char *blob, *p; 605545d5ecaSDag-Erling Smørgrav u_int bloblen, plen; 606cf2b5f3bSDag-Erling Smørgrav u_int32_t seqnr, packets; 607d4af9e69SDag-Erling Smørgrav u_int64_t blocks, bytes; 608545d5ecaSDag-Erling Smørgrav 609545d5ecaSDag-Erling Smørgrav buffer_init(&m); 610545d5ecaSDag-Erling Smørgrav 611545d5ecaSDag-Erling Smørgrav if (!compat20) { 612545d5ecaSDag-Erling Smørgrav u_char iv[24]; 613545d5ecaSDag-Erling Smørgrav u_char *key; 614545d5ecaSDag-Erling Smørgrav u_int ivlen, keylen; 615545d5ecaSDag-Erling Smørgrav 616545d5ecaSDag-Erling Smørgrav buffer_put_int(&m, packet_get_protocol_flags()); 617545d5ecaSDag-Erling Smørgrav 618545d5ecaSDag-Erling Smørgrav buffer_put_int(&m, packet_get_ssh1_cipher()); 619545d5ecaSDag-Erling Smørgrav 620545d5ecaSDag-Erling Smørgrav debug3("%s: Sending ssh1 KEY+IV", __func__); 621545d5ecaSDag-Erling Smørgrav keylen = packet_get_encryption_key(NULL); 622545d5ecaSDag-Erling Smørgrav key = xmalloc(keylen+1); /* add 1 if keylen == 0 */ 623545d5ecaSDag-Erling Smørgrav keylen = packet_get_encryption_key(key); 624545d5ecaSDag-Erling Smørgrav buffer_put_string(&m, key, keylen); 625b83788ffSDag-Erling Smørgrav explicit_bzero(key, keylen); 626e4a9863fSDag-Erling Smørgrav free(key); 627545d5ecaSDag-Erling Smørgrav 628545d5ecaSDag-Erling Smørgrav ivlen = packet_get_keyiv_len(MODE_OUT); 629545d5ecaSDag-Erling Smørgrav packet_get_keyiv(MODE_OUT, iv, ivlen); 630545d5ecaSDag-Erling Smørgrav buffer_put_string(&m, iv, ivlen); 6316888a9beSDag-Erling Smørgrav ivlen = packet_get_keyiv_len(MODE_IN); 632545d5ecaSDag-Erling Smørgrav packet_get_keyiv(MODE_IN, iv, ivlen); 633545d5ecaSDag-Erling Smørgrav buffer_put_string(&m, iv, ivlen); 634545d5ecaSDag-Erling Smørgrav goto skip; 635545d5ecaSDag-Erling Smørgrav } else { 636545d5ecaSDag-Erling Smørgrav /* Kex for rekeying */ 63721e764dfSDag-Erling Smørgrav mm_send_kex(&m, *monitor->m_pkex); 638545d5ecaSDag-Erling Smørgrav } 639545d5ecaSDag-Erling Smørgrav 640545d5ecaSDag-Erling Smørgrav debug3("%s: Sending new keys: %p %p", 6417aee6ffeSDag-Erling Smørgrav __func__, packet_get_newkeys(MODE_OUT), 6427aee6ffeSDag-Erling Smørgrav packet_get_newkeys(MODE_IN)); 643545d5ecaSDag-Erling Smørgrav 644545d5ecaSDag-Erling Smørgrav /* Keys from Kex */ 645545d5ecaSDag-Erling Smørgrav if (!mm_newkeys_to_blob(MODE_OUT, &blob, &bloblen)) 646545d5ecaSDag-Erling Smørgrav fatal("%s: conversion of newkeys failed", __func__); 647545d5ecaSDag-Erling Smørgrav 648545d5ecaSDag-Erling Smørgrav buffer_put_string(&m, blob, bloblen); 649e4a9863fSDag-Erling Smørgrav free(blob); 650545d5ecaSDag-Erling Smørgrav 651545d5ecaSDag-Erling Smørgrav if (!mm_newkeys_to_blob(MODE_IN, &blob, &bloblen)) 652545d5ecaSDag-Erling Smørgrav fatal("%s: conversion of newkeys failed", __func__); 653545d5ecaSDag-Erling Smørgrav 654545d5ecaSDag-Erling Smørgrav buffer_put_string(&m, blob, bloblen); 655e4a9863fSDag-Erling Smørgrav free(blob); 656545d5ecaSDag-Erling Smørgrav 657d4af9e69SDag-Erling Smørgrav packet_get_state(MODE_OUT, &seqnr, &blocks, &packets, &bytes); 658cf2b5f3bSDag-Erling Smørgrav buffer_put_int(&m, seqnr); 659cf2b5f3bSDag-Erling Smørgrav buffer_put_int64(&m, blocks); 660cf2b5f3bSDag-Erling Smørgrav buffer_put_int(&m, packets); 661d4af9e69SDag-Erling Smørgrav buffer_put_int64(&m, bytes); 662d4af9e69SDag-Erling Smørgrav packet_get_state(MODE_IN, &seqnr, &blocks, &packets, &bytes); 663cf2b5f3bSDag-Erling Smørgrav buffer_put_int(&m, seqnr); 664cf2b5f3bSDag-Erling Smørgrav buffer_put_int64(&m, blocks); 665cf2b5f3bSDag-Erling Smørgrav buffer_put_int(&m, packets); 666d4af9e69SDag-Erling Smørgrav buffer_put_int64(&m, bytes); 667545d5ecaSDag-Erling Smørgrav 668545d5ecaSDag-Erling Smørgrav debug3("%s: New keys have been sent", __func__); 669545d5ecaSDag-Erling Smørgrav skip: 670545d5ecaSDag-Erling Smørgrav /* More key context */ 671545d5ecaSDag-Erling Smørgrav plen = packet_get_keycontext(MODE_OUT, NULL); 672545d5ecaSDag-Erling Smørgrav p = xmalloc(plen+1); 673545d5ecaSDag-Erling Smørgrav packet_get_keycontext(MODE_OUT, p); 674545d5ecaSDag-Erling Smørgrav buffer_put_string(&m, p, plen); 675e4a9863fSDag-Erling Smørgrav free(p); 676545d5ecaSDag-Erling Smørgrav 677545d5ecaSDag-Erling Smørgrav plen = packet_get_keycontext(MODE_IN, NULL); 678545d5ecaSDag-Erling Smørgrav p = xmalloc(plen+1); 679545d5ecaSDag-Erling Smørgrav packet_get_keycontext(MODE_IN, p); 680545d5ecaSDag-Erling Smørgrav buffer_put_string(&m, p, plen); 681e4a9863fSDag-Erling Smørgrav free(p); 682545d5ecaSDag-Erling Smørgrav 683545d5ecaSDag-Erling Smørgrav /* Compression state */ 684545d5ecaSDag-Erling Smørgrav debug3("%s: Sending compression state", __func__); 685545d5ecaSDag-Erling Smørgrav buffer_put_string(&m, &outgoing_stream, sizeof(outgoing_stream)); 686545d5ecaSDag-Erling Smørgrav buffer_put_string(&m, &incoming_stream, sizeof(incoming_stream)); 687545d5ecaSDag-Erling Smørgrav 688545d5ecaSDag-Erling Smørgrav /* Network I/O buffers */ 6897aee6ffeSDag-Erling Smørgrav input = (Buffer *)packet_get_input(); 6907aee6ffeSDag-Erling Smørgrav output = (Buffer *)packet_get_output(); 6917aee6ffeSDag-Erling Smørgrav buffer_put_string(&m, buffer_ptr(input), buffer_len(input)); 6927aee6ffeSDag-Erling Smørgrav buffer_put_string(&m, buffer_ptr(output), buffer_len(output)); 6937aee6ffeSDag-Erling Smørgrav 6947aee6ffeSDag-Erling Smørgrav /* Roaming */ 6957aee6ffeSDag-Erling Smørgrav if (compat20) { 6967aee6ffeSDag-Erling Smørgrav buffer_put_int64(&m, get_sent_bytes()); 6977aee6ffeSDag-Erling Smørgrav buffer_put_int64(&m, get_recv_bytes()); 6987aee6ffeSDag-Erling Smørgrav } 699545d5ecaSDag-Erling Smørgrav 70021e764dfSDag-Erling Smørgrav mm_request_send(monitor->m_recvfd, MONITOR_REQ_KEYEXPORT, &m); 701545d5ecaSDag-Erling Smørgrav debug3("%s: Finished sending state", __func__); 702545d5ecaSDag-Erling Smørgrav 703545d5ecaSDag-Erling Smørgrav buffer_free(&m); 704545d5ecaSDag-Erling Smørgrav } 705545d5ecaSDag-Erling Smørgrav 706545d5ecaSDag-Erling Smørgrav int 707333ee039SDag-Erling Smørgrav mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen) 708545d5ecaSDag-Erling Smørgrav { 709545d5ecaSDag-Erling Smørgrav Buffer m; 71021e764dfSDag-Erling Smørgrav char *p, *msg; 711d4af9e69SDag-Erling Smørgrav int success = 0, tmp1 = -1, tmp2 = -1; 712d4af9e69SDag-Erling Smørgrav 713d4af9e69SDag-Erling Smørgrav /* Kludge: ensure there are fds free to receive the pty/tty */ 714d4af9e69SDag-Erling Smørgrav if ((tmp1 = dup(pmonitor->m_recvfd)) == -1 || 715d4af9e69SDag-Erling Smørgrav (tmp2 = dup(pmonitor->m_recvfd)) == -1) { 716d4af9e69SDag-Erling Smørgrav error("%s: cannot allocate fds for pty", __func__); 717d4af9e69SDag-Erling Smørgrav if (tmp1 > 0) 718d4af9e69SDag-Erling Smørgrav close(tmp1); 719d4af9e69SDag-Erling Smørgrav if (tmp2 > 0) 720d4af9e69SDag-Erling Smørgrav close(tmp2); 721d4af9e69SDag-Erling Smørgrav return 0; 722d4af9e69SDag-Erling Smørgrav } 723d4af9e69SDag-Erling Smørgrav close(tmp1); 724d4af9e69SDag-Erling Smørgrav close(tmp2); 725545d5ecaSDag-Erling Smørgrav 726545d5ecaSDag-Erling Smørgrav buffer_init(&m); 727545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTY, &m); 728545d5ecaSDag-Erling Smørgrav 729545d5ecaSDag-Erling Smørgrav debug3("%s: waiting for MONITOR_ANS_PTY", __func__); 730545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PTY, &m); 731545d5ecaSDag-Erling Smørgrav 732545d5ecaSDag-Erling Smørgrav success = buffer_get_int(&m); 733545d5ecaSDag-Erling Smørgrav if (success == 0) { 734545d5ecaSDag-Erling Smørgrav debug3("%s: pty alloc failed", __func__); 735545d5ecaSDag-Erling Smørgrav buffer_free(&m); 736545d5ecaSDag-Erling Smørgrav return (0); 737545d5ecaSDag-Erling Smørgrav } 738545d5ecaSDag-Erling Smørgrav p = buffer_get_string(&m, NULL); 73921e764dfSDag-Erling Smørgrav msg = buffer_get_string(&m, NULL); 740545d5ecaSDag-Erling Smørgrav buffer_free(&m); 741545d5ecaSDag-Erling Smørgrav 742545d5ecaSDag-Erling Smørgrav strlcpy(namebuf, p, namebuflen); /* Possible truncation */ 743e4a9863fSDag-Erling Smørgrav free(p); 744545d5ecaSDag-Erling Smørgrav 74521e764dfSDag-Erling Smørgrav buffer_append(&loginmsg, msg, strlen(msg)); 746e4a9863fSDag-Erling Smørgrav free(msg); 74721e764dfSDag-Erling Smørgrav 748d4af9e69SDag-Erling Smørgrav if ((*ptyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1 || 749d4af9e69SDag-Erling Smørgrav (*ttyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1) 750d4af9e69SDag-Erling Smørgrav fatal("%s: receive fds failed", __func__); 751545d5ecaSDag-Erling Smørgrav 752545d5ecaSDag-Erling Smørgrav /* Success */ 753545d5ecaSDag-Erling Smørgrav return (1); 754545d5ecaSDag-Erling Smørgrav } 755545d5ecaSDag-Erling Smørgrav 756545d5ecaSDag-Erling Smørgrav void 7571ec0d754SDag-Erling Smørgrav mm_session_pty_cleanup2(Session *s) 758545d5ecaSDag-Erling Smørgrav { 759545d5ecaSDag-Erling Smørgrav Buffer m; 760545d5ecaSDag-Erling Smørgrav 761545d5ecaSDag-Erling Smørgrav if (s->ttyfd == -1) 762545d5ecaSDag-Erling Smørgrav return; 763545d5ecaSDag-Erling Smørgrav buffer_init(&m); 764545d5ecaSDag-Erling Smørgrav buffer_put_cstring(&m, s->tty); 765545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTYCLEANUP, &m); 766545d5ecaSDag-Erling Smørgrav buffer_free(&m); 767545d5ecaSDag-Erling Smørgrav 768545d5ecaSDag-Erling Smørgrav /* closed dup'ed master */ 769d4af9e69SDag-Erling Smørgrav if (s->ptymaster != -1 && close(s->ptymaster) < 0) 770d4af9e69SDag-Erling Smørgrav error("close(s->ptymaster/%d): %s", 771d4af9e69SDag-Erling Smørgrav s->ptymaster, strerror(errno)); 772545d5ecaSDag-Erling Smørgrav 773545d5ecaSDag-Erling Smørgrav /* unlink pty from session */ 774545d5ecaSDag-Erling Smørgrav s->ttyfd = -1; 775545d5ecaSDag-Erling Smørgrav } 776545d5ecaSDag-Erling Smørgrav 77783d2307dSDag-Erling Smørgrav #ifdef USE_PAM 77883d2307dSDag-Erling Smørgrav void 7795962c0e9SDag-Erling Smørgrav mm_start_pam(Authctxt *authctxt) 78083d2307dSDag-Erling Smørgrav { 78183d2307dSDag-Erling Smørgrav Buffer m; 78283d2307dSDag-Erling Smørgrav 78383d2307dSDag-Erling Smørgrav debug3("%s entering", __func__); 784cf2b5f3bSDag-Erling Smørgrav if (!options.use_pam) 785cf2b5f3bSDag-Erling Smørgrav fatal("UsePAM=no, but ended up in %s anyway", __func__); 78683d2307dSDag-Erling Smørgrav 78783d2307dSDag-Erling Smørgrav buffer_init(&m); 78883d2307dSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_START, &m); 78983d2307dSDag-Erling Smørgrav 79083d2307dSDag-Erling Smørgrav buffer_free(&m); 79183d2307dSDag-Erling Smørgrav } 792382d19eeSDag-Erling Smørgrav 793cf2b5f3bSDag-Erling Smørgrav u_int 794cf2b5f3bSDag-Erling Smørgrav mm_do_pam_account(void) 795cf2b5f3bSDag-Erling Smørgrav { 796cf2b5f3bSDag-Erling Smørgrav Buffer m; 797cf2b5f3bSDag-Erling Smørgrav u_int ret; 798aa49c926SDag-Erling Smørgrav char *msg; 799cf2b5f3bSDag-Erling Smørgrav 800cf2b5f3bSDag-Erling Smørgrav debug3("%s entering", __func__); 801cf2b5f3bSDag-Erling Smørgrav if (!options.use_pam) 802cf2b5f3bSDag-Erling Smørgrav fatal("UsePAM=no, but ended up in %s anyway", __func__); 803cf2b5f3bSDag-Erling Smørgrav 804cf2b5f3bSDag-Erling Smørgrav buffer_init(&m); 805cf2b5f3bSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_ACCOUNT, &m); 806cf2b5f3bSDag-Erling Smørgrav 807cf2b5f3bSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, 808cf2b5f3bSDag-Erling Smørgrav MONITOR_ANS_PAM_ACCOUNT, &m); 809cf2b5f3bSDag-Erling Smørgrav ret = buffer_get_int(&m); 810aa49c926SDag-Erling Smørgrav msg = buffer_get_string(&m, NULL); 811aa49c926SDag-Erling Smørgrav buffer_append(&loginmsg, msg, strlen(msg)); 812e4a9863fSDag-Erling Smørgrav free(msg); 813cf2b5f3bSDag-Erling Smørgrav 814cf2b5f3bSDag-Erling Smørgrav buffer_free(&m); 815cf2b5f3bSDag-Erling Smørgrav 816cf2b5f3bSDag-Erling Smørgrav debug3("%s returning %d", __func__, ret); 817cf2b5f3bSDag-Erling Smørgrav 818cf2b5f3bSDag-Erling Smørgrav return (ret); 819cf2b5f3bSDag-Erling Smørgrav } 820cf2b5f3bSDag-Erling Smørgrav 821382d19eeSDag-Erling Smørgrav void * 822cf2b5f3bSDag-Erling Smørgrav mm_sshpam_init_ctx(Authctxt *authctxt) 823382d19eeSDag-Erling Smørgrav { 824382d19eeSDag-Erling Smørgrav Buffer m; 825382d19eeSDag-Erling Smørgrav int success; 826382d19eeSDag-Erling Smørgrav 827382d19eeSDag-Erling Smørgrav debug3("%s", __func__); 828382d19eeSDag-Erling Smørgrav buffer_init(&m); 829382d19eeSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_INIT_CTX, &m); 830382d19eeSDag-Erling Smørgrav debug3("%s: waiting for MONITOR_ANS_PAM_INIT_CTX", __func__); 831382d19eeSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_INIT_CTX, &m); 832382d19eeSDag-Erling Smørgrav success = buffer_get_int(&m); 833382d19eeSDag-Erling Smørgrav if (success == 0) { 834382d19eeSDag-Erling Smørgrav debug3("%s: pam_init_ctx failed", __func__); 835382d19eeSDag-Erling Smørgrav buffer_free(&m); 836382d19eeSDag-Erling Smørgrav return (NULL); 837382d19eeSDag-Erling Smørgrav } 838382d19eeSDag-Erling Smørgrav buffer_free(&m); 839382d19eeSDag-Erling Smørgrav return (authctxt); 840382d19eeSDag-Erling Smørgrav } 841382d19eeSDag-Erling Smørgrav 842382d19eeSDag-Erling Smørgrav int 843cf2b5f3bSDag-Erling Smørgrav mm_sshpam_query(void *ctx, char **name, char **info, 844382d19eeSDag-Erling Smørgrav u_int *num, char ***prompts, u_int **echo_on) 845382d19eeSDag-Erling Smørgrav { 846382d19eeSDag-Erling Smørgrav Buffer m; 847d4ecd108SDag-Erling Smørgrav u_int i; 848d4ecd108SDag-Erling Smørgrav int ret; 849382d19eeSDag-Erling Smørgrav 850382d19eeSDag-Erling Smørgrav debug3("%s", __func__); 851382d19eeSDag-Erling Smørgrav buffer_init(&m); 852382d19eeSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_QUERY, &m); 853382d19eeSDag-Erling Smørgrav debug3("%s: waiting for MONITOR_ANS_PAM_QUERY", __func__); 854382d19eeSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_QUERY, &m); 855382d19eeSDag-Erling Smørgrav ret = buffer_get_int(&m); 856382d19eeSDag-Erling Smørgrav debug3("%s: pam_query returned %d", __func__, ret); 857382d19eeSDag-Erling Smørgrav *name = buffer_get_string(&m, NULL); 858382d19eeSDag-Erling Smørgrav *info = buffer_get_string(&m, NULL); 859382d19eeSDag-Erling Smørgrav *num = buffer_get_int(&m); 860333ee039SDag-Erling Smørgrav if (*num > PAM_MAX_NUM_MSG) 861333ee039SDag-Erling Smørgrav fatal("%s: recieved %u PAM messages, expected <= %u", 862333ee039SDag-Erling Smørgrav __func__, *num, PAM_MAX_NUM_MSG); 863333ee039SDag-Erling Smørgrav *prompts = xcalloc((*num + 1), sizeof(char *)); 864333ee039SDag-Erling Smørgrav *echo_on = xcalloc((*num + 1), sizeof(u_int)); 865382d19eeSDag-Erling Smørgrav for (i = 0; i < *num; ++i) { 866382d19eeSDag-Erling Smørgrav (*prompts)[i] = buffer_get_string(&m, NULL); 867382d19eeSDag-Erling Smørgrav (*echo_on)[i] = buffer_get_int(&m); 868382d19eeSDag-Erling Smørgrav } 869382d19eeSDag-Erling Smørgrav buffer_free(&m); 870382d19eeSDag-Erling Smørgrav return (ret); 871382d19eeSDag-Erling Smørgrav } 872382d19eeSDag-Erling Smørgrav 873382d19eeSDag-Erling Smørgrav int 874cf2b5f3bSDag-Erling Smørgrav mm_sshpam_respond(void *ctx, u_int num, char **resp) 875382d19eeSDag-Erling Smørgrav { 876382d19eeSDag-Erling Smørgrav Buffer m; 877d4ecd108SDag-Erling Smørgrav u_int i; 878d4ecd108SDag-Erling Smørgrav int ret; 879382d19eeSDag-Erling Smørgrav 880382d19eeSDag-Erling Smørgrav debug3("%s", __func__); 881382d19eeSDag-Erling Smørgrav buffer_init(&m); 882382d19eeSDag-Erling Smørgrav buffer_put_int(&m, num); 883382d19eeSDag-Erling Smørgrav for (i = 0; i < num; ++i) 884382d19eeSDag-Erling Smørgrav buffer_put_cstring(&m, resp[i]); 885382d19eeSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_RESPOND, &m); 886382d19eeSDag-Erling Smørgrav debug3("%s: waiting for MONITOR_ANS_PAM_RESPOND", __func__); 887382d19eeSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_RESPOND, &m); 888382d19eeSDag-Erling Smørgrav ret = buffer_get_int(&m); 889382d19eeSDag-Erling Smørgrav debug3("%s: pam_respond returned %d", __func__, ret); 890382d19eeSDag-Erling Smørgrav buffer_free(&m); 891382d19eeSDag-Erling Smørgrav return (ret); 892382d19eeSDag-Erling Smørgrav } 893382d19eeSDag-Erling Smørgrav 894382d19eeSDag-Erling Smørgrav void 895cf2b5f3bSDag-Erling Smørgrav mm_sshpam_free_ctx(void *ctxtp) 896382d19eeSDag-Erling Smørgrav { 897382d19eeSDag-Erling Smørgrav Buffer m; 898382d19eeSDag-Erling Smørgrav 899382d19eeSDag-Erling Smørgrav debug3("%s", __func__); 900382d19eeSDag-Erling Smørgrav buffer_init(&m); 901382d19eeSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_FREE_CTX, &m); 902382d19eeSDag-Erling Smørgrav debug3("%s: waiting for MONITOR_ANS_PAM_FREE_CTX", __func__); 903382d19eeSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_FREE_CTX, &m); 904382d19eeSDag-Erling Smørgrav buffer_free(&m); 905382d19eeSDag-Erling Smørgrav } 90683d2307dSDag-Erling Smørgrav #endif /* USE_PAM */ 90783d2307dSDag-Erling Smørgrav 908545d5ecaSDag-Erling Smørgrav /* Request process termination */ 909545d5ecaSDag-Erling Smørgrav 910545d5ecaSDag-Erling Smørgrav void 911545d5ecaSDag-Erling Smørgrav mm_terminate(void) 912545d5ecaSDag-Erling Smørgrav { 913545d5ecaSDag-Erling Smørgrav Buffer m; 914545d5ecaSDag-Erling Smørgrav 915545d5ecaSDag-Erling Smørgrav buffer_init(&m); 916545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_TERM, &m); 917545d5ecaSDag-Erling Smørgrav buffer_free(&m); 918545d5ecaSDag-Erling Smørgrav } 919545d5ecaSDag-Erling Smørgrav 920*a0ee8cc6SDag-Erling Smørgrav #ifdef WITH_SSH1 921545d5ecaSDag-Erling Smørgrav int 922545d5ecaSDag-Erling Smørgrav mm_ssh1_session_key(BIGNUM *num) 923545d5ecaSDag-Erling Smørgrav { 924545d5ecaSDag-Erling Smørgrav int rsafail; 925545d5ecaSDag-Erling Smørgrav Buffer m; 926545d5ecaSDag-Erling Smørgrav 927545d5ecaSDag-Erling Smørgrav buffer_init(&m); 928545d5ecaSDag-Erling Smørgrav buffer_put_bignum2(&m, num); 929545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SESSKEY, &m); 930545d5ecaSDag-Erling Smørgrav 931545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SESSKEY, &m); 932545d5ecaSDag-Erling Smørgrav 933545d5ecaSDag-Erling Smørgrav rsafail = buffer_get_int(&m); 934545d5ecaSDag-Erling Smørgrav buffer_get_bignum2(&m, num); 935545d5ecaSDag-Erling Smørgrav 936545d5ecaSDag-Erling Smørgrav buffer_free(&m); 937545d5ecaSDag-Erling Smørgrav 938545d5ecaSDag-Erling Smørgrav return (rsafail); 939545d5ecaSDag-Erling Smørgrav } 940*a0ee8cc6SDag-Erling Smørgrav #endif 941545d5ecaSDag-Erling Smørgrav 942545d5ecaSDag-Erling Smørgrav static void 943545d5ecaSDag-Erling Smørgrav mm_chall_setup(char **name, char **infotxt, u_int *numprompts, 944545d5ecaSDag-Erling Smørgrav char ***prompts, u_int **echo_on) 945545d5ecaSDag-Erling Smørgrav { 946545d5ecaSDag-Erling Smørgrav *name = xstrdup(""); 947545d5ecaSDag-Erling Smørgrav *infotxt = xstrdup(""); 948545d5ecaSDag-Erling Smørgrav *numprompts = 1; 949333ee039SDag-Erling Smørgrav *prompts = xcalloc(*numprompts, sizeof(char *)); 950333ee039SDag-Erling Smørgrav *echo_on = xcalloc(*numprompts, sizeof(u_int)); 951545d5ecaSDag-Erling Smørgrav (*echo_on)[0] = 0; 952545d5ecaSDag-Erling Smørgrav } 953545d5ecaSDag-Erling Smørgrav 954545d5ecaSDag-Erling Smørgrav int 955545d5ecaSDag-Erling Smørgrav mm_bsdauth_query(void *ctx, char **name, char **infotxt, 956545d5ecaSDag-Erling Smørgrav u_int *numprompts, char ***prompts, u_int **echo_on) 957545d5ecaSDag-Erling Smørgrav { 958545d5ecaSDag-Erling Smørgrav Buffer m; 959e73e9afaSDag-Erling Smørgrav u_int success; 960545d5ecaSDag-Erling Smørgrav char *challenge; 961545d5ecaSDag-Erling Smørgrav 962545d5ecaSDag-Erling Smørgrav debug3("%s: entering", __func__); 963545d5ecaSDag-Erling Smørgrav 964545d5ecaSDag-Erling Smørgrav buffer_init(&m); 965545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHQUERY, &m); 966545d5ecaSDag-Erling Smørgrav 967545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_BSDAUTHQUERY, 968545d5ecaSDag-Erling Smørgrav &m); 969e73e9afaSDag-Erling Smørgrav success = buffer_get_int(&m); 970e73e9afaSDag-Erling Smørgrav if (success == 0) { 971545d5ecaSDag-Erling Smørgrav debug3("%s: no challenge", __func__); 972545d5ecaSDag-Erling Smørgrav buffer_free(&m); 973545d5ecaSDag-Erling Smørgrav return (-1); 974545d5ecaSDag-Erling Smørgrav } 975545d5ecaSDag-Erling Smørgrav 976545d5ecaSDag-Erling Smørgrav /* Get the challenge, and format the response */ 977545d5ecaSDag-Erling Smørgrav challenge = buffer_get_string(&m, NULL); 978545d5ecaSDag-Erling Smørgrav buffer_free(&m); 979545d5ecaSDag-Erling Smørgrav 980545d5ecaSDag-Erling Smørgrav mm_chall_setup(name, infotxt, numprompts, prompts, echo_on); 981545d5ecaSDag-Erling Smørgrav (*prompts)[0] = challenge; 982545d5ecaSDag-Erling Smørgrav 983545d5ecaSDag-Erling Smørgrav debug3("%s: received challenge: %s", __func__, challenge); 984545d5ecaSDag-Erling Smørgrav 985545d5ecaSDag-Erling Smørgrav return (0); 986545d5ecaSDag-Erling Smørgrav } 987545d5ecaSDag-Erling Smørgrav 988545d5ecaSDag-Erling Smørgrav int 989545d5ecaSDag-Erling Smørgrav mm_bsdauth_respond(void *ctx, u_int numresponses, char **responses) 990545d5ecaSDag-Erling Smørgrav { 991545d5ecaSDag-Erling Smørgrav Buffer m; 992545d5ecaSDag-Erling Smørgrav int authok; 993545d5ecaSDag-Erling Smørgrav 994545d5ecaSDag-Erling Smørgrav debug3("%s: entering", __func__); 995545d5ecaSDag-Erling Smørgrav if (numresponses != 1) 996545d5ecaSDag-Erling Smørgrav return (-1); 997545d5ecaSDag-Erling Smørgrav 998545d5ecaSDag-Erling Smørgrav buffer_init(&m); 999545d5ecaSDag-Erling Smørgrav buffer_put_cstring(&m, responses[0]); 1000545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHRESPOND, &m); 1001545d5ecaSDag-Erling Smørgrav 1002545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, 1003545d5ecaSDag-Erling Smørgrav MONITOR_ANS_BSDAUTHRESPOND, &m); 1004545d5ecaSDag-Erling Smørgrav 1005545d5ecaSDag-Erling Smørgrav authok = buffer_get_int(&m); 1006545d5ecaSDag-Erling Smørgrav buffer_free(&m); 1007545d5ecaSDag-Erling Smørgrav 1008545d5ecaSDag-Erling Smørgrav return ((authok == 0) ? -1 : 0); 1009545d5ecaSDag-Erling Smørgrav } 1010545d5ecaSDag-Erling Smørgrav 1011edb557f8SDag-Erling Smørgrav #ifdef SKEY 1012545d5ecaSDag-Erling Smørgrav int 1013545d5ecaSDag-Erling Smørgrav mm_skey_query(void *ctx, char **name, char **infotxt, 1014545d5ecaSDag-Erling Smørgrav u_int *numprompts, char ***prompts, u_int **echo_on) 1015545d5ecaSDag-Erling Smørgrav { 1016545d5ecaSDag-Erling Smørgrav Buffer m; 1017e73e9afaSDag-Erling Smørgrav u_int success; 1018333ee039SDag-Erling Smørgrav char *challenge; 1019545d5ecaSDag-Erling Smørgrav 1020545d5ecaSDag-Erling Smørgrav debug3("%s: entering", __func__); 1021545d5ecaSDag-Erling Smørgrav 1022545d5ecaSDag-Erling Smørgrav buffer_init(&m); 1023545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SKEYQUERY, &m); 1024545d5ecaSDag-Erling Smørgrav 1025545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SKEYQUERY, 1026545d5ecaSDag-Erling Smørgrav &m); 1027e73e9afaSDag-Erling Smørgrav success = buffer_get_int(&m); 1028e73e9afaSDag-Erling Smørgrav if (success == 0) { 1029545d5ecaSDag-Erling Smørgrav debug3("%s: no challenge", __func__); 1030545d5ecaSDag-Erling Smørgrav buffer_free(&m); 1031545d5ecaSDag-Erling Smørgrav return (-1); 1032545d5ecaSDag-Erling Smørgrav } 1033545d5ecaSDag-Erling Smørgrav 1034545d5ecaSDag-Erling Smørgrav /* Get the challenge, and format the response */ 1035545d5ecaSDag-Erling Smørgrav challenge = buffer_get_string(&m, NULL); 1036545d5ecaSDag-Erling Smørgrav buffer_free(&m); 1037545d5ecaSDag-Erling Smørgrav 1038545d5ecaSDag-Erling Smørgrav debug3("%s: received challenge: %s", __func__, challenge); 1039545d5ecaSDag-Erling Smørgrav 1040545d5ecaSDag-Erling Smørgrav mm_chall_setup(name, infotxt, numprompts, prompts, echo_on); 1041545d5ecaSDag-Erling Smørgrav 1042333ee039SDag-Erling Smørgrav xasprintf(*prompts, "%s%s", challenge, SKEY_PROMPT); 1043e4a9863fSDag-Erling Smørgrav free(challenge); 1044545d5ecaSDag-Erling Smørgrav 1045545d5ecaSDag-Erling Smørgrav return (0); 1046545d5ecaSDag-Erling Smørgrav } 1047545d5ecaSDag-Erling Smørgrav 1048545d5ecaSDag-Erling Smørgrav int 1049545d5ecaSDag-Erling Smørgrav mm_skey_respond(void *ctx, u_int numresponses, char **responses) 1050545d5ecaSDag-Erling Smørgrav { 1051545d5ecaSDag-Erling Smørgrav Buffer m; 1052545d5ecaSDag-Erling Smørgrav int authok; 1053545d5ecaSDag-Erling Smørgrav 1054545d5ecaSDag-Erling Smørgrav debug3("%s: entering", __func__); 1055545d5ecaSDag-Erling Smørgrav if (numresponses != 1) 1056545d5ecaSDag-Erling Smørgrav return (-1); 1057545d5ecaSDag-Erling Smørgrav 1058545d5ecaSDag-Erling Smørgrav buffer_init(&m); 1059545d5ecaSDag-Erling Smørgrav buffer_put_cstring(&m, responses[0]); 1060545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SKEYRESPOND, &m); 1061545d5ecaSDag-Erling Smørgrav 1062545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, 1063545d5ecaSDag-Erling Smørgrav MONITOR_ANS_SKEYRESPOND, &m); 1064545d5ecaSDag-Erling Smørgrav 1065545d5ecaSDag-Erling Smørgrav authok = buffer_get_int(&m); 1066545d5ecaSDag-Erling Smørgrav buffer_free(&m); 1067545d5ecaSDag-Erling Smørgrav 1068545d5ecaSDag-Erling Smørgrav return ((authok == 0) ? -1 : 0); 1069545d5ecaSDag-Erling Smørgrav } 107021e764dfSDag-Erling Smørgrav #endif /* SKEY */ 1071545d5ecaSDag-Erling Smørgrav 1072545d5ecaSDag-Erling Smørgrav void 1073545d5ecaSDag-Erling Smørgrav mm_ssh1_session_id(u_char session_id[16]) 1074545d5ecaSDag-Erling Smørgrav { 1075545d5ecaSDag-Erling Smørgrav Buffer m; 1076545d5ecaSDag-Erling Smørgrav int i; 1077545d5ecaSDag-Erling Smørgrav 1078545d5ecaSDag-Erling Smørgrav debug3("%s entering", __func__); 1079545d5ecaSDag-Erling Smørgrav 1080545d5ecaSDag-Erling Smørgrav buffer_init(&m); 1081545d5ecaSDag-Erling Smørgrav for (i = 0; i < 16; i++) 1082545d5ecaSDag-Erling Smørgrav buffer_put_char(&m, session_id[i]); 1083545d5ecaSDag-Erling Smørgrav 1084545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SESSID, &m); 1085545d5ecaSDag-Erling Smørgrav buffer_free(&m); 1086545d5ecaSDag-Erling Smørgrav } 1087545d5ecaSDag-Erling Smørgrav 1088*a0ee8cc6SDag-Erling Smørgrav #ifdef WITH_SSH1 1089545d5ecaSDag-Erling Smørgrav int 1090545d5ecaSDag-Erling Smørgrav mm_auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey) 1091545d5ecaSDag-Erling Smørgrav { 1092545d5ecaSDag-Erling Smørgrav Buffer m; 1093545d5ecaSDag-Erling Smørgrav Key *key; 1094545d5ecaSDag-Erling Smørgrav u_char *blob; 1095545d5ecaSDag-Erling Smørgrav u_int blen; 1096e73e9afaSDag-Erling Smørgrav int allowed = 0, have_forced = 0; 1097545d5ecaSDag-Erling Smørgrav 1098545d5ecaSDag-Erling Smørgrav debug3("%s entering", __func__); 1099545d5ecaSDag-Erling Smørgrav 1100545d5ecaSDag-Erling Smørgrav buffer_init(&m); 1101545d5ecaSDag-Erling Smørgrav buffer_put_bignum2(&m, client_n); 1102545d5ecaSDag-Erling Smørgrav 1103545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSAKEYALLOWED, &m); 1104545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSAKEYALLOWED, &m); 1105545d5ecaSDag-Erling Smørgrav 1106545d5ecaSDag-Erling Smørgrav allowed = buffer_get_int(&m); 1107545d5ecaSDag-Erling Smørgrav 1108e73e9afaSDag-Erling Smørgrav /* fake forced command */ 1109e73e9afaSDag-Erling Smørgrav auth_clear_options(); 1110e73e9afaSDag-Erling Smørgrav have_forced = buffer_get_int(&m); 1111e73e9afaSDag-Erling Smørgrav forced_command = have_forced ? xstrdup("true") : NULL; 1112e73e9afaSDag-Erling Smørgrav 1113545d5ecaSDag-Erling Smørgrav if (allowed && rkey != NULL) { 1114545d5ecaSDag-Erling Smørgrav blob = buffer_get_string(&m, &blen); 1115545d5ecaSDag-Erling Smørgrav if ((key = key_from_blob(blob, blen)) == NULL) 1116545d5ecaSDag-Erling Smørgrav fatal("%s: key_from_blob failed", __func__); 1117545d5ecaSDag-Erling Smørgrav *rkey = key; 1118e4a9863fSDag-Erling Smørgrav free(blob); 1119545d5ecaSDag-Erling Smørgrav } 1120545d5ecaSDag-Erling Smørgrav buffer_free(&m); 1121545d5ecaSDag-Erling Smørgrav 1122545d5ecaSDag-Erling Smørgrav return (allowed); 1123545d5ecaSDag-Erling Smørgrav } 1124545d5ecaSDag-Erling Smørgrav 1125545d5ecaSDag-Erling Smørgrav BIGNUM * 1126545d5ecaSDag-Erling Smørgrav mm_auth_rsa_generate_challenge(Key *key) 1127545d5ecaSDag-Erling Smørgrav { 1128545d5ecaSDag-Erling Smørgrav Buffer m; 1129545d5ecaSDag-Erling Smørgrav BIGNUM *challenge; 1130545d5ecaSDag-Erling Smørgrav u_char *blob; 1131545d5ecaSDag-Erling Smørgrav u_int blen; 1132545d5ecaSDag-Erling Smørgrav 1133545d5ecaSDag-Erling Smørgrav debug3("%s entering", __func__); 1134545d5ecaSDag-Erling Smørgrav 1135545d5ecaSDag-Erling Smørgrav if ((challenge = BN_new()) == NULL) 1136545d5ecaSDag-Erling Smørgrav fatal("%s: BN_new failed", __func__); 1137545d5ecaSDag-Erling Smørgrav 1138545d5ecaSDag-Erling Smørgrav key->type = KEY_RSA; /* XXX cheat for key_to_blob */ 1139545d5ecaSDag-Erling Smørgrav if (key_to_blob(key, &blob, &blen) == 0) 1140545d5ecaSDag-Erling Smørgrav fatal("%s: key_to_blob failed", __func__); 1141545d5ecaSDag-Erling Smørgrav key->type = KEY_RSA1; 1142545d5ecaSDag-Erling Smørgrav 1143545d5ecaSDag-Erling Smørgrav buffer_init(&m); 1144545d5ecaSDag-Erling Smørgrav buffer_put_string(&m, blob, blen); 1145e4a9863fSDag-Erling Smørgrav free(blob); 1146545d5ecaSDag-Erling Smørgrav 1147545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSACHALLENGE, &m); 1148545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSACHALLENGE, &m); 1149545d5ecaSDag-Erling Smørgrav 1150545d5ecaSDag-Erling Smørgrav buffer_get_bignum2(&m, challenge); 1151545d5ecaSDag-Erling Smørgrav buffer_free(&m); 1152545d5ecaSDag-Erling Smørgrav 1153545d5ecaSDag-Erling Smørgrav return (challenge); 1154545d5ecaSDag-Erling Smørgrav } 1155545d5ecaSDag-Erling Smørgrav 1156545d5ecaSDag-Erling Smørgrav int 1157545d5ecaSDag-Erling Smørgrav mm_auth_rsa_verify_response(Key *key, BIGNUM *p, u_char response[16]) 1158545d5ecaSDag-Erling Smørgrav { 1159545d5ecaSDag-Erling Smørgrav Buffer m; 1160545d5ecaSDag-Erling Smørgrav u_char *blob; 1161545d5ecaSDag-Erling Smørgrav u_int blen; 1162545d5ecaSDag-Erling Smørgrav int success = 0; 1163545d5ecaSDag-Erling Smørgrav 1164545d5ecaSDag-Erling Smørgrav debug3("%s entering", __func__); 1165545d5ecaSDag-Erling Smørgrav 1166545d5ecaSDag-Erling Smørgrav key->type = KEY_RSA; /* XXX cheat for key_to_blob */ 1167545d5ecaSDag-Erling Smørgrav if (key_to_blob(key, &blob, &blen) == 0) 1168545d5ecaSDag-Erling Smørgrav fatal("%s: key_to_blob failed", __func__); 1169545d5ecaSDag-Erling Smørgrav key->type = KEY_RSA1; 1170545d5ecaSDag-Erling Smørgrav 1171545d5ecaSDag-Erling Smørgrav buffer_init(&m); 1172545d5ecaSDag-Erling Smørgrav buffer_put_string(&m, blob, blen); 1173545d5ecaSDag-Erling Smørgrav buffer_put_string(&m, response, 16); 1174e4a9863fSDag-Erling Smørgrav free(blob); 1175545d5ecaSDag-Erling Smørgrav 1176545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSARESPONSE, &m); 1177545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSARESPONSE, &m); 1178545d5ecaSDag-Erling Smørgrav 1179545d5ecaSDag-Erling Smørgrav success = buffer_get_int(&m); 1180545d5ecaSDag-Erling Smørgrav buffer_free(&m); 1181545d5ecaSDag-Erling Smørgrav 1182545d5ecaSDag-Erling Smørgrav return (success); 1183545d5ecaSDag-Erling Smørgrav } 1184*a0ee8cc6SDag-Erling Smørgrav #endif 1185f388f5efSDag-Erling Smørgrav 1186aa49c926SDag-Erling Smørgrav #ifdef SSH_AUDIT_EVENTS 1187aa49c926SDag-Erling Smørgrav void 1188aa49c926SDag-Erling Smørgrav mm_audit_event(ssh_audit_event_t event) 1189aa49c926SDag-Erling Smørgrav { 1190aa49c926SDag-Erling Smørgrav Buffer m; 1191aa49c926SDag-Erling Smørgrav 1192aa49c926SDag-Erling Smørgrav debug3("%s entering", __func__); 1193aa49c926SDag-Erling Smørgrav 1194aa49c926SDag-Erling Smørgrav buffer_init(&m); 1195aa49c926SDag-Erling Smørgrav buffer_put_int(&m, event); 1196aa49c926SDag-Erling Smørgrav 1197aa49c926SDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_EVENT, &m); 1198aa49c926SDag-Erling Smørgrav buffer_free(&m); 1199aa49c926SDag-Erling Smørgrav } 1200aa49c926SDag-Erling Smørgrav 1201aa49c926SDag-Erling Smørgrav void 1202aa49c926SDag-Erling Smørgrav mm_audit_run_command(const char *command) 1203aa49c926SDag-Erling Smørgrav { 1204aa49c926SDag-Erling Smørgrav Buffer m; 1205aa49c926SDag-Erling Smørgrav 1206aa49c926SDag-Erling Smørgrav debug3("%s entering command %s", __func__, command); 1207aa49c926SDag-Erling Smørgrav 1208aa49c926SDag-Erling Smørgrav buffer_init(&m); 1209aa49c926SDag-Erling Smørgrav buffer_put_cstring(&m, command); 1210aa49c926SDag-Erling Smørgrav 1211aa49c926SDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, &m); 1212aa49c926SDag-Erling Smørgrav buffer_free(&m); 1213aa49c926SDag-Erling Smørgrav } 1214aa49c926SDag-Erling Smørgrav #endif /* SSH_AUDIT_EVENTS */ 1215aa49c926SDag-Erling Smørgrav 1216cf2b5f3bSDag-Erling Smørgrav #ifdef GSSAPI 1217cf2b5f3bSDag-Erling Smørgrav OM_uint32 121821e764dfSDag-Erling Smørgrav mm_ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID goid) 1219f388f5efSDag-Erling Smørgrav { 1220f388f5efSDag-Erling Smørgrav Buffer m; 1221cf2b5f3bSDag-Erling Smørgrav OM_uint32 major; 1222f388f5efSDag-Erling Smørgrav 1223cf2b5f3bSDag-Erling Smørgrav /* Client doesn't get to see the context */ 1224cf2b5f3bSDag-Erling Smørgrav *ctx = NULL; 1225f388f5efSDag-Erling Smørgrav 1226f388f5efSDag-Erling Smørgrav buffer_init(&m); 122721e764dfSDag-Erling Smørgrav buffer_put_string(&m, goid->elements, goid->length); 1228f388f5efSDag-Erling Smørgrav 1229cf2b5f3bSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSETUP, &m); 1230cf2b5f3bSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSETUP, &m); 1231f388f5efSDag-Erling Smørgrav 1232cf2b5f3bSDag-Erling Smørgrav major = buffer_get_int(&m); 1233cf2b5f3bSDag-Erling Smørgrav 1234f388f5efSDag-Erling Smørgrav buffer_free(&m); 1235cf2b5f3bSDag-Erling Smørgrav return (major); 1236f388f5efSDag-Erling Smørgrav } 1237f388f5efSDag-Erling Smørgrav 1238cf2b5f3bSDag-Erling Smørgrav OM_uint32 1239cf2b5f3bSDag-Erling Smørgrav mm_ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *in, 1240cf2b5f3bSDag-Erling Smørgrav gss_buffer_desc *out, OM_uint32 *flags) 1241f388f5efSDag-Erling Smørgrav { 1242f388f5efSDag-Erling Smørgrav Buffer m; 1243cf2b5f3bSDag-Erling Smørgrav OM_uint32 major; 1244f388f5efSDag-Erling Smørgrav u_int len; 1245f388f5efSDag-Erling Smørgrav 1246cf2b5f3bSDag-Erling Smørgrav buffer_init(&m); 1247cf2b5f3bSDag-Erling Smørgrav buffer_put_string(&m, in->value, in->length); 1248cf2b5f3bSDag-Erling Smørgrav 1249cf2b5f3bSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSTEP, &m); 1250cf2b5f3bSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSTEP, &m); 1251cf2b5f3bSDag-Erling Smørgrav 1252cf2b5f3bSDag-Erling Smørgrav major = buffer_get_int(&m); 1253cf2b5f3bSDag-Erling Smørgrav out->value = buffer_get_string(&m, &len); 1254cf2b5f3bSDag-Erling Smørgrav out->length = len; 1255cf2b5f3bSDag-Erling Smørgrav if (flags) 1256cf2b5f3bSDag-Erling Smørgrav *flags = buffer_get_int(&m); 1257f388f5efSDag-Erling Smørgrav 1258f388f5efSDag-Erling Smørgrav buffer_free(&m); 1259cf2b5f3bSDag-Erling Smørgrav 1260cf2b5f3bSDag-Erling Smørgrav return (major); 1261f388f5efSDag-Erling Smørgrav } 1262cf2b5f3bSDag-Erling Smørgrav 12631ec0d754SDag-Erling Smørgrav OM_uint32 12641ec0d754SDag-Erling Smørgrav mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) 12651ec0d754SDag-Erling Smørgrav { 12661ec0d754SDag-Erling Smørgrav Buffer m; 12671ec0d754SDag-Erling Smørgrav OM_uint32 major; 12681ec0d754SDag-Erling Smørgrav 12691ec0d754SDag-Erling Smørgrav buffer_init(&m); 12701ec0d754SDag-Erling Smørgrav buffer_put_string(&m, gssbuf->value, gssbuf->length); 12711ec0d754SDag-Erling Smørgrav buffer_put_string(&m, gssmic->value, gssmic->length); 12721ec0d754SDag-Erling Smørgrav 12731ec0d754SDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSCHECKMIC, &m); 12741ec0d754SDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSCHECKMIC, 12751ec0d754SDag-Erling Smørgrav &m); 12761ec0d754SDag-Erling Smørgrav 12771ec0d754SDag-Erling Smørgrav major = buffer_get_int(&m); 12781ec0d754SDag-Erling Smørgrav buffer_free(&m); 12791ec0d754SDag-Erling Smørgrav return(major); 12801ec0d754SDag-Erling Smørgrav } 12811ec0d754SDag-Erling Smørgrav 1282cf2b5f3bSDag-Erling Smørgrav int 1283cf2b5f3bSDag-Erling Smørgrav mm_ssh_gssapi_userok(char *user) 1284cf2b5f3bSDag-Erling Smørgrav { 1285cf2b5f3bSDag-Erling Smørgrav Buffer m; 1286cf2b5f3bSDag-Erling Smørgrav int authenticated = 0; 1287cf2b5f3bSDag-Erling Smørgrav 1288cf2b5f3bSDag-Erling Smørgrav buffer_init(&m); 1289cf2b5f3bSDag-Erling Smørgrav 1290cf2b5f3bSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, &m); 1291cf2b5f3bSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUSEROK, 1292cf2b5f3bSDag-Erling Smørgrav &m); 1293cf2b5f3bSDag-Erling Smørgrav 1294cf2b5f3bSDag-Erling Smørgrav authenticated = buffer_get_int(&m); 1295cf2b5f3bSDag-Erling Smørgrav 1296cf2b5f3bSDag-Erling Smørgrav buffer_free(&m); 1297cf2b5f3bSDag-Erling Smørgrav debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not "); 1298cf2b5f3bSDag-Erling Smørgrav return (authenticated); 1299cf2b5f3bSDag-Erling Smørgrav } 1300cf2b5f3bSDag-Erling Smørgrav #endif /* GSSAPI */ 1301cce7d346SDag-Erling Smørgrav 1302