1*bc5531deSDag-Erling Smørgrav /* $OpenBSD: monitor_wrap.c,v 1.84 2015/02/16 22:13:32 djm 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 41a0ee8cc6SDag-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> 45a0ee8cc6SDag-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" 50a0ee8cc6SDag-Erling Smørgrav #ifdef WITH_OPENSSL 51545d5ecaSDag-Erling Smørgrav #include "dh.h" 52a0ee8cc6SDag-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 85*bc5531deSDag-Erling Smørgrav #include "ssherr.h" 86*bc5531deSDag-Erling Smørgrav 87545d5ecaSDag-Erling Smørgrav /* Imports */ 88545d5ecaSDag-Erling Smørgrav extern int compat20; 89545d5ecaSDag-Erling Smørgrav extern z_stream incoming_stream; 90545d5ecaSDag-Erling Smørgrav extern z_stream outgoing_stream; 91545d5ecaSDag-Erling Smørgrav extern struct monitor *pmonitor; 9221e764dfSDag-Erling Smørgrav extern Buffer loginmsg; 93cf2b5f3bSDag-Erling Smørgrav extern ServerOptions options; 94545d5ecaSDag-Erling Smørgrav 95e146993eSDag-Erling Smørgrav void 96e146993eSDag-Erling Smørgrav mm_log_handler(LogLevel level, const char *msg, void *ctx) 97e146993eSDag-Erling Smørgrav { 98e146993eSDag-Erling Smørgrav Buffer log_msg; 99e146993eSDag-Erling Smørgrav struct monitor *mon = (struct monitor *)ctx; 100e146993eSDag-Erling Smørgrav 101e146993eSDag-Erling Smørgrav if (mon->m_log_sendfd == -1) 102e146993eSDag-Erling Smørgrav fatal("%s: no log channel", __func__); 103e146993eSDag-Erling Smørgrav 104e146993eSDag-Erling Smørgrav buffer_init(&log_msg); 105e146993eSDag-Erling Smørgrav /* 106e146993eSDag-Erling Smørgrav * Placeholder for packet length. Will be filled in with the actual 107e146993eSDag-Erling Smørgrav * packet length once the packet has been constucted. This saves 108e146993eSDag-Erling Smørgrav * fragile math. 109e146993eSDag-Erling Smørgrav */ 110e146993eSDag-Erling Smørgrav buffer_put_int(&log_msg, 0); 111e146993eSDag-Erling Smørgrav 112e146993eSDag-Erling Smørgrav buffer_put_int(&log_msg, level); 113e146993eSDag-Erling Smørgrav buffer_put_cstring(&log_msg, msg); 114e146993eSDag-Erling Smørgrav put_u32(buffer_ptr(&log_msg), buffer_len(&log_msg) - 4); 115e146993eSDag-Erling Smørgrav if (atomicio(vwrite, mon->m_log_sendfd, buffer_ptr(&log_msg), 116e146993eSDag-Erling Smørgrav buffer_len(&log_msg)) != buffer_len(&log_msg)) 117e146993eSDag-Erling Smørgrav fatal("%s: write: %s", __func__, strerror(errno)); 118e146993eSDag-Erling Smørgrav buffer_free(&log_msg); 119e146993eSDag-Erling Smørgrav } 120e146993eSDag-Erling Smørgrav 1211ec0d754SDag-Erling Smørgrav int 1221ec0d754SDag-Erling Smørgrav mm_is_monitor(void) 1231ec0d754SDag-Erling Smørgrav { 1241ec0d754SDag-Erling Smørgrav /* 1251ec0d754SDag-Erling Smørgrav * m_pid is only set in the privileged part, and 1261ec0d754SDag-Erling Smørgrav * points to the unprivileged child. 1271ec0d754SDag-Erling Smørgrav */ 1281ec0d754SDag-Erling Smørgrav return (pmonitor && pmonitor->m_pid > 0); 1291ec0d754SDag-Erling Smørgrav } 1301ec0d754SDag-Erling Smørgrav 131545d5ecaSDag-Erling Smørgrav void 13221e764dfSDag-Erling Smørgrav mm_request_send(int sock, enum monitor_reqtype type, Buffer *m) 133545d5ecaSDag-Erling Smørgrav { 134545d5ecaSDag-Erling Smørgrav u_int mlen = buffer_len(m); 135f388f5efSDag-Erling Smørgrav u_char buf[5]; 136545d5ecaSDag-Erling Smørgrav 137545d5ecaSDag-Erling Smørgrav debug3("%s entering: type %d", __func__, type); 138545d5ecaSDag-Erling Smørgrav 139333ee039SDag-Erling Smørgrav put_u32(buf, mlen + 1); 140545d5ecaSDag-Erling Smørgrav buf[4] = (u_char) type; /* 1st byte of payload is mesg-type */ 14121e764dfSDag-Erling Smørgrav if (atomicio(vwrite, sock, buf, sizeof(buf)) != sizeof(buf)) 142d4ecd108SDag-Erling Smørgrav fatal("%s: write: %s", __func__, strerror(errno)); 14321e764dfSDag-Erling Smørgrav if (atomicio(vwrite, sock, buffer_ptr(m), mlen) != mlen) 144d4ecd108SDag-Erling Smørgrav fatal("%s: write: %s", __func__, strerror(errno)); 145545d5ecaSDag-Erling Smørgrav } 146545d5ecaSDag-Erling Smørgrav 147545d5ecaSDag-Erling Smørgrav void 14821e764dfSDag-Erling Smørgrav mm_request_receive(int sock, Buffer *m) 149545d5ecaSDag-Erling Smørgrav { 150545d5ecaSDag-Erling Smørgrav u_char buf[4]; 151545d5ecaSDag-Erling Smørgrav u_int msg_len; 152545d5ecaSDag-Erling Smørgrav 153545d5ecaSDag-Erling Smørgrav debug3("%s entering", __func__); 154545d5ecaSDag-Erling Smørgrav 155d4ecd108SDag-Erling Smørgrav if (atomicio(read, sock, buf, sizeof(buf)) != sizeof(buf)) { 156*bc5531deSDag-Erling Smørgrav if (errno == EPIPE) { 157*bc5531deSDag-Erling Smørgrav error("%s: socket closed", __func__); 1581ec0d754SDag-Erling Smørgrav cleanup_exit(255); 159*bc5531deSDag-Erling Smørgrav } 160d4ecd108SDag-Erling Smørgrav fatal("%s: read: %s", __func__, strerror(errno)); 161545d5ecaSDag-Erling Smørgrav } 162333ee039SDag-Erling Smørgrav msg_len = get_u32(buf); 163545d5ecaSDag-Erling Smørgrav if (msg_len > 256 * 1024) 164545d5ecaSDag-Erling Smørgrav fatal("%s: read: bad msg_len %d", __func__, msg_len); 165545d5ecaSDag-Erling Smørgrav buffer_clear(m); 166545d5ecaSDag-Erling Smørgrav buffer_append_space(m, msg_len); 167d4ecd108SDag-Erling Smørgrav if (atomicio(read, sock, buffer_ptr(m), msg_len) != msg_len) 168d4ecd108SDag-Erling Smørgrav fatal("%s: read: %s", __func__, strerror(errno)); 169545d5ecaSDag-Erling Smørgrav } 170545d5ecaSDag-Erling Smørgrav 171545d5ecaSDag-Erling Smørgrav void 17221e764dfSDag-Erling Smørgrav mm_request_receive_expect(int sock, enum monitor_reqtype type, Buffer *m) 173545d5ecaSDag-Erling Smørgrav { 174545d5ecaSDag-Erling Smørgrav u_char rtype; 175545d5ecaSDag-Erling Smørgrav 176545d5ecaSDag-Erling Smørgrav debug3("%s entering: type %d", __func__, type); 177545d5ecaSDag-Erling Smørgrav 17821e764dfSDag-Erling Smørgrav mm_request_receive(sock, m); 179545d5ecaSDag-Erling Smørgrav rtype = buffer_get_char(m); 180545d5ecaSDag-Erling Smørgrav if (rtype != type) 181545d5ecaSDag-Erling Smørgrav fatal("%s: read: rtype %d != type %d", __func__, 182545d5ecaSDag-Erling Smørgrav rtype, type); 183545d5ecaSDag-Erling Smørgrav } 184545d5ecaSDag-Erling Smørgrav 185a0ee8cc6SDag-Erling Smørgrav #ifdef WITH_OPENSSL 186545d5ecaSDag-Erling Smørgrav DH * 187545d5ecaSDag-Erling Smørgrav mm_choose_dh(int min, int nbits, int max) 188545d5ecaSDag-Erling Smørgrav { 189545d5ecaSDag-Erling Smørgrav BIGNUM *p, *g; 190545d5ecaSDag-Erling Smørgrav int success = 0; 191545d5ecaSDag-Erling Smørgrav Buffer m; 192545d5ecaSDag-Erling Smørgrav 193545d5ecaSDag-Erling Smørgrav buffer_init(&m); 194545d5ecaSDag-Erling Smørgrav buffer_put_int(&m, min); 195545d5ecaSDag-Erling Smørgrav buffer_put_int(&m, nbits); 196545d5ecaSDag-Erling Smørgrav buffer_put_int(&m, max); 197545d5ecaSDag-Erling Smørgrav 198545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_MODULI, &m); 199545d5ecaSDag-Erling Smørgrav 200545d5ecaSDag-Erling Smørgrav debug3("%s: waiting for MONITOR_ANS_MODULI", __func__); 201545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_MODULI, &m); 202545d5ecaSDag-Erling Smørgrav 203545d5ecaSDag-Erling Smørgrav success = buffer_get_char(&m); 204545d5ecaSDag-Erling Smørgrav if (success == 0) 205545d5ecaSDag-Erling Smørgrav fatal("%s: MONITOR_ANS_MODULI failed", __func__); 206545d5ecaSDag-Erling Smørgrav 207545d5ecaSDag-Erling Smørgrav if ((p = BN_new()) == NULL) 208545d5ecaSDag-Erling Smørgrav fatal("%s: BN_new failed", __func__); 209545d5ecaSDag-Erling Smørgrav if ((g = BN_new()) == NULL) 210545d5ecaSDag-Erling Smørgrav fatal("%s: BN_new failed", __func__); 211545d5ecaSDag-Erling Smørgrav buffer_get_bignum2(&m, p); 212545d5ecaSDag-Erling Smørgrav buffer_get_bignum2(&m, g); 213545d5ecaSDag-Erling Smørgrav 214545d5ecaSDag-Erling Smørgrav debug3("%s: remaining %d", __func__, buffer_len(&m)); 215545d5ecaSDag-Erling Smørgrav buffer_free(&m); 216545d5ecaSDag-Erling Smørgrav 217545d5ecaSDag-Erling Smørgrav return (dh_new_group(g, p)); 218545d5ecaSDag-Erling Smørgrav } 219a0ee8cc6SDag-Erling Smørgrav #endif 220545d5ecaSDag-Erling Smørgrav 221545d5ecaSDag-Erling Smørgrav int 222*bc5531deSDag-Erling Smørgrav mm_key_sign(Key *key, u_char **sigp, u_int *lenp, 223*bc5531deSDag-Erling Smørgrav const u_char *data, u_int datalen) 224545d5ecaSDag-Erling Smørgrav { 225*bc5531deSDag-Erling Smørgrav struct kex *kex = *pmonitor->m_pkex; 226545d5ecaSDag-Erling Smørgrav Buffer m; 227545d5ecaSDag-Erling Smørgrav 228545d5ecaSDag-Erling Smørgrav debug3("%s entering", __func__); 229545d5ecaSDag-Erling Smørgrav 230545d5ecaSDag-Erling Smørgrav buffer_init(&m); 231*bc5531deSDag-Erling Smørgrav buffer_put_int(&m, kex->host_key_index(key, 0, active_state)); 232545d5ecaSDag-Erling Smørgrav buffer_put_string(&m, data, datalen); 233545d5ecaSDag-Erling Smørgrav 234545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SIGN, &m); 235545d5ecaSDag-Erling Smørgrav 236545d5ecaSDag-Erling Smørgrav debug3("%s: waiting for MONITOR_ANS_SIGN", __func__); 237545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SIGN, &m); 238545d5ecaSDag-Erling Smørgrav *sigp = buffer_get_string(&m, lenp); 239545d5ecaSDag-Erling Smørgrav buffer_free(&m); 240545d5ecaSDag-Erling Smørgrav 241545d5ecaSDag-Erling Smørgrav return (0); 242545d5ecaSDag-Erling Smørgrav } 243545d5ecaSDag-Erling Smørgrav 244545d5ecaSDag-Erling Smørgrav struct passwd * 24521e764dfSDag-Erling Smørgrav mm_getpwnamallow(const char *username) 246545d5ecaSDag-Erling Smørgrav { 247545d5ecaSDag-Erling Smørgrav Buffer m; 248545d5ecaSDag-Erling Smørgrav struct passwd *pw; 249e146993eSDag-Erling Smørgrav u_int len, i; 250d4af9e69SDag-Erling Smørgrav ServerOptions *newopts; 251545d5ecaSDag-Erling Smørgrav 252545d5ecaSDag-Erling Smørgrav debug3("%s entering", __func__); 253545d5ecaSDag-Erling Smørgrav 254545d5ecaSDag-Erling Smørgrav buffer_init(&m); 25521e764dfSDag-Erling Smørgrav buffer_put_cstring(&m, username); 256545d5ecaSDag-Erling Smørgrav 257545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PWNAM, &m); 258545d5ecaSDag-Erling Smørgrav 259545d5ecaSDag-Erling Smørgrav debug3("%s: waiting for MONITOR_ANS_PWNAM", __func__); 260545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PWNAM, &m); 261545d5ecaSDag-Erling Smørgrav 262545d5ecaSDag-Erling Smørgrav if (buffer_get_char(&m) == 0) { 263d4af9e69SDag-Erling Smørgrav pw = NULL; 264d4af9e69SDag-Erling Smørgrav goto out; 265545d5ecaSDag-Erling Smørgrav } 266d4af9e69SDag-Erling Smørgrav pw = buffer_get_string(&m, &len); 267d4af9e69SDag-Erling Smørgrav if (len != sizeof(struct passwd)) 268545d5ecaSDag-Erling Smørgrav fatal("%s: struct passwd size mismatch", __func__); 269545d5ecaSDag-Erling Smørgrav pw->pw_name = buffer_get_string(&m, NULL); 270545d5ecaSDag-Erling Smørgrav pw->pw_passwd = buffer_get_string(&m, NULL); 271e4a9863fSDag-Erling Smørgrav #ifdef HAVE_STRUCT_PASSWD_PW_GECOS 272545d5ecaSDag-Erling Smørgrav pw->pw_gecos = buffer_get_string(&m, NULL); 273e4a9863fSDag-Erling Smørgrav #endif 274e4a9863fSDag-Erling Smørgrav #ifdef HAVE_STRUCT_PASSWD_PW_CLASS 275545d5ecaSDag-Erling Smørgrav pw->pw_class = buffer_get_string(&m, NULL); 27683d2307dSDag-Erling Smørgrav #endif 277545d5ecaSDag-Erling Smørgrav pw->pw_dir = buffer_get_string(&m, NULL); 278545d5ecaSDag-Erling Smørgrav pw->pw_shell = buffer_get_string(&m, NULL); 279d4af9e69SDag-Erling Smørgrav 280d4af9e69SDag-Erling Smørgrav out: 281d4af9e69SDag-Erling Smørgrav /* copy options block as a Match directive may have changed some */ 282d4af9e69SDag-Erling Smørgrav newopts = buffer_get_string(&m, &len); 283d4af9e69SDag-Erling Smørgrav if (len != sizeof(*newopts)) 284d4af9e69SDag-Erling Smørgrav fatal("%s: option block size mismatch", __func__); 285e146993eSDag-Erling Smørgrav 286e146993eSDag-Erling Smørgrav #define M_CP_STROPT(x) do { \ 287e146993eSDag-Erling Smørgrav if (newopts->x != NULL) \ 288e146993eSDag-Erling Smørgrav newopts->x = buffer_get_string(&m, NULL); \ 289e146993eSDag-Erling Smørgrav } while (0) 290e146993eSDag-Erling Smørgrav #define M_CP_STRARRAYOPT(x, nx) do { \ 291e146993eSDag-Erling Smørgrav for (i = 0; i < newopts->nx; i++) \ 292e146993eSDag-Erling Smørgrav newopts->x[i] = buffer_get_string(&m, NULL); \ 293e146993eSDag-Erling Smørgrav } while (0) 294e146993eSDag-Erling Smørgrav /* See comment in servconf.h */ 295e146993eSDag-Erling Smørgrav COPY_MATCH_STRING_OPTS(); 296e146993eSDag-Erling Smørgrav #undef M_CP_STROPT 297e146993eSDag-Erling Smørgrav #undef M_CP_STRARRAYOPT 298e146993eSDag-Erling Smørgrav 299d4af9e69SDag-Erling Smørgrav copy_set_server_options(&options, newopts, 1); 300e4a9863fSDag-Erling Smørgrav free(newopts); 301d4af9e69SDag-Erling Smørgrav 302545d5ecaSDag-Erling Smørgrav buffer_free(&m); 303545d5ecaSDag-Erling Smørgrav 304545d5ecaSDag-Erling Smørgrav return (pw); 305545d5ecaSDag-Erling Smørgrav } 306545d5ecaSDag-Erling Smørgrav 3071ec0d754SDag-Erling Smørgrav char * 3081ec0d754SDag-Erling Smørgrav mm_auth2_read_banner(void) 309545d5ecaSDag-Erling Smørgrav { 310545d5ecaSDag-Erling Smørgrav Buffer m; 311545d5ecaSDag-Erling Smørgrav char *banner; 312545d5ecaSDag-Erling Smørgrav 313545d5ecaSDag-Erling Smørgrav debug3("%s entering", __func__); 314545d5ecaSDag-Erling Smørgrav 315545d5ecaSDag-Erling Smørgrav buffer_init(&m); 316545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTH2_READ_BANNER, &m); 317545d5ecaSDag-Erling Smørgrav buffer_clear(&m); 318545d5ecaSDag-Erling Smørgrav 3191ec0d754SDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, 3201ec0d754SDag-Erling Smørgrav MONITOR_ANS_AUTH2_READ_BANNER, &m); 321545d5ecaSDag-Erling Smørgrav banner = buffer_get_string(&m, NULL); 322545d5ecaSDag-Erling Smørgrav buffer_free(&m); 323545d5ecaSDag-Erling Smørgrav 3241ec0d754SDag-Erling Smørgrav /* treat empty banner as missing banner */ 3251ec0d754SDag-Erling Smørgrav if (strlen(banner) == 0) { 326e4a9863fSDag-Erling Smørgrav free(banner); 3271ec0d754SDag-Erling Smørgrav banner = NULL; 3281ec0d754SDag-Erling Smørgrav } 329545d5ecaSDag-Erling Smørgrav return (banner); 330545d5ecaSDag-Erling Smørgrav } 331545d5ecaSDag-Erling Smørgrav 332545d5ecaSDag-Erling Smørgrav /* Inform the privileged process about service and style */ 333545d5ecaSDag-Erling Smørgrav 334545d5ecaSDag-Erling Smørgrav void 335545d5ecaSDag-Erling Smørgrav mm_inform_authserv(char *service, char *style) 336545d5ecaSDag-Erling Smørgrav { 337545d5ecaSDag-Erling Smørgrav Buffer m; 338545d5ecaSDag-Erling Smørgrav 339545d5ecaSDag-Erling Smørgrav debug3("%s entering", __func__); 340545d5ecaSDag-Erling Smørgrav 341545d5ecaSDag-Erling Smørgrav buffer_init(&m); 342545d5ecaSDag-Erling Smørgrav buffer_put_cstring(&m, service); 343545d5ecaSDag-Erling Smørgrav buffer_put_cstring(&m, style ? style : ""); 344545d5ecaSDag-Erling Smørgrav 345545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHSERV, &m); 346545d5ecaSDag-Erling Smørgrav 347545d5ecaSDag-Erling Smørgrav buffer_free(&m); 348545d5ecaSDag-Erling Smørgrav } 349545d5ecaSDag-Erling Smørgrav 350545d5ecaSDag-Erling Smørgrav /* Do the password authentication */ 351545d5ecaSDag-Erling Smørgrav int 352545d5ecaSDag-Erling Smørgrav mm_auth_password(Authctxt *authctxt, char *password) 353545d5ecaSDag-Erling Smørgrav { 354545d5ecaSDag-Erling Smørgrav Buffer m; 355545d5ecaSDag-Erling Smørgrav int authenticated = 0; 356545d5ecaSDag-Erling Smørgrav 357545d5ecaSDag-Erling Smørgrav debug3("%s entering", __func__); 358545d5ecaSDag-Erling Smørgrav 359545d5ecaSDag-Erling Smørgrav buffer_init(&m); 360545d5ecaSDag-Erling Smørgrav buffer_put_cstring(&m, password); 361545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHPASSWORD, &m); 362545d5ecaSDag-Erling Smørgrav 363545d5ecaSDag-Erling Smørgrav debug3("%s: waiting for MONITOR_ANS_AUTHPASSWORD", __func__); 364545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUTHPASSWORD, &m); 365545d5ecaSDag-Erling Smørgrav 366545d5ecaSDag-Erling Smørgrav authenticated = buffer_get_int(&m); 367545d5ecaSDag-Erling Smørgrav 368545d5ecaSDag-Erling Smørgrav buffer_free(&m); 369545d5ecaSDag-Erling Smørgrav 370545d5ecaSDag-Erling Smørgrav debug3("%s: user %sauthenticated", 371545d5ecaSDag-Erling Smørgrav __func__, authenticated ? "" : "not "); 372545d5ecaSDag-Erling Smørgrav return (authenticated); 373545d5ecaSDag-Erling Smørgrav } 374545d5ecaSDag-Erling Smørgrav 375545d5ecaSDag-Erling Smørgrav int 376545d5ecaSDag-Erling Smørgrav mm_user_key_allowed(struct passwd *pw, Key *key) 377545d5ecaSDag-Erling Smørgrav { 378545d5ecaSDag-Erling Smørgrav return (mm_key_allowed(MM_USERKEY, NULL, NULL, key)); 379545d5ecaSDag-Erling Smørgrav } 380545d5ecaSDag-Erling Smørgrav 381545d5ecaSDag-Erling Smørgrav int 382545d5ecaSDag-Erling Smørgrav mm_hostbased_key_allowed(struct passwd *pw, char *user, char *host, 383545d5ecaSDag-Erling Smørgrav Key *key) 384545d5ecaSDag-Erling Smørgrav { 385545d5ecaSDag-Erling Smørgrav return (mm_key_allowed(MM_HOSTKEY, user, host, key)); 386545d5ecaSDag-Erling Smørgrav } 387545d5ecaSDag-Erling Smørgrav 388545d5ecaSDag-Erling Smørgrav int 389545d5ecaSDag-Erling Smørgrav mm_auth_rhosts_rsa_key_allowed(struct passwd *pw, char *user, 390545d5ecaSDag-Erling Smørgrav char *host, Key *key) 391545d5ecaSDag-Erling Smørgrav { 392545d5ecaSDag-Erling Smørgrav int ret; 393545d5ecaSDag-Erling Smørgrav 394545d5ecaSDag-Erling Smørgrav key->type = KEY_RSA; /* XXX hack for key_to_blob */ 395545d5ecaSDag-Erling Smørgrav ret = mm_key_allowed(MM_RSAHOSTKEY, user, host, key); 396545d5ecaSDag-Erling Smørgrav key->type = KEY_RSA1; 397545d5ecaSDag-Erling Smørgrav return (ret); 398545d5ecaSDag-Erling Smørgrav } 399545d5ecaSDag-Erling Smørgrav 400545d5ecaSDag-Erling Smørgrav int 401545d5ecaSDag-Erling Smørgrav mm_key_allowed(enum mm_keytype type, char *user, char *host, Key *key) 402545d5ecaSDag-Erling Smørgrav { 403545d5ecaSDag-Erling Smørgrav Buffer m; 404545d5ecaSDag-Erling Smørgrav u_char *blob; 405545d5ecaSDag-Erling Smørgrav u_int len; 406e73e9afaSDag-Erling Smørgrav int allowed = 0, have_forced = 0; 407545d5ecaSDag-Erling Smørgrav 408545d5ecaSDag-Erling Smørgrav debug3("%s entering", __func__); 409545d5ecaSDag-Erling Smørgrav 410545d5ecaSDag-Erling Smørgrav /* Convert the key to a blob and the pass it over */ 411545d5ecaSDag-Erling Smørgrav if (!key_to_blob(key, &blob, &len)) 412545d5ecaSDag-Erling Smørgrav return (0); 413545d5ecaSDag-Erling Smørgrav 414545d5ecaSDag-Erling Smørgrav buffer_init(&m); 415545d5ecaSDag-Erling Smørgrav buffer_put_int(&m, type); 416545d5ecaSDag-Erling Smørgrav buffer_put_cstring(&m, user ? user : ""); 417545d5ecaSDag-Erling Smørgrav buffer_put_cstring(&m, host ? host : ""); 418545d5ecaSDag-Erling Smørgrav buffer_put_string(&m, blob, len); 419e4a9863fSDag-Erling Smørgrav free(blob); 420545d5ecaSDag-Erling Smørgrav 421545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYALLOWED, &m); 422545d5ecaSDag-Erling Smørgrav 423545d5ecaSDag-Erling Smørgrav debug3("%s: waiting for MONITOR_ANS_KEYALLOWED", __func__); 424545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYALLOWED, &m); 425545d5ecaSDag-Erling Smørgrav 426545d5ecaSDag-Erling Smørgrav allowed = buffer_get_int(&m); 427545d5ecaSDag-Erling Smørgrav 428e73e9afaSDag-Erling Smørgrav /* fake forced command */ 429e73e9afaSDag-Erling Smørgrav auth_clear_options(); 430e73e9afaSDag-Erling Smørgrav have_forced = buffer_get_int(&m); 431e73e9afaSDag-Erling Smørgrav forced_command = have_forced ? xstrdup("true") : NULL; 432e73e9afaSDag-Erling Smørgrav 433545d5ecaSDag-Erling Smørgrav buffer_free(&m); 434545d5ecaSDag-Erling Smørgrav 435545d5ecaSDag-Erling Smørgrav return (allowed); 436545d5ecaSDag-Erling Smørgrav } 437545d5ecaSDag-Erling Smørgrav 438545d5ecaSDag-Erling Smørgrav /* 439545d5ecaSDag-Erling Smørgrav * This key verify needs to send the key type along, because the 440545d5ecaSDag-Erling Smørgrav * privileged parent makes the decision if the key is allowed 441545d5ecaSDag-Erling Smørgrav * for authentication. 442545d5ecaSDag-Erling Smørgrav */ 443545d5ecaSDag-Erling Smørgrav 444545d5ecaSDag-Erling Smørgrav int 445545d5ecaSDag-Erling Smørgrav mm_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen) 446545d5ecaSDag-Erling Smørgrav { 447545d5ecaSDag-Erling Smørgrav Buffer m; 448545d5ecaSDag-Erling Smørgrav u_char *blob; 449545d5ecaSDag-Erling Smørgrav u_int len; 450545d5ecaSDag-Erling Smørgrav int verified = 0; 451545d5ecaSDag-Erling Smørgrav 452545d5ecaSDag-Erling Smørgrav debug3("%s entering", __func__); 453545d5ecaSDag-Erling Smørgrav 454545d5ecaSDag-Erling Smørgrav /* Convert the key to a blob and the pass it over */ 455545d5ecaSDag-Erling Smørgrav if (!key_to_blob(key, &blob, &len)) 456545d5ecaSDag-Erling Smørgrav return (0); 457545d5ecaSDag-Erling Smørgrav 458545d5ecaSDag-Erling Smørgrav buffer_init(&m); 459545d5ecaSDag-Erling Smørgrav buffer_put_string(&m, blob, len); 460545d5ecaSDag-Erling Smørgrav buffer_put_string(&m, sig, siglen); 461545d5ecaSDag-Erling Smørgrav buffer_put_string(&m, data, datalen); 462e4a9863fSDag-Erling Smørgrav free(blob); 463545d5ecaSDag-Erling Smørgrav 464545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYVERIFY, &m); 465545d5ecaSDag-Erling Smørgrav 466545d5ecaSDag-Erling Smørgrav debug3("%s: waiting for MONITOR_ANS_KEYVERIFY", __func__); 467545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYVERIFY, &m); 468545d5ecaSDag-Erling Smørgrav 469545d5ecaSDag-Erling Smørgrav verified = buffer_get_int(&m); 470545d5ecaSDag-Erling Smørgrav 471545d5ecaSDag-Erling Smørgrav buffer_free(&m); 472545d5ecaSDag-Erling Smørgrav 473545d5ecaSDag-Erling Smørgrav return (verified); 474545d5ecaSDag-Erling Smørgrav } 475545d5ecaSDag-Erling Smørgrav 476545d5ecaSDag-Erling Smørgrav void 47721e764dfSDag-Erling Smørgrav mm_send_keystate(struct monitor *monitor) 478545d5ecaSDag-Erling Smørgrav { 479*bc5531deSDag-Erling Smørgrav struct ssh *ssh = active_state; /* XXX */ 480*bc5531deSDag-Erling Smørgrav struct sshbuf *m; 481*bc5531deSDag-Erling Smørgrav int r; 482545d5ecaSDag-Erling Smørgrav 483*bc5531deSDag-Erling Smørgrav if ((m = sshbuf_new()) == NULL) 484*bc5531deSDag-Erling Smørgrav fatal("%s: sshbuf_new failed", __func__); 485*bc5531deSDag-Erling Smørgrav if ((r = ssh_packet_get_state(ssh, m)) != 0) 486*bc5531deSDag-Erling Smørgrav fatal("%s: get_state failed: %s", 487*bc5531deSDag-Erling Smørgrav __func__, ssh_err(r)); 488*bc5531deSDag-Erling Smørgrav mm_request_send(monitor->m_recvfd, MONITOR_REQ_KEYEXPORT, m); 489545d5ecaSDag-Erling Smørgrav debug3("%s: Finished sending state", __func__); 490*bc5531deSDag-Erling Smørgrav sshbuf_free(m); 491545d5ecaSDag-Erling Smørgrav } 492545d5ecaSDag-Erling Smørgrav 493545d5ecaSDag-Erling Smørgrav int 494333ee039SDag-Erling Smørgrav mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen) 495545d5ecaSDag-Erling Smørgrav { 496545d5ecaSDag-Erling Smørgrav Buffer m; 49721e764dfSDag-Erling Smørgrav char *p, *msg; 498d4af9e69SDag-Erling Smørgrav int success = 0, tmp1 = -1, tmp2 = -1; 499d4af9e69SDag-Erling Smørgrav 500d4af9e69SDag-Erling Smørgrav /* Kludge: ensure there are fds free to receive the pty/tty */ 501d4af9e69SDag-Erling Smørgrav if ((tmp1 = dup(pmonitor->m_recvfd)) == -1 || 502d4af9e69SDag-Erling Smørgrav (tmp2 = dup(pmonitor->m_recvfd)) == -1) { 503d4af9e69SDag-Erling Smørgrav error("%s: cannot allocate fds for pty", __func__); 504d4af9e69SDag-Erling Smørgrav if (tmp1 > 0) 505d4af9e69SDag-Erling Smørgrav close(tmp1); 506d4af9e69SDag-Erling Smørgrav if (tmp2 > 0) 507d4af9e69SDag-Erling Smørgrav close(tmp2); 508d4af9e69SDag-Erling Smørgrav return 0; 509d4af9e69SDag-Erling Smørgrav } 510d4af9e69SDag-Erling Smørgrav close(tmp1); 511d4af9e69SDag-Erling Smørgrav close(tmp2); 512545d5ecaSDag-Erling Smørgrav 513545d5ecaSDag-Erling Smørgrav buffer_init(&m); 514545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTY, &m); 515545d5ecaSDag-Erling Smørgrav 516545d5ecaSDag-Erling Smørgrav debug3("%s: waiting for MONITOR_ANS_PTY", __func__); 517545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PTY, &m); 518545d5ecaSDag-Erling Smørgrav 519545d5ecaSDag-Erling Smørgrav success = buffer_get_int(&m); 520545d5ecaSDag-Erling Smørgrav if (success == 0) { 521545d5ecaSDag-Erling Smørgrav debug3("%s: pty alloc failed", __func__); 522545d5ecaSDag-Erling Smørgrav buffer_free(&m); 523545d5ecaSDag-Erling Smørgrav return (0); 524545d5ecaSDag-Erling Smørgrav } 525545d5ecaSDag-Erling Smørgrav p = buffer_get_string(&m, NULL); 52621e764dfSDag-Erling Smørgrav msg = buffer_get_string(&m, NULL); 527545d5ecaSDag-Erling Smørgrav buffer_free(&m); 528545d5ecaSDag-Erling Smørgrav 529545d5ecaSDag-Erling Smørgrav strlcpy(namebuf, p, namebuflen); /* Possible truncation */ 530e4a9863fSDag-Erling Smørgrav free(p); 531545d5ecaSDag-Erling Smørgrav 53221e764dfSDag-Erling Smørgrav buffer_append(&loginmsg, msg, strlen(msg)); 533e4a9863fSDag-Erling Smørgrav free(msg); 53421e764dfSDag-Erling Smørgrav 535d4af9e69SDag-Erling Smørgrav if ((*ptyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1 || 536d4af9e69SDag-Erling Smørgrav (*ttyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1) 537d4af9e69SDag-Erling Smørgrav fatal("%s: receive fds failed", __func__); 538545d5ecaSDag-Erling Smørgrav 539545d5ecaSDag-Erling Smørgrav /* Success */ 540545d5ecaSDag-Erling Smørgrav return (1); 541545d5ecaSDag-Erling Smørgrav } 542545d5ecaSDag-Erling Smørgrav 543545d5ecaSDag-Erling Smørgrav void 5441ec0d754SDag-Erling Smørgrav mm_session_pty_cleanup2(Session *s) 545545d5ecaSDag-Erling Smørgrav { 546545d5ecaSDag-Erling Smørgrav Buffer m; 547545d5ecaSDag-Erling Smørgrav 548545d5ecaSDag-Erling Smørgrav if (s->ttyfd == -1) 549545d5ecaSDag-Erling Smørgrav return; 550545d5ecaSDag-Erling Smørgrav buffer_init(&m); 551545d5ecaSDag-Erling Smørgrav buffer_put_cstring(&m, s->tty); 552545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTYCLEANUP, &m); 553545d5ecaSDag-Erling Smørgrav buffer_free(&m); 554545d5ecaSDag-Erling Smørgrav 555545d5ecaSDag-Erling Smørgrav /* closed dup'ed master */ 556d4af9e69SDag-Erling Smørgrav if (s->ptymaster != -1 && close(s->ptymaster) < 0) 557d4af9e69SDag-Erling Smørgrav error("close(s->ptymaster/%d): %s", 558d4af9e69SDag-Erling Smørgrav s->ptymaster, strerror(errno)); 559545d5ecaSDag-Erling Smørgrav 560545d5ecaSDag-Erling Smørgrav /* unlink pty from session */ 561545d5ecaSDag-Erling Smørgrav s->ttyfd = -1; 562545d5ecaSDag-Erling Smørgrav } 563545d5ecaSDag-Erling Smørgrav 56483d2307dSDag-Erling Smørgrav #ifdef USE_PAM 56583d2307dSDag-Erling Smørgrav void 5665962c0e9SDag-Erling Smørgrav mm_start_pam(Authctxt *authctxt) 56783d2307dSDag-Erling Smørgrav { 56883d2307dSDag-Erling Smørgrav Buffer m; 56983d2307dSDag-Erling Smørgrav 57083d2307dSDag-Erling Smørgrav debug3("%s entering", __func__); 571cf2b5f3bSDag-Erling Smørgrav if (!options.use_pam) 572cf2b5f3bSDag-Erling Smørgrav fatal("UsePAM=no, but ended up in %s anyway", __func__); 57383d2307dSDag-Erling Smørgrav 57483d2307dSDag-Erling Smørgrav buffer_init(&m); 57583d2307dSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_START, &m); 57683d2307dSDag-Erling Smørgrav 57783d2307dSDag-Erling Smørgrav buffer_free(&m); 57883d2307dSDag-Erling Smørgrav } 579382d19eeSDag-Erling Smørgrav 580cf2b5f3bSDag-Erling Smørgrav u_int 581cf2b5f3bSDag-Erling Smørgrav mm_do_pam_account(void) 582cf2b5f3bSDag-Erling Smørgrav { 583cf2b5f3bSDag-Erling Smørgrav Buffer m; 584cf2b5f3bSDag-Erling Smørgrav u_int ret; 585aa49c926SDag-Erling Smørgrav char *msg; 586cf2b5f3bSDag-Erling Smørgrav 587cf2b5f3bSDag-Erling Smørgrav debug3("%s entering", __func__); 588cf2b5f3bSDag-Erling Smørgrav if (!options.use_pam) 589cf2b5f3bSDag-Erling Smørgrav fatal("UsePAM=no, but ended up in %s anyway", __func__); 590cf2b5f3bSDag-Erling Smørgrav 591cf2b5f3bSDag-Erling Smørgrav buffer_init(&m); 592cf2b5f3bSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_ACCOUNT, &m); 593cf2b5f3bSDag-Erling Smørgrav 594cf2b5f3bSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, 595cf2b5f3bSDag-Erling Smørgrav MONITOR_ANS_PAM_ACCOUNT, &m); 596cf2b5f3bSDag-Erling Smørgrav ret = buffer_get_int(&m); 597aa49c926SDag-Erling Smørgrav msg = buffer_get_string(&m, NULL); 598aa49c926SDag-Erling Smørgrav buffer_append(&loginmsg, msg, strlen(msg)); 599e4a9863fSDag-Erling Smørgrav free(msg); 600cf2b5f3bSDag-Erling Smørgrav 601cf2b5f3bSDag-Erling Smørgrav buffer_free(&m); 602cf2b5f3bSDag-Erling Smørgrav 603cf2b5f3bSDag-Erling Smørgrav debug3("%s returning %d", __func__, ret); 604cf2b5f3bSDag-Erling Smørgrav 605cf2b5f3bSDag-Erling Smørgrav return (ret); 606cf2b5f3bSDag-Erling Smørgrav } 607cf2b5f3bSDag-Erling Smørgrav 608382d19eeSDag-Erling Smørgrav void * 609cf2b5f3bSDag-Erling Smørgrav mm_sshpam_init_ctx(Authctxt *authctxt) 610382d19eeSDag-Erling Smørgrav { 611382d19eeSDag-Erling Smørgrav Buffer m; 612382d19eeSDag-Erling Smørgrav int success; 613382d19eeSDag-Erling Smørgrav 614382d19eeSDag-Erling Smørgrav debug3("%s", __func__); 615382d19eeSDag-Erling Smørgrav buffer_init(&m); 616382d19eeSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_INIT_CTX, &m); 617382d19eeSDag-Erling Smørgrav debug3("%s: waiting for MONITOR_ANS_PAM_INIT_CTX", __func__); 618382d19eeSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_INIT_CTX, &m); 619382d19eeSDag-Erling Smørgrav success = buffer_get_int(&m); 620382d19eeSDag-Erling Smørgrav if (success == 0) { 621382d19eeSDag-Erling Smørgrav debug3("%s: pam_init_ctx failed", __func__); 622382d19eeSDag-Erling Smørgrav buffer_free(&m); 623382d19eeSDag-Erling Smørgrav return (NULL); 624382d19eeSDag-Erling Smørgrav } 625382d19eeSDag-Erling Smørgrav buffer_free(&m); 626382d19eeSDag-Erling Smørgrav return (authctxt); 627382d19eeSDag-Erling Smørgrav } 628382d19eeSDag-Erling Smørgrav 629382d19eeSDag-Erling Smørgrav int 630cf2b5f3bSDag-Erling Smørgrav mm_sshpam_query(void *ctx, char **name, char **info, 631382d19eeSDag-Erling Smørgrav u_int *num, char ***prompts, u_int **echo_on) 632382d19eeSDag-Erling Smørgrav { 633382d19eeSDag-Erling Smørgrav Buffer m; 634d4ecd108SDag-Erling Smørgrav u_int i; 635d4ecd108SDag-Erling Smørgrav int ret; 636382d19eeSDag-Erling Smørgrav 637382d19eeSDag-Erling Smørgrav debug3("%s", __func__); 638382d19eeSDag-Erling Smørgrav buffer_init(&m); 639382d19eeSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_QUERY, &m); 640382d19eeSDag-Erling Smørgrav debug3("%s: waiting for MONITOR_ANS_PAM_QUERY", __func__); 641382d19eeSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_QUERY, &m); 642382d19eeSDag-Erling Smørgrav ret = buffer_get_int(&m); 643382d19eeSDag-Erling Smørgrav debug3("%s: pam_query returned %d", __func__, ret); 644382d19eeSDag-Erling Smørgrav *name = buffer_get_string(&m, NULL); 645382d19eeSDag-Erling Smørgrav *info = buffer_get_string(&m, NULL); 646382d19eeSDag-Erling Smørgrav *num = buffer_get_int(&m); 647333ee039SDag-Erling Smørgrav if (*num > PAM_MAX_NUM_MSG) 648333ee039SDag-Erling Smørgrav fatal("%s: recieved %u PAM messages, expected <= %u", 649333ee039SDag-Erling Smørgrav __func__, *num, PAM_MAX_NUM_MSG); 650333ee039SDag-Erling Smørgrav *prompts = xcalloc((*num + 1), sizeof(char *)); 651333ee039SDag-Erling Smørgrav *echo_on = xcalloc((*num + 1), sizeof(u_int)); 652382d19eeSDag-Erling Smørgrav for (i = 0; i < *num; ++i) { 653382d19eeSDag-Erling Smørgrav (*prompts)[i] = buffer_get_string(&m, NULL); 654382d19eeSDag-Erling Smørgrav (*echo_on)[i] = buffer_get_int(&m); 655382d19eeSDag-Erling Smørgrav } 656382d19eeSDag-Erling Smørgrav buffer_free(&m); 657382d19eeSDag-Erling Smørgrav return (ret); 658382d19eeSDag-Erling Smørgrav } 659382d19eeSDag-Erling Smørgrav 660382d19eeSDag-Erling Smørgrav int 661cf2b5f3bSDag-Erling Smørgrav mm_sshpam_respond(void *ctx, u_int num, char **resp) 662382d19eeSDag-Erling Smørgrav { 663382d19eeSDag-Erling Smørgrav Buffer m; 664d4ecd108SDag-Erling Smørgrav u_int i; 665d4ecd108SDag-Erling Smørgrav int ret; 666382d19eeSDag-Erling Smørgrav 667382d19eeSDag-Erling Smørgrav debug3("%s", __func__); 668382d19eeSDag-Erling Smørgrav buffer_init(&m); 669382d19eeSDag-Erling Smørgrav buffer_put_int(&m, num); 670382d19eeSDag-Erling Smørgrav for (i = 0; i < num; ++i) 671382d19eeSDag-Erling Smørgrav buffer_put_cstring(&m, resp[i]); 672382d19eeSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_RESPOND, &m); 673382d19eeSDag-Erling Smørgrav debug3("%s: waiting for MONITOR_ANS_PAM_RESPOND", __func__); 674382d19eeSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_RESPOND, &m); 675382d19eeSDag-Erling Smørgrav ret = buffer_get_int(&m); 676382d19eeSDag-Erling Smørgrav debug3("%s: pam_respond returned %d", __func__, ret); 677382d19eeSDag-Erling Smørgrav buffer_free(&m); 678382d19eeSDag-Erling Smørgrav return (ret); 679382d19eeSDag-Erling Smørgrav } 680382d19eeSDag-Erling Smørgrav 681382d19eeSDag-Erling Smørgrav void 682cf2b5f3bSDag-Erling Smørgrav mm_sshpam_free_ctx(void *ctxtp) 683382d19eeSDag-Erling Smørgrav { 684382d19eeSDag-Erling Smørgrav Buffer m; 685382d19eeSDag-Erling Smørgrav 686382d19eeSDag-Erling Smørgrav debug3("%s", __func__); 687382d19eeSDag-Erling Smørgrav buffer_init(&m); 688382d19eeSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_FREE_CTX, &m); 689382d19eeSDag-Erling Smørgrav debug3("%s: waiting for MONITOR_ANS_PAM_FREE_CTX", __func__); 690382d19eeSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_FREE_CTX, &m); 691382d19eeSDag-Erling Smørgrav buffer_free(&m); 692382d19eeSDag-Erling Smørgrav } 69383d2307dSDag-Erling Smørgrav #endif /* USE_PAM */ 69483d2307dSDag-Erling Smørgrav 695545d5ecaSDag-Erling Smørgrav /* Request process termination */ 696545d5ecaSDag-Erling Smørgrav 697545d5ecaSDag-Erling Smørgrav void 698545d5ecaSDag-Erling Smørgrav mm_terminate(void) 699545d5ecaSDag-Erling Smørgrav { 700545d5ecaSDag-Erling Smørgrav Buffer m; 701545d5ecaSDag-Erling Smørgrav 702545d5ecaSDag-Erling Smørgrav buffer_init(&m); 703545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_TERM, &m); 704545d5ecaSDag-Erling Smørgrav buffer_free(&m); 705545d5ecaSDag-Erling Smørgrav } 706545d5ecaSDag-Erling Smørgrav 707a0ee8cc6SDag-Erling Smørgrav #ifdef WITH_SSH1 708545d5ecaSDag-Erling Smørgrav int 709545d5ecaSDag-Erling Smørgrav mm_ssh1_session_key(BIGNUM *num) 710545d5ecaSDag-Erling Smørgrav { 711545d5ecaSDag-Erling Smørgrav int rsafail; 712545d5ecaSDag-Erling Smørgrav Buffer m; 713545d5ecaSDag-Erling Smørgrav 714545d5ecaSDag-Erling Smørgrav buffer_init(&m); 715545d5ecaSDag-Erling Smørgrav buffer_put_bignum2(&m, num); 716545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SESSKEY, &m); 717545d5ecaSDag-Erling Smørgrav 718545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SESSKEY, &m); 719545d5ecaSDag-Erling Smørgrav 720545d5ecaSDag-Erling Smørgrav rsafail = buffer_get_int(&m); 721545d5ecaSDag-Erling Smørgrav buffer_get_bignum2(&m, num); 722545d5ecaSDag-Erling Smørgrav 723545d5ecaSDag-Erling Smørgrav buffer_free(&m); 724545d5ecaSDag-Erling Smørgrav 725545d5ecaSDag-Erling Smørgrav return (rsafail); 726545d5ecaSDag-Erling Smørgrav } 727a0ee8cc6SDag-Erling Smørgrav #endif 728545d5ecaSDag-Erling Smørgrav 729545d5ecaSDag-Erling Smørgrav static void 730545d5ecaSDag-Erling Smørgrav mm_chall_setup(char **name, char **infotxt, u_int *numprompts, 731545d5ecaSDag-Erling Smørgrav char ***prompts, u_int **echo_on) 732545d5ecaSDag-Erling Smørgrav { 733545d5ecaSDag-Erling Smørgrav *name = xstrdup(""); 734545d5ecaSDag-Erling Smørgrav *infotxt = xstrdup(""); 735545d5ecaSDag-Erling Smørgrav *numprompts = 1; 736333ee039SDag-Erling Smørgrav *prompts = xcalloc(*numprompts, sizeof(char *)); 737333ee039SDag-Erling Smørgrav *echo_on = xcalloc(*numprompts, sizeof(u_int)); 738545d5ecaSDag-Erling Smørgrav (*echo_on)[0] = 0; 739545d5ecaSDag-Erling Smørgrav } 740545d5ecaSDag-Erling Smørgrav 741545d5ecaSDag-Erling Smørgrav int 742545d5ecaSDag-Erling Smørgrav mm_bsdauth_query(void *ctx, char **name, char **infotxt, 743545d5ecaSDag-Erling Smørgrav u_int *numprompts, char ***prompts, u_int **echo_on) 744545d5ecaSDag-Erling Smørgrav { 745545d5ecaSDag-Erling Smørgrav Buffer m; 746e73e9afaSDag-Erling Smørgrav u_int success; 747545d5ecaSDag-Erling Smørgrav char *challenge; 748545d5ecaSDag-Erling Smørgrav 749545d5ecaSDag-Erling Smørgrav debug3("%s: entering", __func__); 750545d5ecaSDag-Erling Smørgrav 751545d5ecaSDag-Erling Smørgrav buffer_init(&m); 752545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHQUERY, &m); 753545d5ecaSDag-Erling Smørgrav 754545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_BSDAUTHQUERY, 755545d5ecaSDag-Erling Smørgrav &m); 756e73e9afaSDag-Erling Smørgrav success = buffer_get_int(&m); 757e73e9afaSDag-Erling Smørgrav if (success == 0) { 758545d5ecaSDag-Erling Smørgrav debug3("%s: no challenge", __func__); 759545d5ecaSDag-Erling Smørgrav buffer_free(&m); 760545d5ecaSDag-Erling Smørgrav return (-1); 761545d5ecaSDag-Erling Smørgrav } 762545d5ecaSDag-Erling Smørgrav 763545d5ecaSDag-Erling Smørgrav /* Get the challenge, and format the response */ 764545d5ecaSDag-Erling Smørgrav challenge = buffer_get_string(&m, NULL); 765545d5ecaSDag-Erling Smørgrav buffer_free(&m); 766545d5ecaSDag-Erling Smørgrav 767545d5ecaSDag-Erling Smørgrav mm_chall_setup(name, infotxt, numprompts, prompts, echo_on); 768545d5ecaSDag-Erling Smørgrav (*prompts)[0] = challenge; 769545d5ecaSDag-Erling Smørgrav 770545d5ecaSDag-Erling Smørgrav debug3("%s: received challenge: %s", __func__, challenge); 771545d5ecaSDag-Erling Smørgrav 772545d5ecaSDag-Erling Smørgrav return (0); 773545d5ecaSDag-Erling Smørgrav } 774545d5ecaSDag-Erling Smørgrav 775545d5ecaSDag-Erling Smørgrav int 776545d5ecaSDag-Erling Smørgrav mm_bsdauth_respond(void *ctx, u_int numresponses, char **responses) 777545d5ecaSDag-Erling Smørgrav { 778545d5ecaSDag-Erling Smørgrav Buffer m; 779545d5ecaSDag-Erling Smørgrav int authok; 780545d5ecaSDag-Erling Smørgrav 781545d5ecaSDag-Erling Smørgrav debug3("%s: entering", __func__); 782545d5ecaSDag-Erling Smørgrav if (numresponses != 1) 783545d5ecaSDag-Erling Smørgrav return (-1); 784545d5ecaSDag-Erling Smørgrav 785545d5ecaSDag-Erling Smørgrav buffer_init(&m); 786545d5ecaSDag-Erling Smørgrav buffer_put_cstring(&m, responses[0]); 787545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHRESPOND, &m); 788545d5ecaSDag-Erling Smørgrav 789545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, 790545d5ecaSDag-Erling Smørgrav MONITOR_ANS_BSDAUTHRESPOND, &m); 791545d5ecaSDag-Erling Smørgrav 792545d5ecaSDag-Erling Smørgrav authok = buffer_get_int(&m); 793545d5ecaSDag-Erling Smørgrav buffer_free(&m); 794545d5ecaSDag-Erling Smørgrav 795545d5ecaSDag-Erling Smørgrav return ((authok == 0) ? -1 : 0); 796545d5ecaSDag-Erling Smørgrav } 797545d5ecaSDag-Erling Smørgrav 798edb557f8SDag-Erling Smørgrav #ifdef SKEY 799545d5ecaSDag-Erling Smørgrav int 800545d5ecaSDag-Erling Smørgrav mm_skey_query(void *ctx, char **name, char **infotxt, 801545d5ecaSDag-Erling Smørgrav u_int *numprompts, char ***prompts, u_int **echo_on) 802545d5ecaSDag-Erling Smørgrav { 803545d5ecaSDag-Erling Smørgrav Buffer m; 804e73e9afaSDag-Erling Smørgrav u_int success; 805333ee039SDag-Erling Smørgrav char *challenge; 806545d5ecaSDag-Erling Smørgrav 807545d5ecaSDag-Erling Smørgrav debug3("%s: entering", __func__); 808545d5ecaSDag-Erling Smørgrav 809545d5ecaSDag-Erling Smørgrav buffer_init(&m); 810545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SKEYQUERY, &m); 811545d5ecaSDag-Erling Smørgrav 812545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SKEYQUERY, 813545d5ecaSDag-Erling Smørgrav &m); 814e73e9afaSDag-Erling Smørgrav success = buffer_get_int(&m); 815e73e9afaSDag-Erling Smørgrav if (success == 0) { 816545d5ecaSDag-Erling Smørgrav debug3("%s: no challenge", __func__); 817545d5ecaSDag-Erling Smørgrav buffer_free(&m); 818545d5ecaSDag-Erling Smørgrav return (-1); 819545d5ecaSDag-Erling Smørgrav } 820545d5ecaSDag-Erling Smørgrav 821545d5ecaSDag-Erling Smørgrav /* Get the challenge, and format the response */ 822545d5ecaSDag-Erling Smørgrav challenge = buffer_get_string(&m, NULL); 823545d5ecaSDag-Erling Smørgrav buffer_free(&m); 824545d5ecaSDag-Erling Smørgrav 825545d5ecaSDag-Erling Smørgrav debug3("%s: received challenge: %s", __func__, challenge); 826545d5ecaSDag-Erling Smørgrav 827545d5ecaSDag-Erling Smørgrav mm_chall_setup(name, infotxt, numprompts, prompts, echo_on); 828545d5ecaSDag-Erling Smørgrav 829333ee039SDag-Erling Smørgrav xasprintf(*prompts, "%s%s", challenge, SKEY_PROMPT); 830e4a9863fSDag-Erling Smørgrav free(challenge); 831545d5ecaSDag-Erling Smørgrav 832545d5ecaSDag-Erling Smørgrav return (0); 833545d5ecaSDag-Erling Smørgrav } 834545d5ecaSDag-Erling Smørgrav 835545d5ecaSDag-Erling Smørgrav int 836545d5ecaSDag-Erling Smørgrav mm_skey_respond(void *ctx, u_int numresponses, char **responses) 837545d5ecaSDag-Erling Smørgrav { 838545d5ecaSDag-Erling Smørgrav Buffer m; 839545d5ecaSDag-Erling Smørgrav int authok; 840545d5ecaSDag-Erling Smørgrav 841545d5ecaSDag-Erling Smørgrav debug3("%s: entering", __func__); 842545d5ecaSDag-Erling Smørgrav if (numresponses != 1) 843545d5ecaSDag-Erling Smørgrav return (-1); 844545d5ecaSDag-Erling Smørgrav 845545d5ecaSDag-Erling Smørgrav buffer_init(&m); 846545d5ecaSDag-Erling Smørgrav buffer_put_cstring(&m, responses[0]); 847545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SKEYRESPOND, &m); 848545d5ecaSDag-Erling Smørgrav 849545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, 850545d5ecaSDag-Erling Smørgrav MONITOR_ANS_SKEYRESPOND, &m); 851545d5ecaSDag-Erling Smørgrav 852545d5ecaSDag-Erling Smørgrav authok = buffer_get_int(&m); 853545d5ecaSDag-Erling Smørgrav buffer_free(&m); 854545d5ecaSDag-Erling Smørgrav 855545d5ecaSDag-Erling Smørgrav return ((authok == 0) ? -1 : 0); 856545d5ecaSDag-Erling Smørgrav } 85721e764dfSDag-Erling Smørgrav #endif /* SKEY */ 858545d5ecaSDag-Erling Smørgrav 859545d5ecaSDag-Erling Smørgrav void 860545d5ecaSDag-Erling Smørgrav mm_ssh1_session_id(u_char session_id[16]) 861545d5ecaSDag-Erling Smørgrav { 862545d5ecaSDag-Erling Smørgrav Buffer m; 863545d5ecaSDag-Erling Smørgrav int i; 864545d5ecaSDag-Erling Smørgrav 865545d5ecaSDag-Erling Smørgrav debug3("%s entering", __func__); 866545d5ecaSDag-Erling Smørgrav 867545d5ecaSDag-Erling Smørgrav buffer_init(&m); 868545d5ecaSDag-Erling Smørgrav for (i = 0; i < 16; i++) 869545d5ecaSDag-Erling Smørgrav buffer_put_char(&m, session_id[i]); 870545d5ecaSDag-Erling Smørgrav 871545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SESSID, &m); 872545d5ecaSDag-Erling Smørgrav buffer_free(&m); 873545d5ecaSDag-Erling Smørgrav } 874545d5ecaSDag-Erling Smørgrav 875a0ee8cc6SDag-Erling Smørgrav #ifdef WITH_SSH1 876545d5ecaSDag-Erling Smørgrav int 877545d5ecaSDag-Erling Smørgrav mm_auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey) 878545d5ecaSDag-Erling Smørgrav { 879545d5ecaSDag-Erling Smørgrav Buffer m; 880545d5ecaSDag-Erling Smørgrav Key *key; 881545d5ecaSDag-Erling Smørgrav u_char *blob; 882545d5ecaSDag-Erling Smørgrav u_int blen; 883e73e9afaSDag-Erling Smørgrav int allowed = 0, have_forced = 0; 884545d5ecaSDag-Erling Smørgrav 885545d5ecaSDag-Erling Smørgrav debug3("%s entering", __func__); 886545d5ecaSDag-Erling Smørgrav 887545d5ecaSDag-Erling Smørgrav buffer_init(&m); 888545d5ecaSDag-Erling Smørgrav buffer_put_bignum2(&m, client_n); 889545d5ecaSDag-Erling Smørgrav 890545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSAKEYALLOWED, &m); 891545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSAKEYALLOWED, &m); 892545d5ecaSDag-Erling Smørgrav 893545d5ecaSDag-Erling Smørgrav allowed = buffer_get_int(&m); 894545d5ecaSDag-Erling Smørgrav 895e73e9afaSDag-Erling Smørgrav /* fake forced command */ 896e73e9afaSDag-Erling Smørgrav auth_clear_options(); 897e73e9afaSDag-Erling Smørgrav have_forced = buffer_get_int(&m); 898e73e9afaSDag-Erling Smørgrav forced_command = have_forced ? xstrdup("true") : NULL; 899e73e9afaSDag-Erling Smørgrav 900545d5ecaSDag-Erling Smørgrav if (allowed && rkey != NULL) { 901545d5ecaSDag-Erling Smørgrav blob = buffer_get_string(&m, &blen); 902545d5ecaSDag-Erling Smørgrav if ((key = key_from_blob(blob, blen)) == NULL) 903545d5ecaSDag-Erling Smørgrav fatal("%s: key_from_blob failed", __func__); 904545d5ecaSDag-Erling Smørgrav *rkey = key; 905e4a9863fSDag-Erling Smørgrav free(blob); 906545d5ecaSDag-Erling Smørgrav } 907545d5ecaSDag-Erling Smørgrav buffer_free(&m); 908545d5ecaSDag-Erling Smørgrav 909545d5ecaSDag-Erling Smørgrav return (allowed); 910545d5ecaSDag-Erling Smørgrav } 911545d5ecaSDag-Erling Smørgrav 912545d5ecaSDag-Erling Smørgrav BIGNUM * 913545d5ecaSDag-Erling Smørgrav mm_auth_rsa_generate_challenge(Key *key) 914545d5ecaSDag-Erling Smørgrav { 915545d5ecaSDag-Erling Smørgrav Buffer m; 916545d5ecaSDag-Erling Smørgrav BIGNUM *challenge; 917545d5ecaSDag-Erling Smørgrav u_char *blob; 918545d5ecaSDag-Erling Smørgrav u_int blen; 919545d5ecaSDag-Erling Smørgrav 920545d5ecaSDag-Erling Smørgrav debug3("%s entering", __func__); 921545d5ecaSDag-Erling Smørgrav 922545d5ecaSDag-Erling Smørgrav if ((challenge = BN_new()) == NULL) 923545d5ecaSDag-Erling Smørgrav fatal("%s: BN_new failed", __func__); 924545d5ecaSDag-Erling Smørgrav 925545d5ecaSDag-Erling Smørgrav key->type = KEY_RSA; /* XXX cheat for key_to_blob */ 926545d5ecaSDag-Erling Smørgrav if (key_to_blob(key, &blob, &blen) == 0) 927545d5ecaSDag-Erling Smørgrav fatal("%s: key_to_blob failed", __func__); 928545d5ecaSDag-Erling Smørgrav key->type = KEY_RSA1; 929545d5ecaSDag-Erling Smørgrav 930545d5ecaSDag-Erling Smørgrav buffer_init(&m); 931545d5ecaSDag-Erling Smørgrav buffer_put_string(&m, blob, blen); 932e4a9863fSDag-Erling Smørgrav free(blob); 933545d5ecaSDag-Erling Smørgrav 934545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSACHALLENGE, &m); 935545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSACHALLENGE, &m); 936545d5ecaSDag-Erling Smørgrav 937545d5ecaSDag-Erling Smørgrav buffer_get_bignum2(&m, challenge); 938545d5ecaSDag-Erling Smørgrav buffer_free(&m); 939545d5ecaSDag-Erling Smørgrav 940545d5ecaSDag-Erling Smørgrav return (challenge); 941545d5ecaSDag-Erling Smørgrav } 942545d5ecaSDag-Erling Smørgrav 943545d5ecaSDag-Erling Smørgrav int 944545d5ecaSDag-Erling Smørgrav mm_auth_rsa_verify_response(Key *key, BIGNUM *p, u_char response[16]) 945545d5ecaSDag-Erling Smørgrav { 946545d5ecaSDag-Erling Smørgrav Buffer m; 947545d5ecaSDag-Erling Smørgrav u_char *blob; 948545d5ecaSDag-Erling Smørgrav u_int blen; 949545d5ecaSDag-Erling Smørgrav int success = 0; 950545d5ecaSDag-Erling Smørgrav 951545d5ecaSDag-Erling Smørgrav debug3("%s entering", __func__); 952545d5ecaSDag-Erling Smørgrav 953545d5ecaSDag-Erling Smørgrav key->type = KEY_RSA; /* XXX cheat for key_to_blob */ 954545d5ecaSDag-Erling Smørgrav if (key_to_blob(key, &blob, &blen) == 0) 955545d5ecaSDag-Erling Smørgrav fatal("%s: key_to_blob failed", __func__); 956545d5ecaSDag-Erling Smørgrav key->type = KEY_RSA1; 957545d5ecaSDag-Erling Smørgrav 958545d5ecaSDag-Erling Smørgrav buffer_init(&m); 959545d5ecaSDag-Erling Smørgrav buffer_put_string(&m, blob, blen); 960545d5ecaSDag-Erling Smørgrav buffer_put_string(&m, response, 16); 961e4a9863fSDag-Erling Smørgrav free(blob); 962545d5ecaSDag-Erling Smørgrav 963545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSARESPONSE, &m); 964545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSARESPONSE, &m); 965545d5ecaSDag-Erling Smørgrav 966545d5ecaSDag-Erling Smørgrav success = buffer_get_int(&m); 967545d5ecaSDag-Erling Smørgrav buffer_free(&m); 968545d5ecaSDag-Erling Smørgrav 969545d5ecaSDag-Erling Smørgrav return (success); 970545d5ecaSDag-Erling Smørgrav } 971a0ee8cc6SDag-Erling Smørgrav #endif 972f388f5efSDag-Erling Smørgrav 973aa49c926SDag-Erling Smørgrav #ifdef SSH_AUDIT_EVENTS 974aa49c926SDag-Erling Smørgrav void 975aa49c926SDag-Erling Smørgrav mm_audit_event(ssh_audit_event_t event) 976aa49c926SDag-Erling Smørgrav { 977aa49c926SDag-Erling Smørgrav Buffer m; 978aa49c926SDag-Erling Smørgrav 979aa49c926SDag-Erling Smørgrav debug3("%s entering", __func__); 980aa49c926SDag-Erling Smørgrav 981aa49c926SDag-Erling Smørgrav buffer_init(&m); 982aa49c926SDag-Erling Smørgrav buffer_put_int(&m, event); 983aa49c926SDag-Erling Smørgrav 984aa49c926SDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_EVENT, &m); 985aa49c926SDag-Erling Smørgrav buffer_free(&m); 986aa49c926SDag-Erling Smørgrav } 987aa49c926SDag-Erling Smørgrav 988aa49c926SDag-Erling Smørgrav void 989aa49c926SDag-Erling Smørgrav mm_audit_run_command(const char *command) 990aa49c926SDag-Erling Smørgrav { 991aa49c926SDag-Erling Smørgrav Buffer m; 992aa49c926SDag-Erling Smørgrav 993aa49c926SDag-Erling Smørgrav debug3("%s entering command %s", __func__, command); 994aa49c926SDag-Erling Smørgrav 995aa49c926SDag-Erling Smørgrav buffer_init(&m); 996aa49c926SDag-Erling Smørgrav buffer_put_cstring(&m, command); 997aa49c926SDag-Erling Smørgrav 998aa49c926SDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, &m); 999aa49c926SDag-Erling Smørgrav buffer_free(&m); 1000aa49c926SDag-Erling Smørgrav } 1001aa49c926SDag-Erling Smørgrav #endif /* SSH_AUDIT_EVENTS */ 1002aa49c926SDag-Erling Smørgrav 1003cf2b5f3bSDag-Erling Smørgrav #ifdef GSSAPI 1004cf2b5f3bSDag-Erling Smørgrav OM_uint32 100521e764dfSDag-Erling Smørgrav mm_ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID goid) 1006f388f5efSDag-Erling Smørgrav { 1007f388f5efSDag-Erling Smørgrav Buffer m; 1008cf2b5f3bSDag-Erling Smørgrav OM_uint32 major; 1009f388f5efSDag-Erling Smørgrav 1010cf2b5f3bSDag-Erling Smørgrav /* Client doesn't get to see the context */ 1011cf2b5f3bSDag-Erling Smørgrav *ctx = NULL; 1012f388f5efSDag-Erling Smørgrav 1013f388f5efSDag-Erling Smørgrav buffer_init(&m); 101421e764dfSDag-Erling Smørgrav buffer_put_string(&m, goid->elements, goid->length); 1015f388f5efSDag-Erling Smørgrav 1016cf2b5f3bSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSETUP, &m); 1017cf2b5f3bSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSETUP, &m); 1018f388f5efSDag-Erling Smørgrav 1019cf2b5f3bSDag-Erling Smørgrav major = buffer_get_int(&m); 1020cf2b5f3bSDag-Erling Smørgrav 1021f388f5efSDag-Erling Smørgrav buffer_free(&m); 1022cf2b5f3bSDag-Erling Smørgrav return (major); 1023f388f5efSDag-Erling Smørgrav } 1024f388f5efSDag-Erling Smørgrav 1025cf2b5f3bSDag-Erling Smørgrav OM_uint32 1026cf2b5f3bSDag-Erling Smørgrav mm_ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *in, 1027cf2b5f3bSDag-Erling Smørgrav gss_buffer_desc *out, OM_uint32 *flags) 1028f388f5efSDag-Erling Smørgrav { 1029f388f5efSDag-Erling Smørgrav Buffer m; 1030cf2b5f3bSDag-Erling Smørgrav OM_uint32 major; 1031f388f5efSDag-Erling Smørgrav u_int len; 1032f388f5efSDag-Erling Smørgrav 1033cf2b5f3bSDag-Erling Smørgrav buffer_init(&m); 1034cf2b5f3bSDag-Erling Smørgrav buffer_put_string(&m, in->value, in->length); 1035cf2b5f3bSDag-Erling Smørgrav 1036cf2b5f3bSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSTEP, &m); 1037cf2b5f3bSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSTEP, &m); 1038cf2b5f3bSDag-Erling Smørgrav 1039cf2b5f3bSDag-Erling Smørgrav major = buffer_get_int(&m); 1040cf2b5f3bSDag-Erling Smørgrav out->value = buffer_get_string(&m, &len); 1041cf2b5f3bSDag-Erling Smørgrav out->length = len; 1042cf2b5f3bSDag-Erling Smørgrav if (flags) 1043cf2b5f3bSDag-Erling Smørgrav *flags = buffer_get_int(&m); 1044f388f5efSDag-Erling Smørgrav 1045f388f5efSDag-Erling Smørgrav buffer_free(&m); 1046cf2b5f3bSDag-Erling Smørgrav 1047cf2b5f3bSDag-Erling Smørgrav return (major); 1048f388f5efSDag-Erling Smørgrav } 1049cf2b5f3bSDag-Erling Smørgrav 10501ec0d754SDag-Erling Smørgrav OM_uint32 10511ec0d754SDag-Erling Smørgrav mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) 10521ec0d754SDag-Erling Smørgrav { 10531ec0d754SDag-Erling Smørgrav Buffer m; 10541ec0d754SDag-Erling Smørgrav OM_uint32 major; 10551ec0d754SDag-Erling Smørgrav 10561ec0d754SDag-Erling Smørgrav buffer_init(&m); 10571ec0d754SDag-Erling Smørgrav buffer_put_string(&m, gssbuf->value, gssbuf->length); 10581ec0d754SDag-Erling Smørgrav buffer_put_string(&m, gssmic->value, gssmic->length); 10591ec0d754SDag-Erling Smørgrav 10601ec0d754SDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSCHECKMIC, &m); 10611ec0d754SDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSCHECKMIC, 10621ec0d754SDag-Erling Smørgrav &m); 10631ec0d754SDag-Erling Smørgrav 10641ec0d754SDag-Erling Smørgrav major = buffer_get_int(&m); 10651ec0d754SDag-Erling Smørgrav buffer_free(&m); 10661ec0d754SDag-Erling Smørgrav return(major); 10671ec0d754SDag-Erling Smørgrav } 10681ec0d754SDag-Erling Smørgrav 1069cf2b5f3bSDag-Erling Smørgrav int 1070cf2b5f3bSDag-Erling Smørgrav mm_ssh_gssapi_userok(char *user) 1071cf2b5f3bSDag-Erling Smørgrav { 1072cf2b5f3bSDag-Erling Smørgrav Buffer m; 1073cf2b5f3bSDag-Erling Smørgrav int authenticated = 0; 1074cf2b5f3bSDag-Erling Smørgrav 1075cf2b5f3bSDag-Erling Smørgrav buffer_init(&m); 1076cf2b5f3bSDag-Erling Smørgrav 1077cf2b5f3bSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, &m); 1078cf2b5f3bSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUSEROK, 1079cf2b5f3bSDag-Erling Smørgrav &m); 1080cf2b5f3bSDag-Erling Smørgrav 1081cf2b5f3bSDag-Erling Smørgrav authenticated = buffer_get_int(&m); 1082cf2b5f3bSDag-Erling Smørgrav 1083cf2b5f3bSDag-Erling Smørgrav buffer_free(&m); 1084cf2b5f3bSDag-Erling Smørgrav debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not "); 1085cf2b5f3bSDag-Erling Smørgrav return (authenticated); 1086cf2b5f3bSDag-Erling Smørgrav } 1087cf2b5f3bSDag-Erling Smørgrav #endif /* GSSAPI */ 1088cce7d346SDag-Erling Smørgrav 1089