1*557f75e5SDag-Erling Smørgrav /* $OpenBSD: monitor_wrap.c,v 1.85 2015/05/01 03:23:51 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 85bc5531deSDag-Erling Smørgrav #include "ssherr.h" 86bc5531deSDag-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*557f75e5SDag-Erling Smørgrav if (errno == EPIPE) 1571ec0d754SDag-Erling Smørgrav cleanup_exit(255); 158d4ecd108SDag-Erling Smørgrav fatal("%s: read: %s", __func__, strerror(errno)); 159545d5ecaSDag-Erling Smørgrav } 160333ee039SDag-Erling Smørgrav msg_len = get_u32(buf); 161545d5ecaSDag-Erling Smørgrav if (msg_len > 256 * 1024) 162545d5ecaSDag-Erling Smørgrav fatal("%s: read: bad msg_len %d", __func__, msg_len); 163545d5ecaSDag-Erling Smørgrav buffer_clear(m); 164545d5ecaSDag-Erling Smørgrav buffer_append_space(m, msg_len); 165d4ecd108SDag-Erling Smørgrav if (atomicio(read, sock, buffer_ptr(m), msg_len) != msg_len) 166d4ecd108SDag-Erling Smørgrav fatal("%s: read: %s", __func__, strerror(errno)); 167545d5ecaSDag-Erling Smørgrav } 168545d5ecaSDag-Erling Smørgrav 169545d5ecaSDag-Erling Smørgrav void 17021e764dfSDag-Erling Smørgrav mm_request_receive_expect(int sock, enum monitor_reqtype type, Buffer *m) 171545d5ecaSDag-Erling Smørgrav { 172545d5ecaSDag-Erling Smørgrav u_char rtype; 173545d5ecaSDag-Erling Smørgrav 174545d5ecaSDag-Erling Smørgrav debug3("%s entering: type %d", __func__, type); 175545d5ecaSDag-Erling Smørgrav 17621e764dfSDag-Erling Smørgrav mm_request_receive(sock, m); 177545d5ecaSDag-Erling Smørgrav rtype = buffer_get_char(m); 178545d5ecaSDag-Erling Smørgrav if (rtype != type) 179545d5ecaSDag-Erling Smørgrav fatal("%s: read: rtype %d != type %d", __func__, 180545d5ecaSDag-Erling Smørgrav rtype, type); 181545d5ecaSDag-Erling Smørgrav } 182545d5ecaSDag-Erling Smørgrav 183a0ee8cc6SDag-Erling Smørgrav #ifdef WITH_OPENSSL 184545d5ecaSDag-Erling Smørgrav DH * 185545d5ecaSDag-Erling Smørgrav mm_choose_dh(int min, int nbits, int max) 186545d5ecaSDag-Erling Smørgrav { 187545d5ecaSDag-Erling Smørgrav BIGNUM *p, *g; 188545d5ecaSDag-Erling Smørgrav int success = 0; 189545d5ecaSDag-Erling Smørgrav Buffer m; 190545d5ecaSDag-Erling Smørgrav 191545d5ecaSDag-Erling Smørgrav buffer_init(&m); 192545d5ecaSDag-Erling Smørgrav buffer_put_int(&m, min); 193545d5ecaSDag-Erling Smørgrav buffer_put_int(&m, nbits); 194545d5ecaSDag-Erling Smørgrav buffer_put_int(&m, max); 195545d5ecaSDag-Erling Smørgrav 196545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_MODULI, &m); 197545d5ecaSDag-Erling Smørgrav 198545d5ecaSDag-Erling Smørgrav debug3("%s: waiting for MONITOR_ANS_MODULI", __func__); 199545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_MODULI, &m); 200545d5ecaSDag-Erling Smørgrav 201545d5ecaSDag-Erling Smørgrav success = buffer_get_char(&m); 202545d5ecaSDag-Erling Smørgrav if (success == 0) 203545d5ecaSDag-Erling Smørgrav fatal("%s: MONITOR_ANS_MODULI failed", __func__); 204545d5ecaSDag-Erling Smørgrav 205545d5ecaSDag-Erling Smørgrav if ((p = BN_new()) == NULL) 206545d5ecaSDag-Erling Smørgrav fatal("%s: BN_new failed", __func__); 207545d5ecaSDag-Erling Smørgrav if ((g = BN_new()) == NULL) 208545d5ecaSDag-Erling Smørgrav fatal("%s: BN_new failed", __func__); 209545d5ecaSDag-Erling Smørgrav buffer_get_bignum2(&m, p); 210545d5ecaSDag-Erling Smørgrav buffer_get_bignum2(&m, g); 211545d5ecaSDag-Erling Smørgrav 212545d5ecaSDag-Erling Smørgrav debug3("%s: remaining %d", __func__, buffer_len(&m)); 213545d5ecaSDag-Erling Smørgrav buffer_free(&m); 214545d5ecaSDag-Erling Smørgrav 215545d5ecaSDag-Erling Smørgrav return (dh_new_group(g, p)); 216545d5ecaSDag-Erling Smørgrav } 217a0ee8cc6SDag-Erling Smørgrav #endif 218545d5ecaSDag-Erling Smørgrav 219545d5ecaSDag-Erling Smørgrav int 220bc5531deSDag-Erling Smørgrav mm_key_sign(Key *key, u_char **sigp, u_int *lenp, 221bc5531deSDag-Erling Smørgrav const u_char *data, u_int datalen) 222545d5ecaSDag-Erling Smørgrav { 223bc5531deSDag-Erling Smørgrav struct kex *kex = *pmonitor->m_pkex; 224545d5ecaSDag-Erling Smørgrav Buffer m; 225545d5ecaSDag-Erling Smørgrav 226545d5ecaSDag-Erling Smørgrav debug3("%s entering", __func__); 227545d5ecaSDag-Erling Smørgrav 228545d5ecaSDag-Erling Smørgrav buffer_init(&m); 229bc5531deSDag-Erling Smørgrav buffer_put_int(&m, kex->host_key_index(key, 0, active_state)); 230545d5ecaSDag-Erling Smørgrav buffer_put_string(&m, data, datalen); 231545d5ecaSDag-Erling Smørgrav 232545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SIGN, &m); 233545d5ecaSDag-Erling Smørgrav 234545d5ecaSDag-Erling Smørgrav debug3("%s: waiting for MONITOR_ANS_SIGN", __func__); 235545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SIGN, &m); 236545d5ecaSDag-Erling Smørgrav *sigp = buffer_get_string(&m, lenp); 237545d5ecaSDag-Erling Smørgrav buffer_free(&m); 238545d5ecaSDag-Erling Smørgrav 239545d5ecaSDag-Erling Smørgrav return (0); 240545d5ecaSDag-Erling Smørgrav } 241545d5ecaSDag-Erling Smørgrav 242545d5ecaSDag-Erling Smørgrav struct passwd * 24321e764dfSDag-Erling Smørgrav mm_getpwnamallow(const char *username) 244545d5ecaSDag-Erling Smørgrav { 245545d5ecaSDag-Erling Smørgrav Buffer m; 246545d5ecaSDag-Erling Smørgrav struct passwd *pw; 247e146993eSDag-Erling Smørgrav u_int len, i; 248d4af9e69SDag-Erling Smørgrav ServerOptions *newopts; 249545d5ecaSDag-Erling Smørgrav 250545d5ecaSDag-Erling Smørgrav debug3("%s entering", __func__); 251545d5ecaSDag-Erling Smørgrav 252545d5ecaSDag-Erling Smørgrav buffer_init(&m); 25321e764dfSDag-Erling Smørgrav buffer_put_cstring(&m, username); 254545d5ecaSDag-Erling Smørgrav 255545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PWNAM, &m); 256545d5ecaSDag-Erling Smørgrav 257545d5ecaSDag-Erling Smørgrav debug3("%s: waiting for MONITOR_ANS_PWNAM", __func__); 258545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PWNAM, &m); 259545d5ecaSDag-Erling Smørgrav 260545d5ecaSDag-Erling Smørgrav if (buffer_get_char(&m) == 0) { 261d4af9e69SDag-Erling Smørgrav pw = NULL; 262d4af9e69SDag-Erling Smørgrav goto out; 263545d5ecaSDag-Erling Smørgrav } 264d4af9e69SDag-Erling Smørgrav pw = buffer_get_string(&m, &len); 265d4af9e69SDag-Erling Smørgrav if (len != sizeof(struct passwd)) 266545d5ecaSDag-Erling Smørgrav fatal("%s: struct passwd size mismatch", __func__); 267545d5ecaSDag-Erling Smørgrav pw->pw_name = buffer_get_string(&m, NULL); 268545d5ecaSDag-Erling Smørgrav pw->pw_passwd = buffer_get_string(&m, NULL); 269e4a9863fSDag-Erling Smørgrav #ifdef HAVE_STRUCT_PASSWD_PW_GECOS 270545d5ecaSDag-Erling Smørgrav pw->pw_gecos = buffer_get_string(&m, NULL); 271e4a9863fSDag-Erling Smørgrav #endif 272e4a9863fSDag-Erling Smørgrav #ifdef HAVE_STRUCT_PASSWD_PW_CLASS 273545d5ecaSDag-Erling Smørgrav pw->pw_class = buffer_get_string(&m, NULL); 27483d2307dSDag-Erling Smørgrav #endif 275545d5ecaSDag-Erling Smørgrav pw->pw_dir = buffer_get_string(&m, NULL); 276545d5ecaSDag-Erling Smørgrav pw->pw_shell = buffer_get_string(&m, NULL); 277d4af9e69SDag-Erling Smørgrav 278d4af9e69SDag-Erling Smørgrav out: 279d4af9e69SDag-Erling Smørgrav /* copy options block as a Match directive may have changed some */ 280d4af9e69SDag-Erling Smørgrav newopts = buffer_get_string(&m, &len); 281d4af9e69SDag-Erling Smørgrav if (len != sizeof(*newopts)) 282d4af9e69SDag-Erling Smørgrav fatal("%s: option block size mismatch", __func__); 283e146993eSDag-Erling Smørgrav 284e146993eSDag-Erling Smørgrav #define M_CP_STROPT(x) do { \ 285e146993eSDag-Erling Smørgrav if (newopts->x != NULL) \ 286e146993eSDag-Erling Smørgrav newopts->x = buffer_get_string(&m, NULL); \ 287e146993eSDag-Erling Smørgrav } while (0) 288e146993eSDag-Erling Smørgrav #define M_CP_STRARRAYOPT(x, nx) do { \ 289e146993eSDag-Erling Smørgrav for (i = 0; i < newopts->nx; i++) \ 290e146993eSDag-Erling Smørgrav newopts->x[i] = buffer_get_string(&m, NULL); \ 291e146993eSDag-Erling Smørgrav } while (0) 292e146993eSDag-Erling Smørgrav /* See comment in servconf.h */ 293e146993eSDag-Erling Smørgrav COPY_MATCH_STRING_OPTS(); 294e146993eSDag-Erling Smørgrav #undef M_CP_STROPT 295e146993eSDag-Erling Smørgrav #undef M_CP_STRARRAYOPT 296e146993eSDag-Erling Smørgrav 297d4af9e69SDag-Erling Smørgrav copy_set_server_options(&options, newopts, 1); 298e4a9863fSDag-Erling Smørgrav free(newopts); 299d4af9e69SDag-Erling Smørgrav 300545d5ecaSDag-Erling Smørgrav buffer_free(&m); 301545d5ecaSDag-Erling Smørgrav 302545d5ecaSDag-Erling Smørgrav return (pw); 303545d5ecaSDag-Erling Smørgrav } 304545d5ecaSDag-Erling Smørgrav 3051ec0d754SDag-Erling Smørgrav char * 3061ec0d754SDag-Erling Smørgrav mm_auth2_read_banner(void) 307545d5ecaSDag-Erling Smørgrav { 308545d5ecaSDag-Erling Smørgrav Buffer m; 309545d5ecaSDag-Erling Smørgrav char *banner; 310545d5ecaSDag-Erling Smørgrav 311545d5ecaSDag-Erling Smørgrav debug3("%s entering", __func__); 312545d5ecaSDag-Erling Smørgrav 313545d5ecaSDag-Erling Smørgrav buffer_init(&m); 314545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTH2_READ_BANNER, &m); 315545d5ecaSDag-Erling Smørgrav buffer_clear(&m); 316545d5ecaSDag-Erling Smørgrav 3171ec0d754SDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, 3181ec0d754SDag-Erling Smørgrav MONITOR_ANS_AUTH2_READ_BANNER, &m); 319545d5ecaSDag-Erling Smørgrav banner = buffer_get_string(&m, NULL); 320545d5ecaSDag-Erling Smørgrav buffer_free(&m); 321545d5ecaSDag-Erling Smørgrav 3221ec0d754SDag-Erling Smørgrav /* treat empty banner as missing banner */ 3231ec0d754SDag-Erling Smørgrav if (strlen(banner) == 0) { 324e4a9863fSDag-Erling Smørgrav free(banner); 3251ec0d754SDag-Erling Smørgrav banner = NULL; 3261ec0d754SDag-Erling Smørgrav } 327545d5ecaSDag-Erling Smørgrav return (banner); 328545d5ecaSDag-Erling Smørgrav } 329545d5ecaSDag-Erling Smørgrav 330545d5ecaSDag-Erling Smørgrav /* Inform the privileged process about service and style */ 331545d5ecaSDag-Erling Smørgrav 332545d5ecaSDag-Erling Smørgrav void 333545d5ecaSDag-Erling Smørgrav mm_inform_authserv(char *service, char *style) 334545d5ecaSDag-Erling Smørgrav { 335545d5ecaSDag-Erling Smørgrav Buffer m; 336545d5ecaSDag-Erling Smørgrav 337545d5ecaSDag-Erling Smørgrav debug3("%s entering", __func__); 338545d5ecaSDag-Erling Smørgrav 339545d5ecaSDag-Erling Smørgrav buffer_init(&m); 340545d5ecaSDag-Erling Smørgrav buffer_put_cstring(&m, service); 341545d5ecaSDag-Erling Smørgrav buffer_put_cstring(&m, style ? style : ""); 342545d5ecaSDag-Erling Smørgrav 343545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHSERV, &m); 344545d5ecaSDag-Erling Smørgrav 345545d5ecaSDag-Erling Smørgrav buffer_free(&m); 346545d5ecaSDag-Erling Smørgrav } 347545d5ecaSDag-Erling Smørgrav 348545d5ecaSDag-Erling Smørgrav /* Do the password authentication */ 349545d5ecaSDag-Erling Smørgrav int 350545d5ecaSDag-Erling Smørgrav mm_auth_password(Authctxt *authctxt, char *password) 351545d5ecaSDag-Erling Smørgrav { 352545d5ecaSDag-Erling Smørgrav Buffer m; 353545d5ecaSDag-Erling Smørgrav int authenticated = 0; 354545d5ecaSDag-Erling Smørgrav 355545d5ecaSDag-Erling Smørgrav debug3("%s entering", __func__); 356545d5ecaSDag-Erling Smørgrav 357545d5ecaSDag-Erling Smørgrav buffer_init(&m); 358545d5ecaSDag-Erling Smørgrav buffer_put_cstring(&m, password); 359545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHPASSWORD, &m); 360545d5ecaSDag-Erling Smørgrav 361545d5ecaSDag-Erling Smørgrav debug3("%s: waiting for MONITOR_ANS_AUTHPASSWORD", __func__); 362545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUTHPASSWORD, &m); 363545d5ecaSDag-Erling Smørgrav 364545d5ecaSDag-Erling Smørgrav authenticated = buffer_get_int(&m); 365545d5ecaSDag-Erling Smørgrav 366545d5ecaSDag-Erling Smørgrav buffer_free(&m); 367545d5ecaSDag-Erling Smørgrav 368545d5ecaSDag-Erling Smørgrav debug3("%s: user %sauthenticated", 369545d5ecaSDag-Erling Smørgrav __func__, authenticated ? "" : "not "); 370545d5ecaSDag-Erling Smørgrav return (authenticated); 371545d5ecaSDag-Erling Smørgrav } 372545d5ecaSDag-Erling Smørgrav 373545d5ecaSDag-Erling Smørgrav int 374*557f75e5SDag-Erling Smørgrav mm_user_key_allowed(struct passwd *pw, Key *key, int pubkey_auth_attempt) 375545d5ecaSDag-Erling Smørgrav { 376*557f75e5SDag-Erling Smørgrav return (mm_key_allowed(MM_USERKEY, NULL, NULL, key, 377*557f75e5SDag-Erling Smørgrav pubkey_auth_attempt)); 378545d5ecaSDag-Erling Smørgrav } 379545d5ecaSDag-Erling Smørgrav 380545d5ecaSDag-Erling Smørgrav int 381545d5ecaSDag-Erling Smørgrav mm_hostbased_key_allowed(struct passwd *pw, char *user, char *host, 382545d5ecaSDag-Erling Smørgrav Key *key) 383545d5ecaSDag-Erling Smørgrav { 384*557f75e5SDag-Erling Smørgrav return (mm_key_allowed(MM_HOSTKEY, user, host, key, 0)); 385545d5ecaSDag-Erling Smørgrav } 386545d5ecaSDag-Erling Smørgrav 387545d5ecaSDag-Erling Smørgrav int 388545d5ecaSDag-Erling Smørgrav mm_auth_rhosts_rsa_key_allowed(struct passwd *pw, char *user, 389545d5ecaSDag-Erling Smørgrav char *host, Key *key) 390545d5ecaSDag-Erling Smørgrav { 391545d5ecaSDag-Erling Smørgrav int ret; 392545d5ecaSDag-Erling Smørgrav 393545d5ecaSDag-Erling Smørgrav key->type = KEY_RSA; /* XXX hack for key_to_blob */ 394*557f75e5SDag-Erling Smørgrav ret = mm_key_allowed(MM_RSAHOSTKEY, user, host, key, 0); 395545d5ecaSDag-Erling Smørgrav key->type = KEY_RSA1; 396545d5ecaSDag-Erling Smørgrav return (ret); 397545d5ecaSDag-Erling Smørgrav } 398545d5ecaSDag-Erling Smørgrav 399545d5ecaSDag-Erling Smørgrav int 400*557f75e5SDag-Erling Smørgrav mm_key_allowed(enum mm_keytype type, char *user, char *host, Key *key, 401*557f75e5SDag-Erling Smørgrav int pubkey_auth_attempt) 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); 419*557f75e5SDag-Erling Smørgrav buffer_put_int(&m, pubkey_auth_attempt); 420e4a9863fSDag-Erling Smørgrav free(blob); 421545d5ecaSDag-Erling Smørgrav 422545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYALLOWED, &m); 423545d5ecaSDag-Erling Smørgrav 424545d5ecaSDag-Erling Smørgrav debug3("%s: waiting for MONITOR_ANS_KEYALLOWED", __func__); 425545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYALLOWED, &m); 426545d5ecaSDag-Erling Smørgrav 427545d5ecaSDag-Erling Smørgrav allowed = buffer_get_int(&m); 428545d5ecaSDag-Erling Smørgrav 429e73e9afaSDag-Erling Smørgrav /* fake forced command */ 430e73e9afaSDag-Erling Smørgrav auth_clear_options(); 431e73e9afaSDag-Erling Smørgrav have_forced = buffer_get_int(&m); 432e73e9afaSDag-Erling Smørgrav forced_command = have_forced ? xstrdup("true") : NULL; 433e73e9afaSDag-Erling Smørgrav 434545d5ecaSDag-Erling Smørgrav buffer_free(&m); 435545d5ecaSDag-Erling Smørgrav 436545d5ecaSDag-Erling Smørgrav return (allowed); 437545d5ecaSDag-Erling Smørgrav } 438545d5ecaSDag-Erling Smørgrav 439545d5ecaSDag-Erling Smørgrav /* 440545d5ecaSDag-Erling Smørgrav * This key verify needs to send the key type along, because the 441545d5ecaSDag-Erling Smørgrav * privileged parent makes the decision if the key is allowed 442545d5ecaSDag-Erling Smørgrav * for authentication. 443545d5ecaSDag-Erling Smørgrav */ 444545d5ecaSDag-Erling Smørgrav 445545d5ecaSDag-Erling Smørgrav int 446545d5ecaSDag-Erling Smørgrav mm_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen) 447545d5ecaSDag-Erling Smørgrav { 448545d5ecaSDag-Erling Smørgrav Buffer m; 449545d5ecaSDag-Erling Smørgrav u_char *blob; 450545d5ecaSDag-Erling Smørgrav u_int len; 451545d5ecaSDag-Erling Smørgrav int verified = 0; 452545d5ecaSDag-Erling Smørgrav 453545d5ecaSDag-Erling Smørgrav debug3("%s entering", __func__); 454545d5ecaSDag-Erling Smørgrav 455545d5ecaSDag-Erling Smørgrav /* Convert the key to a blob and the pass it over */ 456545d5ecaSDag-Erling Smørgrav if (!key_to_blob(key, &blob, &len)) 457545d5ecaSDag-Erling Smørgrav return (0); 458545d5ecaSDag-Erling Smørgrav 459545d5ecaSDag-Erling Smørgrav buffer_init(&m); 460545d5ecaSDag-Erling Smørgrav buffer_put_string(&m, blob, len); 461545d5ecaSDag-Erling Smørgrav buffer_put_string(&m, sig, siglen); 462545d5ecaSDag-Erling Smørgrav buffer_put_string(&m, data, datalen); 463e4a9863fSDag-Erling Smørgrav free(blob); 464545d5ecaSDag-Erling Smørgrav 465545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYVERIFY, &m); 466545d5ecaSDag-Erling Smørgrav 467545d5ecaSDag-Erling Smørgrav debug3("%s: waiting for MONITOR_ANS_KEYVERIFY", __func__); 468545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYVERIFY, &m); 469545d5ecaSDag-Erling Smørgrav 470545d5ecaSDag-Erling Smørgrav verified = buffer_get_int(&m); 471545d5ecaSDag-Erling Smørgrav 472545d5ecaSDag-Erling Smørgrav buffer_free(&m); 473545d5ecaSDag-Erling Smørgrav 474545d5ecaSDag-Erling Smørgrav return (verified); 475545d5ecaSDag-Erling Smørgrav } 476545d5ecaSDag-Erling Smørgrav 477545d5ecaSDag-Erling Smørgrav void 47821e764dfSDag-Erling Smørgrav mm_send_keystate(struct monitor *monitor) 479545d5ecaSDag-Erling Smørgrav { 480bc5531deSDag-Erling Smørgrav struct ssh *ssh = active_state; /* XXX */ 481bc5531deSDag-Erling Smørgrav struct sshbuf *m; 482bc5531deSDag-Erling Smørgrav int r; 483545d5ecaSDag-Erling Smørgrav 484bc5531deSDag-Erling Smørgrav if ((m = sshbuf_new()) == NULL) 485bc5531deSDag-Erling Smørgrav fatal("%s: sshbuf_new failed", __func__); 486bc5531deSDag-Erling Smørgrav if ((r = ssh_packet_get_state(ssh, m)) != 0) 487bc5531deSDag-Erling Smørgrav fatal("%s: get_state failed: %s", 488bc5531deSDag-Erling Smørgrav __func__, ssh_err(r)); 489bc5531deSDag-Erling Smørgrav mm_request_send(monitor->m_recvfd, MONITOR_REQ_KEYEXPORT, m); 490545d5ecaSDag-Erling Smørgrav debug3("%s: Finished sending state", __func__); 491bc5531deSDag-Erling Smørgrav sshbuf_free(m); 492545d5ecaSDag-Erling Smørgrav } 493545d5ecaSDag-Erling Smørgrav 494545d5ecaSDag-Erling Smørgrav int 495333ee039SDag-Erling Smørgrav mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen) 496545d5ecaSDag-Erling Smørgrav { 497545d5ecaSDag-Erling Smørgrav Buffer m; 49821e764dfSDag-Erling Smørgrav char *p, *msg; 499d4af9e69SDag-Erling Smørgrav int success = 0, tmp1 = -1, tmp2 = -1; 500d4af9e69SDag-Erling Smørgrav 501d4af9e69SDag-Erling Smørgrav /* Kludge: ensure there are fds free to receive the pty/tty */ 502d4af9e69SDag-Erling Smørgrav if ((tmp1 = dup(pmonitor->m_recvfd)) == -1 || 503d4af9e69SDag-Erling Smørgrav (tmp2 = dup(pmonitor->m_recvfd)) == -1) { 504d4af9e69SDag-Erling Smørgrav error("%s: cannot allocate fds for pty", __func__); 505d4af9e69SDag-Erling Smørgrav if (tmp1 > 0) 506d4af9e69SDag-Erling Smørgrav close(tmp1); 507d4af9e69SDag-Erling Smørgrav if (tmp2 > 0) 508d4af9e69SDag-Erling Smørgrav close(tmp2); 509d4af9e69SDag-Erling Smørgrav return 0; 510d4af9e69SDag-Erling Smørgrav } 511d4af9e69SDag-Erling Smørgrav close(tmp1); 512d4af9e69SDag-Erling Smørgrav close(tmp2); 513545d5ecaSDag-Erling Smørgrav 514545d5ecaSDag-Erling Smørgrav buffer_init(&m); 515545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTY, &m); 516545d5ecaSDag-Erling Smørgrav 517545d5ecaSDag-Erling Smørgrav debug3("%s: waiting for MONITOR_ANS_PTY", __func__); 518545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PTY, &m); 519545d5ecaSDag-Erling Smørgrav 520545d5ecaSDag-Erling Smørgrav success = buffer_get_int(&m); 521545d5ecaSDag-Erling Smørgrav if (success == 0) { 522545d5ecaSDag-Erling Smørgrav debug3("%s: pty alloc failed", __func__); 523545d5ecaSDag-Erling Smørgrav buffer_free(&m); 524545d5ecaSDag-Erling Smørgrav return (0); 525545d5ecaSDag-Erling Smørgrav } 526545d5ecaSDag-Erling Smørgrav p = buffer_get_string(&m, NULL); 52721e764dfSDag-Erling Smørgrav msg = buffer_get_string(&m, NULL); 528545d5ecaSDag-Erling Smørgrav buffer_free(&m); 529545d5ecaSDag-Erling Smørgrav 530545d5ecaSDag-Erling Smørgrav strlcpy(namebuf, p, namebuflen); /* Possible truncation */ 531e4a9863fSDag-Erling Smørgrav free(p); 532545d5ecaSDag-Erling Smørgrav 53321e764dfSDag-Erling Smørgrav buffer_append(&loginmsg, msg, strlen(msg)); 534e4a9863fSDag-Erling Smørgrav free(msg); 53521e764dfSDag-Erling Smørgrav 536d4af9e69SDag-Erling Smørgrav if ((*ptyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1 || 537d4af9e69SDag-Erling Smørgrav (*ttyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1) 538d4af9e69SDag-Erling Smørgrav fatal("%s: receive fds failed", __func__); 539545d5ecaSDag-Erling Smørgrav 540545d5ecaSDag-Erling Smørgrav /* Success */ 541545d5ecaSDag-Erling Smørgrav return (1); 542545d5ecaSDag-Erling Smørgrav } 543545d5ecaSDag-Erling Smørgrav 544545d5ecaSDag-Erling Smørgrav void 5451ec0d754SDag-Erling Smørgrav mm_session_pty_cleanup2(Session *s) 546545d5ecaSDag-Erling Smørgrav { 547545d5ecaSDag-Erling Smørgrav Buffer m; 548545d5ecaSDag-Erling Smørgrav 549545d5ecaSDag-Erling Smørgrav if (s->ttyfd == -1) 550545d5ecaSDag-Erling Smørgrav return; 551545d5ecaSDag-Erling Smørgrav buffer_init(&m); 552545d5ecaSDag-Erling Smørgrav buffer_put_cstring(&m, s->tty); 553545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTYCLEANUP, &m); 554545d5ecaSDag-Erling Smørgrav buffer_free(&m); 555545d5ecaSDag-Erling Smørgrav 556545d5ecaSDag-Erling Smørgrav /* closed dup'ed master */ 557d4af9e69SDag-Erling Smørgrav if (s->ptymaster != -1 && close(s->ptymaster) < 0) 558d4af9e69SDag-Erling Smørgrav error("close(s->ptymaster/%d): %s", 559d4af9e69SDag-Erling Smørgrav s->ptymaster, strerror(errno)); 560545d5ecaSDag-Erling Smørgrav 561545d5ecaSDag-Erling Smørgrav /* unlink pty from session */ 562545d5ecaSDag-Erling Smørgrav s->ttyfd = -1; 563545d5ecaSDag-Erling Smørgrav } 564545d5ecaSDag-Erling Smørgrav 56583d2307dSDag-Erling Smørgrav #ifdef USE_PAM 56683d2307dSDag-Erling Smørgrav void 5675962c0e9SDag-Erling Smørgrav mm_start_pam(Authctxt *authctxt) 56883d2307dSDag-Erling Smørgrav { 56983d2307dSDag-Erling Smørgrav Buffer m; 57083d2307dSDag-Erling Smørgrav 57183d2307dSDag-Erling Smørgrav debug3("%s entering", __func__); 572cf2b5f3bSDag-Erling Smørgrav if (!options.use_pam) 573cf2b5f3bSDag-Erling Smørgrav fatal("UsePAM=no, but ended up in %s anyway", __func__); 57483d2307dSDag-Erling Smørgrav 57583d2307dSDag-Erling Smørgrav buffer_init(&m); 57683d2307dSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_START, &m); 57783d2307dSDag-Erling Smørgrav 57883d2307dSDag-Erling Smørgrav buffer_free(&m); 57983d2307dSDag-Erling Smørgrav } 580382d19eeSDag-Erling Smørgrav 581cf2b5f3bSDag-Erling Smørgrav u_int 582cf2b5f3bSDag-Erling Smørgrav mm_do_pam_account(void) 583cf2b5f3bSDag-Erling Smørgrav { 584cf2b5f3bSDag-Erling Smørgrav Buffer m; 585cf2b5f3bSDag-Erling Smørgrav u_int ret; 586aa49c926SDag-Erling Smørgrav char *msg; 587cf2b5f3bSDag-Erling Smørgrav 588cf2b5f3bSDag-Erling Smørgrav debug3("%s entering", __func__); 589cf2b5f3bSDag-Erling Smørgrav if (!options.use_pam) 590cf2b5f3bSDag-Erling Smørgrav fatal("UsePAM=no, but ended up in %s anyway", __func__); 591cf2b5f3bSDag-Erling Smørgrav 592cf2b5f3bSDag-Erling Smørgrav buffer_init(&m); 593cf2b5f3bSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_ACCOUNT, &m); 594cf2b5f3bSDag-Erling Smørgrav 595cf2b5f3bSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, 596cf2b5f3bSDag-Erling Smørgrav MONITOR_ANS_PAM_ACCOUNT, &m); 597cf2b5f3bSDag-Erling Smørgrav ret = buffer_get_int(&m); 598aa49c926SDag-Erling Smørgrav msg = buffer_get_string(&m, NULL); 599aa49c926SDag-Erling Smørgrav buffer_append(&loginmsg, msg, strlen(msg)); 600e4a9863fSDag-Erling Smørgrav free(msg); 601cf2b5f3bSDag-Erling Smørgrav 602cf2b5f3bSDag-Erling Smørgrav buffer_free(&m); 603cf2b5f3bSDag-Erling Smørgrav 604cf2b5f3bSDag-Erling Smørgrav debug3("%s returning %d", __func__, ret); 605cf2b5f3bSDag-Erling Smørgrav 606cf2b5f3bSDag-Erling Smørgrav return (ret); 607cf2b5f3bSDag-Erling Smørgrav } 608cf2b5f3bSDag-Erling Smørgrav 609382d19eeSDag-Erling Smørgrav void * 610cf2b5f3bSDag-Erling Smørgrav mm_sshpam_init_ctx(Authctxt *authctxt) 611382d19eeSDag-Erling Smørgrav { 612382d19eeSDag-Erling Smørgrav Buffer m; 613382d19eeSDag-Erling Smørgrav int success; 614382d19eeSDag-Erling Smørgrav 615382d19eeSDag-Erling Smørgrav debug3("%s", __func__); 616382d19eeSDag-Erling Smørgrav buffer_init(&m); 617382d19eeSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_INIT_CTX, &m); 618382d19eeSDag-Erling Smørgrav debug3("%s: waiting for MONITOR_ANS_PAM_INIT_CTX", __func__); 619382d19eeSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_INIT_CTX, &m); 620382d19eeSDag-Erling Smørgrav success = buffer_get_int(&m); 621382d19eeSDag-Erling Smørgrav if (success == 0) { 622382d19eeSDag-Erling Smørgrav debug3("%s: pam_init_ctx failed", __func__); 623382d19eeSDag-Erling Smørgrav buffer_free(&m); 624382d19eeSDag-Erling Smørgrav return (NULL); 625382d19eeSDag-Erling Smørgrav } 626382d19eeSDag-Erling Smørgrav buffer_free(&m); 627382d19eeSDag-Erling Smørgrav return (authctxt); 628382d19eeSDag-Erling Smørgrav } 629382d19eeSDag-Erling Smørgrav 630382d19eeSDag-Erling Smørgrav int 631cf2b5f3bSDag-Erling Smørgrav mm_sshpam_query(void *ctx, char **name, char **info, 632382d19eeSDag-Erling Smørgrav u_int *num, char ***prompts, u_int **echo_on) 633382d19eeSDag-Erling Smørgrav { 634382d19eeSDag-Erling Smørgrav Buffer m; 635d4ecd108SDag-Erling Smørgrav u_int i; 636d4ecd108SDag-Erling Smørgrav int ret; 637382d19eeSDag-Erling Smørgrav 638382d19eeSDag-Erling Smørgrav debug3("%s", __func__); 639382d19eeSDag-Erling Smørgrav buffer_init(&m); 640382d19eeSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_QUERY, &m); 641382d19eeSDag-Erling Smørgrav debug3("%s: waiting for MONITOR_ANS_PAM_QUERY", __func__); 642382d19eeSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_QUERY, &m); 643382d19eeSDag-Erling Smørgrav ret = buffer_get_int(&m); 644382d19eeSDag-Erling Smørgrav debug3("%s: pam_query returned %d", __func__, ret); 645382d19eeSDag-Erling Smørgrav *name = buffer_get_string(&m, NULL); 646382d19eeSDag-Erling Smørgrav *info = buffer_get_string(&m, NULL); 647382d19eeSDag-Erling Smørgrav *num = buffer_get_int(&m); 648333ee039SDag-Erling Smørgrav if (*num > PAM_MAX_NUM_MSG) 649333ee039SDag-Erling Smørgrav fatal("%s: recieved %u PAM messages, expected <= %u", 650333ee039SDag-Erling Smørgrav __func__, *num, PAM_MAX_NUM_MSG); 651333ee039SDag-Erling Smørgrav *prompts = xcalloc((*num + 1), sizeof(char *)); 652333ee039SDag-Erling Smørgrav *echo_on = xcalloc((*num + 1), sizeof(u_int)); 653382d19eeSDag-Erling Smørgrav for (i = 0; i < *num; ++i) { 654382d19eeSDag-Erling Smørgrav (*prompts)[i] = buffer_get_string(&m, NULL); 655382d19eeSDag-Erling Smørgrav (*echo_on)[i] = buffer_get_int(&m); 656382d19eeSDag-Erling Smørgrav } 657382d19eeSDag-Erling Smørgrav buffer_free(&m); 658382d19eeSDag-Erling Smørgrav return (ret); 659382d19eeSDag-Erling Smørgrav } 660382d19eeSDag-Erling Smørgrav 661382d19eeSDag-Erling Smørgrav int 662cf2b5f3bSDag-Erling Smørgrav mm_sshpam_respond(void *ctx, u_int num, char **resp) 663382d19eeSDag-Erling Smørgrav { 664382d19eeSDag-Erling Smørgrav Buffer m; 665d4ecd108SDag-Erling Smørgrav u_int i; 666d4ecd108SDag-Erling Smørgrav int ret; 667382d19eeSDag-Erling Smørgrav 668382d19eeSDag-Erling Smørgrav debug3("%s", __func__); 669382d19eeSDag-Erling Smørgrav buffer_init(&m); 670382d19eeSDag-Erling Smørgrav buffer_put_int(&m, num); 671382d19eeSDag-Erling Smørgrav for (i = 0; i < num; ++i) 672382d19eeSDag-Erling Smørgrav buffer_put_cstring(&m, resp[i]); 673382d19eeSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_RESPOND, &m); 674382d19eeSDag-Erling Smørgrav debug3("%s: waiting for MONITOR_ANS_PAM_RESPOND", __func__); 675382d19eeSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_RESPOND, &m); 676382d19eeSDag-Erling Smørgrav ret = buffer_get_int(&m); 677382d19eeSDag-Erling Smørgrav debug3("%s: pam_respond returned %d", __func__, ret); 678382d19eeSDag-Erling Smørgrav buffer_free(&m); 679382d19eeSDag-Erling Smørgrav return (ret); 680382d19eeSDag-Erling Smørgrav } 681382d19eeSDag-Erling Smørgrav 682382d19eeSDag-Erling Smørgrav void 683cf2b5f3bSDag-Erling Smørgrav mm_sshpam_free_ctx(void *ctxtp) 684382d19eeSDag-Erling Smørgrav { 685382d19eeSDag-Erling Smørgrav Buffer m; 686382d19eeSDag-Erling Smørgrav 687382d19eeSDag-Erling Smørgrav debug3("%s", __func__); 688382d19eeSDag-Erling Smørgrav buffer_init(&m); 689382d19eeSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_FREE_CTX, &m); 690382d19eeSDag-Erling Smørgrav debug3("%s: waiting for MONITOR_ANS_PAM_FREE_CTX", __func__); 691382d19eeSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_FREE_CTX, &m); 692382d19eeSDag-Erling Smørgrav buffer_free(&m); 693382d19eeSDag-Erling Smørgrav } 69483d2307dSDag-Erling Smørgrav #endif /* USE_PAM */ 69583d2307dSDag-Erling Smørgrav 696545d5ecaSDag-Erling Smørgrav /* Request process termination */ 697545d5ecaSDag-Erling Smørgrav 698545d5ecaSDag-Erling Smørgrav void 699545d5ecaSDag-Erling Smørgrav mm_terminate(void) 700545d5ecaSDag-Erling Smørgrav { 701545d5ecaSDag-Erling Smørgrav Buffer m; 702545d5ecaSDag-Erling Smørgrav 703545d5ecaSDag-Erling Smørgrav buffer_init(&m); 704545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_TERM, &m); 705545d5ecaSDag-Erling Smørgrav buffer_free(&m); 706545d5ecaSDag-Erling Smørgrav } 707545d5ecaSDag-Erling Smørgrav 708a0ee8cc6SDag-Erling Smørgrav #ifdef WITH_SSH1 709545d5ecaSDag-Erling Smørgrav int 710545d5ecaSDag-Erling Smørgrav mm_ssh1_session_key(BIGNUM *num) 711545d5ecaSDag-Erling Smørgrav { 712545d5ecaSDag-Erling Smørgrav int rsafail; 713545d5ecaSDag-Erling Smørgrav Buffer m; 714545d5ecaSDag-Erling Smørgrav 715545d5ecaSDag-Erling Smørgrav buffer_init(&m); 716545d5ecaSDag-Erling Smørgrav buffer_put_bignum2(&m, num); 717545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SESSKEY, &m); 718545d5ecaSDag-Erling Smørgrav 719545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SESSKEY, &m); 720545d5ecaSDag-Erling Smørgrav 721545d5ecaSDag-Erling Smørgrav rsafail = buffer_get_int(&m); 722545d5ecaSDag-Erling Smørgrav buffer_get_bignum2(&m, num); 723545d5ecaSDag-Erling Smørgrav 724545d5ecaSDag-Erling Smørgrav buffer_free(&m); 725545d5ecaSDag-Erling Smørgrav 726545d5ecaSDag-Erling Smørgrav return (rsafail); 727545d5ecaSDag-Erling Smørgrav } 728a0ee8cc6SDag-Erling Smørgrav #endif 729545d5ecaSDag-Erling Smørgrav 730545d5ecaSDag-Erling Smørgrav static void 731545d5ecaSDag-Erling Smørgrav mm_chall_setup(char **name, char **infotxt, u_int *numprompts, 732545d5ecaSDag-Erling Smørgrav char ***prompts, u_int **echo_on) 733545d5ecaSDag-Erling Smørgrav { 734545d5ecaSDag-Erling Smørgrav *name = xstrdup(""); 735545d5ecaSDag-Erling Smørgrav *infotxt = xstrdup(""); 736545d5ecaSDag-Erling Smørgrav *numprompts = 1; 737333ee039SDag-Erling Smørgrav *prompts = xcalloc(*numprompts, sizeof(char *)); 738333ee039SDag-Erling Smørgrav *echo_on = xcalloc(*numprompts, sizeof(u_int)); 739545d5ecaSDag-Erling Smørgrav (*echo_on)[0] = 0; 740545d5ecaSDag-Erling Smørgrav } 741545d5ecaSDag-Erling Smørgrav 742545d5ecaSDag-Erling Smørgrav int 743545d5ecaSDag-Erling Smørgrav mm_bsdauth_query(void *ctx, char **name, char **infotxt, 744545d5ecaSDag-Erling Smørgrav u_int *numprompts, char ***prompts, u_int **echo_on) 745545d5ecaSDag-Erling Smørgrav { 746545d5ecaSDag-Erling Smørgrav Buffer m; 747e73e9afaSDag-Erling Smørgrav u_int success; 748545d5ecaSDag-Erling Smørgrav char *challenge; 749545d5ecaSDag-Erling Smørgrav 750545d5ecaSDag-Erling Smørgrav debug3("%s: entering", __func__); 751545d5ecaSDag-Erling Smørgrav 752545d5ecaSDag-Erling Smørgrav buffer_init(&m); 753545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHQUERY, &m); 754545d5ecaSDag-Erling Smørgrav 755545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_BSDAUTHQUERY, 756545d5ecaSDag-Erling Smørgrav &m); 757e73e9afaSDag-Erling Smørgrav success = buffer_get_int(&m); 758e73e9afaSDag-Erling Smørgrav if (success == 0) { 759545d5ecaSDag-Erling Smørgrav debug3("%s: no challenge", __func__); 760545d5ecaSDag-Erling Smørgrav buffer_free(&m); 761545d5ecaSDag-Erling Smørgrav return (-1); 762545d5ecaSDag-Erling Smørgrav } 763545d5ecaSDag-Erling Smørgrav 764545d5ecaSDag-Erling Smørgrav /* Get the challenge, and format the response */ 765545d5ecaSDag-Erling Smørgrav challenge = buffer_get_string(&m, NULL); 766545d5ecaSDag-Erling Smørgrav buffer_free(&m); 767545d5ecaSDag-Erling Smørgrav 768545d5ecaSDag-Erling Smørgrav mm_chall_setup(name, infotxt, numprompts, prompts, echo_on); 769545d5ecaSDag-Erling Smørgrav (*prompts)[0] = challenge; 770545d5ecaSDag-Erling Smørgrav 771545d5ecaSDag-Erling Smørgrav debug3("%s: received challenge: %s", __func__, challenge); 772545d5ecaSDag-Erling Smørgrav 773545d5ecaSDag-Erling Smørgrav return (0); 774545d5ecaSDag-Erling Smørgrav } 775545d5ecaSDag-Erling Smørgrav 776545d5ecaSDag-Erling Smørgrav int 777545d5ecaSDag-Erling Smørgrav mm_bsdauth_respond(void *ctx, u_int numresponses, char **responses) 778545d5ecaSDag-Erling Smørgrav { 779545d5ecaSDag-Erling Smørgrav Buffer m; 780545d5ecaSDag-Erling Smørgrav int authok; 781545d5ecaSDag-Erling Smørgrav 782545d5ecaSDag-Erling Smørgrav debug3("%s: entering", __func__); 783545d5ecaSDag-Erling Smørgrav if (numresponses != 1) 784545d5ecaSDag-Erling Smørgrav return (-1); 785545d5ecaSDag-Erling Smørgrav 786545d5ecaSDag-Erling Smørgrav buffer_init(&m); 787545d5ecaSDag-Erling Smørgrav buffer_put_cstring(&m, responses[0]); 788545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHRESPOND, &m); 789545d5ecaSDag-Erling Smørgrav 790545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, 791545d5ecaSDag-Erling Smørgrav MONITOR_ANS_BSDAUTHRESPOND, &m); 792545d5ecaSDag-Erling Smørgrav 793545d5ecaSDag-Erling Smørgrav authok = buffer_get_int(&m); 794545d5ecaSDag-Erling Smørgrav buffer_free(&m); 795545d5ecaSDag-Erling Smørgrav 796545d5ecaSDag-Erling Smørgrav return ((authok == 0) ? -1 : 0); 797545d5ecaSDag-Erling Smørgrav } 798545d5ecaSDag-Erling Smørgrav 799edb557f8SDag-Erling Smørgrav #ifdef SKEY 800545d5ecaSDag-Erling Smørgrav int 801545d5ecaSDag-Erling Smørgrav mm_skey_query(void *ctx, char **name, char **infotxt, 802545d5ecaSDag-Erling Smørgrav u_int *numprompts, char ***prompts, u_int **echo_on) 803545d5ecaSDag-Erling Smørgrav { 804545d5ecaSDag-Erling Smørgrav Buffer m; 805e73e9afaSDag-Erling Smørgrav u_int success; 806333ee039SDag-Erling Smørgrav char *challenge; 807545d5ecaSDag-Erling Smørgrav 808545d5ecaSDag-Erling Smørgrav debug3("%s: entering", __func__); 809545d5ecaSDag-Erling Smørgrav 810545d5ecaSDag-Erling Smørgrav buffer_init(&m); 811545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SKEYQUERY, &m); 812545d5ecaSDag-Erling Smørgrav 813545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SKEYQUERY, 814545d5ecaSDag-Erling Smørgrav &m); 815e73e9afaSDag-Erling Smørgrav success = buffer_get_int(&m); 816e73e9afaSDag-Erling Smørgrav if (success == 0) { 817545d5ecaSDag-Erling Smørgrav debug3("%s: no challenge", __func__); 818545d5ecaSDag-Erling Smørgrav buffer_free(&m); 819545d5ecaSDag-Erling Smørgrav return (-1); 820545d5ecaSDag-Erling Smørgrav } 821545d5ecaSDag-Erling Smørgrav 822545d5ecaSDag-Erling Smørgrav /* Get the challenge, and format the response */ 823545d5ecaSDag-Erling Smørgrav challenge = buffer_get_string(&m, NULL); 824545d5ecaSDag-Erling Smørgrav buffer_free(&m); 825545d5ecaSDag-Erling Smørgrav 826545d5ecaSDag-Erling Smørgrav debug3("%s: received challenge: %s", __func__, challenge); 827545d5ecaSDag-Erling Smørgrav 828545d5ecaSDag-Erling Smørgrav mm_chall_setup(name, infotxt, numprompts, prompts, echo_on); 829545d5ecaSDag-Erling Smørgrav 830333ee039SDag-Erling Smørgrav xasprintf(*prompts, "%s%s", challenge, SKEY_PROMPT); 831e4a9863fSDag-Erling Smørgrav free(challenge); 832545d5ecaSDag-Erling Smørgrav 833545d5ecaSDag-Erling Smørgrav return (0); 834545d5ecaSDag-Erling Smørgrav } 835545d5ecaSDag-Erling Smørgrav 836545d5ecaSDag-Erling Smørgrav int 837545d5ecaSDag-Erling Smørgrav mm_skey_respond(void *ctx, u_int numresponses, char **responses) 838545d5ecaSDag-Erling Smørgrav { 839545d5ecaSDag-Erling Smørgrav Buffer m; 840545d5ecaSDag-Erling Smørgrav int authok; 841545d5ecaSDag-Erling Smørgrav 842545d5ecaSDag-Erling Smørgrav debug3("%s: entering", __func__); 843545d5ecaSDag-Erling Smørgrav if (numresponses != 1) 844545d5ecaSDag-Erling Smørgrav return (-1); 845545d5ecaSDag-Erling Smørgrav 846545d5ecaSDag-Erling Smørgrav buffer_init(&m); 847545d5ecaSDag-Erling Smørgrav buffer_put_cstring(&m, responses[0]); 848545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SKEYRESPOND, &m); 849545d5ecaSDag-Erling Smørgrav 850545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, 851545d5ecaSDag-Erling Smørgrav MONITOR_ANS_SKEYRESPOND, &m); 852545d5ecaSDag-Erling Smørgrav 853545d5ecaSDag-Erling Smørgrav authok = buffer_get_int(&m); 854545d5ecaSDag-Erling Smørgrav buffer_free(&m); 855545d5ecaSDag-Erling Smørgrav 856545d5ecaSDag-Erling Smørgrav return ((authok == 0) ? -1 : 0); 857545d5ecaSDag-Erling Smørgrav } 85821e764dfSDag-Erling Smørgrav #endif /* SKEY */ 859545d5ecaSDag-Erling Smørgrav 860545d5ecaSDag-Erling Smørgrav void 861545d5ecaSDag-Erling Smørgrav mm_ssh1_session_id(u_char session_id[16]) 862545d5ecaSDag-Erling Smørgrav { 863545d5ecaSDag-Erling Smørgrav Buffer m; 864545d5ecaSDag-Erling Smørgrav int i; 865545d5ecaSDag-Erling Smørgrav 866545d5ecaSDag-Erling Smørgrav debug3("%s entering", __func__); 867545d5ecaSDag-Erling Smørgrav 868545d5ecaSDag-Erling Smørgrav buffer_init(&m); 869545d5ecaSDag-Erling Smørgrav for (i = 0; i < 16; i++) 870545d5ecaSDag-Erling Smørgrav buffer_put_char(&m, session_id[i]); 871545d5ecaSDag-Erling Smørgrav 872545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SESSID, &m); 873545d5ecaSDag-Erling Smørgrav buffer_free(&m); 874545d5ecaSDag-Erling Smørgrav } 875545d5ecaSDag-Erling Smørgrav 876a0ee8cc6SDag-Erling Smørgrav #ifdef WITH_SSH1 877545d5ecaSDag-Erling Smørgrav int 878545d5ecaSDag-Erling Smørgrav mm_auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey) 879545d5ecaSDag-Erling Smørgrav { 880545d5ecaSDag-Erling Smørgrav Buffer m; 881545d5ecaSDag-Erling Smørgrav Key *key; 882545d5ecaSDag-Erling Smørgrav u_char *blob; 883545d5ecaSDag-Erling Smørgrav u_int blen; 884e73e9afaSDag-Erling Smørgrav int allowed = 0, have_forced = 0; 885545d5ecaSDag-Erling Smørgrav 886545d5ecaSDag-Erling Smørgrav debug3("%s entering", __func__); 887545d5ecaSDag-Erling Smørgrav 888545d5ecaSDag-Erling Smørgrav buffer_init(&m); 889545d5ecaSDag-Erling Smørgrav buffer_put_bignum2(&m, client_n); 890545d5ecaSDag-Erling Smørgrav 891545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSAKEYALLOWED, &m); 892545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSAKEYALLOWED, &m); 893545d5ecaSDag-Erling Smørgrav 894545d5ecaSDag-Erling Smørgrav allowed = buffer_get_int(&m); 895545d5ecaSDag-Erling Smørgrav 896e73e9afaSDag-Erling Smørgrav /* fake forced command */ 897e73e9afaSDag-Erling Smørgrav auth_clear_options(); 898e73e9afaSDag-Erling Smørgrav have_forced = buffer_get_int(&m); 899e73e9afaSDag-Erling Smørgrav forced_command = have_forced ? xstrdup("true") : NULL; 900e73e9afaSDag-Erling Smørgrav 901545d5ecaSDag-Erling Smørgrav if (allowed && rkey != NULL) { 902545d5ecaSDag-Erling Smørgrav blob = buffer_get_string(&m, &blen); 903545d5ecaSDag-Erling Smørgrav if ((key = key_from_blob(blob, blen)) == NULL) 904545d5ecaSDag-Erling Smørgrav fatal("%s: key_from_blob failed", __func__); 905545d5ecaSDag-Erling Smørgrav *rkey = key; 906e4a9863fSDag-Erling Smørgrav free(blob); 907545d5ecaSDag-Erling Smørgrav } 908545d5ecaSDag-Erling Smørgrav buffer_free(&m); 909545d5ecaSDag-Erling Smørgrav 910545d5ecaSDag-Erling Smørgrav return (allowed); 911545d5ecaSDag-Erling Smørgrav } 912545d5ecaSDag-Erling Smørgrav 913545d5ecaSDag-Erling Smørgrav BIGNUM * 914545d5ecaSDag-Erling Smørgrav mm_auth_rsa_generate_challenge(Key *key) 915545d5ecaSDag-Erling Smørgrav { 916545d5ecaSDag-Erling Smørgrav Buffer m; 917545d5ecaSDag-Erling Smørgrav BIGNUM *challenge; 918545d5ecaSDag-Erling Smørgrav u_char *blob; 919545d5ecaSDag-Erling Smørgrav u_int blen; 920545d5ecaSDag-Erling Smørgrav 921545d5ecaSDag-Erling Smørgrav debug3("%s entering", __func__); 922545d5ecaSDag-Erling Smørgrav 923545d5ecaSDag-Erling Smørgrav if ((challenge = BN_new()) == NULL) 924545d5ecaSDag-Erling Smørgrav fatal("%s: BN_new failed", __func__); 925545d5ecaSDag-Erling Smørgrav 926545d5ecaSDag-Erling Smørgrav key->type = KEY_RSA; /* XXX cheat for key_to_blob */ 927545d5ecaSDag-Erling Smørgrav if (key_to_blob(key, &blob, &blen) == 0) 928545d5ecaSDag-Erling Smørgrav fatal("%s: key_to_blob failed", __func__); 929545d5ecaSDag-Erling Smørgrav key->type = KEY_RSA1; 930545d5ecaSDag-Erling Smørgrav 931545d5ecaSDag-Erling Smørgrav buffer_init(&m); 932545d5ecaSDag-Erling Smørgrav buffer_put_string(&m, blob, blen); 933e4a9863fSDag-Erling Smørgrav free(blob); 934545d5ecaSDag-Erling Smørgrav 935545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSACHALLENGE, &m); 936545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSACHALLENGE, &m); 937545d5ecaSDag-Erling Smørgrav 938545d5ecaSDag-Erling Smørgrav buffer_get_bignum2(&m, challenge); 939545d5ecaSDag-Erling Smørgrav buffer_free(&m); 940545d5ecaSDag-Erling Smørgrav 941545d5ecaSDag-Erling Smørgrav return (challenge); 942545d5ecaSDag-Erling Smørgrav } 943545d5ecaSDag-Erling Smørgrav 944545d5ecaSDag-Erling Smørgrav int 945545d5ecaSDag-Erling Smørgrav mm_auth_rsa_verify_response(Key *key, BIGNUM *p, u_char response[16]) 946545d5ecaSDag-Erling Smørgrav { 947545d5ecaSDag-Erling Smørgrav Buffer m; 948545d5ecaSDag-Erling Smørgrav u_char *blob; 949545d5ecaSDag-Erling Smørgrav u_int blen; 950545d5ecaSDag-Erling Smørgrav int success = 0; 951545d5ecaSDag-Erling Smørgrav 952545d5ecaSDag-Erling Smørgrav debug3("%s entering", __func__); 953545d5ecaSDag-Erling Smørgrav 954545d5ecaSDag-Erling Smørgrav key->type = KEY_RSA; /* XXX cheat for key_to_blob */ 955545d5ecaSDag-Erling Smørgrav if (key_to_blob(key, &blob, &blen) == 0) 956545d5ecaSDag-Erling Smørgrav fatal("%s: key_to_blob failed", __func__); 957545d5ecaSDag-Erling Smørgrav key->type = KEY_RSA1; 958545d5ecaSDag-Erling Smørgrav 959545d5ecaSDag-Erling Smørgrav buffer_init(&m); 960545d5ecaSDag-Erling Smørgrav buffer_put_string(&m, blob, blen); 961545d5ecaSDag-Erling Smørgrav buffer_put_string(&m, response, 16); 962e4a9863fSDag-Erling Smørgrav free(blob); 963545d5ecaSDag-Erling Smørgrav 964545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSARESPONSE, &m); 965545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSARESPONSE, &m); 966545d5ecaSDag-Erling Smørgrav 967545d5ecaSDag-Erling Smørgrav success = buffer_get_int(&m); 968545d5ecaSDag-Erling Smørgrav buffer_free(&m); 969545d5ecaSDag-Erling Smørgrav 970545d5ecaSDag-Erling Smørgrav return (success); 971545d5ecaSDag-Erling Smørgrav } 972a0ee8cc6SDag-Erling Smørgrav #endif 973f388f5efSDag-Erling Smørgrav 974aa49c926SDag-Erling Smørgrav #ifdef SSH_AUDIT_EVENTS 975aa49c926SDag-Erling Smørgrav void 976aa49c926SDag-Erling Smørgrav mm_audit_event(ssh_audit_event_t event) 977aa49c926SDag-Erling Smørgrav { 978aa49c926SDag-Erling Smørgrav Buffer m; 979aa49c926SDag-Erling Smørgrav 980aa49c926SDag-Erling Smørgrav debug3("%s entering", __func__); 981aa49c926SDag-Erling Smørgrav 982aa49c926SDag-Erling Smørgrav buffer_init(&m); 983aa49c926SDag-Erling Smørgrav buffer_put_int(&m, event); 984aa49c926SDag-Erling Smørgrav 985aa49c926SDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_EVENT, &m); 986aa49c926SDag-Erling Smørgrav buffer_free(&m); 987aa49c926SDag-Erling Smørgrav } 988aa49c926SDag-Erling Smørgrav 989aa49c926SDag-Erling Smørgrav void 990aa49c926SDag-Erling Smørgrav mm_audit_run_command(const char *command) 991aa49c926SDag-Erling Smørgrav { 992aa49c926SDag-Erling Smørgrav Buffer m; 993aa49c926SDag-Erling Smørgrav 994aa49c926SDag-Erling Smørgrav debug3("%s entering command %s", __func__, command); 995aa49c926SDag-Erling Smørgrav 996aa49c926SDag-Erling Smørgrav buffer_init(&m); 997aa49c926SDag-Erling Smørgrav buffer_put_cstring(&m, command); 998aa49c926SDag-Erling Smørgrav 999aa49c926SDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, &m); 1000aa49c926SDag-Erling Smørgrav buffer_free(&m); 1001aa49c926SDag-Erling Smørgrav } 1002aa49c926SDag-Erling Smørgrav #endif /* SSH_AUDIT_EVENTS */ 1003aa49c926SDag-Erling Smørgrav 1004cf2b5f3bSDag-Erling Smørgrav #ifdef GSSAPI 1005cf2b5f3bSDag-Erling Smørgrav OM_uint32 100621e764dfSDag-Erling Smørgrav mm_ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID goid) 1007f388f5efSDag-Erling Smørgrav { 1008f388f5efSDag-Erling Smørgrav Buffer m; 1009cf2b5f3bSDag-Erling Smørgrav OM_uint32 major; 1010f388f5efSDag-Erling Smørgrav 1011cf2b5f3bSDag-Erling Smørgrav /* Client doesn't get to see the context */ 1012cf2b5f3bSDag-Erling Smørgrav *ctx = NULL; 1013f388f5efSDag-Erling Smørgrav 1014f388f5efSDag-Erling Smørgrav buffer_init(&m); 101521e764dfSDag-Erling Smørgrav buffer_put_string(&m, goid->elements, goid->length); 1016f388f5efSDag-Erling Smørgrav 1017cf2b5f3bSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSETUP, &m); 1018cf2b5f3bSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSETUP, &m); 1019f388f5efSDag-Erling Smørgrav 1020cf2b5f3bSDag-Erling Smørgrav major = buffer_get_int(&m); 1021cf2b5f3bSDag-Erling Smørgrav 1022f388f5efSDag-Erling Smørgrav buffer_free(&m); 1023cf2b5f3bSDag-Erling Smørgrav return (major); 1024f388f5efSDag-Erling Smørgrav } 1025f388f5efSDag-Erling Smørgrav 1026cf2b5f3bSDag-Erling Smørgrav OM_uint32 1027cf2b5f3bSDag-Erling Smørgrav mm_ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *in, 1028cf2b5f3bSDag-Erling Smørgrav gss_buffer_desc *out, OM_uint32 *flags) 1029f388f5efSDag-Erling Smørgrav { 1030f388f5efSDag-Erling Smørgrav Buffer m; 1031cf2b5f3bSDag-Erling Smørgrav OM_uint32 major; 1032f388f5efSDag-Erling Smørgrav u_int len; 1033f388f5efSDag-Erling Smørgrav 1034cf2b5f3bSDag-Erling Smørgrav buffer_init(&m); 1035cf2b5f3bSDag-Erling Smørgrav buffer_put_string(&m, in->value, in->length); 1036cf2b5f3bSDag-Erling Smørgrav 1037cf2b5f3bSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSTEP, &m); 1038cf2b5f3bSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSTEP, &m); 1039cf2b5f3bSDag-Erling Smørgrav 1040cf2b5f3bSDag-Erling Smørgrav major = buffer_get_int(&m); 1041cf2b5f3bSDag-Erling Smørgrav out->value = buffer_get_string(&m, &len); 1042cf2b5f3bSDag-Erling Smørgrav out->length = len; 1043cf2b5f3bSDag-Erling Smørgrav if (flags) 1044cf2b5f3bSDag-Erling Smørgrav *flags = buffer_get_int(&m); 1045f388f5efSDag-Erling Smørgrav 1046f388f5efSDag-Erling Smørgrav buffer_free(&m); 1047cf2b5f3bSDag-Erling Smørgrav 1048cf2b5f3bSDag-Erling Smørgrav return (major); 1049f388f5efSDag-Erling Smørgrav } 1050cf2b5f3bSDag-Erling Smørgrav 10511ec0d754SDag-Erling Smørgrav OM_uint32 10521ec0d754SDag-Erling Smørgrav mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) 10531ec0d754SDag-Erling Smørgrav { 10541ec0d754SDag-Erling Smørgrav Buffer m; 10551ec0d754SDag-Erling Smørgrav OM_uint32 major; 10561ec0d754SDag-Erling Smørgrav 10571ec0d754SDag-Erling Smørgrav buffer_init(&m); 10581ec0d754SDag-Erling Smørgrav buffer_put_string(&m, gssbuf->value, gssbuf->length); 10591ec0d754SDag-Erling Smørgrav buffer_put_string(&m, gssmic->value, gssmic->length); 10601ec0d754SDag-Erling Smørgrav 10611ec0d754SDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSCHECKMIC, &m); 10621ec0d754SDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSCHECKMIC, 10631ec0d754SDag-Erling Smørgrav &m); 10641ec0d754SDag-Erling Smørgrav 10651ec0d754SDag-Erling Smørgrav major = buffer_get_int(&m); 10661ec0d754SDag-Erling Smørgrav buffer_free(&m); 10671ec0d754SDag-Erling Smørgrav return(major); 10681ec0d754SDag-Erling Smørgrav } 10691ec0d754SDag-Erling Smørgrav 1070cf2b5f3bSDag-Erling Smørgrav int 1071cf2b5f3bSDag-Erling Smørgrav mm_ssh_gssapi_userok(char *user) 1072cf2b5f3bSDag-Erling Smørgrav { 1073cf2b5f3bSDag-Erling Smørgrav Buffer m; 1074cf2b5f3bSDag-Erling Smørgrav int authenticated = 0; 1075cf2b5f3bSDag-Erling Smørgrav 1076cf2b5f3bSDag-Erling Smørgrav buffer_init(&m); 1077cf2b5f3bSDag-Erling Smørgrav 1078cf2b5f3bSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, &m); 1079cf2b5f3bSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUSEROK, 1080cf2b5f3bSDag-Erling Smørgrav &m); 1081cf2b5f3bSDag-Erling Smørgrav 1082cf2b5f3bSDag-Erling Smørgrav authenticated = buffer_get_int(&m); 1083cf2b5f3bSDag-Erling Smørgrav 1084cf2b5f3bSDag-Erling Smørgrav buffer_free(&m); 1085cf2b5f3bSDag-Erling Smørgrav debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not "); 1086cf2b5f3bSDag-Erling Smørgrav return (authenticated); 1087cf2b5f3bSDag-Erling Smørgrav } 1088cf2b5f3bSDag-Erling Smørgrav #endif /* GSSAPI */ 1089cce7d346SDag-Erling Smørgrav 1090