1*076ad2f8SDag-Erling Smørgrav /* $OpenBSD: monitor_wrap.c,v 1.88 2016/03/07 19:02:43 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" 63*076ad2f8SDag-Erling Smørgrav #include "auth-pam.h" 645962c0e9SDag-Erling Smørgrav #ifdef TARGET_OS_MAC /* XXX Broken krb5 headers on Mac */ 655962c0e9SDag-Erling Smørgrav #undef TARGET_OS_MAC 66545d5ecaSDag-Erling Smørgrav #include "zlib.h" 675962c0e9SDag-Erling Smørgrav #define TARGET_OS_MAC 1 685962c0e9SDag-Erling Smørgrav #else 695962c0e9SDag-Erling Smørgrav #include "zlib.h" 705962c0e9SDag-Erling Smørgrav #endif 71545d5ecaSDag-Erling Smørgrav #include "monitor.h" 72cf2b5f3bSDag-Erling Smørgrav #ifdef GSSAPI 73cf2b5f3bSDag-Erling Smørgrav #include "ssh-gss.h" 74cf2b5f3bSDag-Erling Smørgrav #endif 75333ee039SDag-Erling Smørgrav #include "monitor_wrap.h" 76333ee039SDag-Erling Smørgrav #include "atomicio.h" 77333ee039SDag-Erling Smørgrav #include "monitor_fdpass.h" 78333ee039SDag-Erling Smørgrav #include "misc.h" 794a421b63SDag-Erling Smørgrav #include "uuencode.h" 80333ee039SDag-Erling Smørgrav 81333ee039SDag-Erling Smørgrav #include "channels.h" 82333ee039SDag-Erling Smørgrav #include "session.h" 83d4af9e69SDag-Erling Smørgrav #include "servconf.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)) { 156557f75e5SDag-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, 221acc1a9efSDag-Erling Smørgrav const u_char *data, u_int datalen, const char *hostkey_alg) 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); 231acc1a9efSDag-Erling Smørgrav buffer_put_cstring(&m, hostkey_alg); 232545d5ecaSDag-Erling Smørgrav 233545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SIGN, &m); 234545d5ecaSDag-Erling Smørgrav 235545d5ecaSDag-Erling Smørgrav debug3("%s: waiting for MONITOR_ANS_SIGN", __func__); 236545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SIGN, &m); 237545d5ecaSDag-Erling Smørgrav *sigp = buffer_get_string(&m, lenp); 238545d5ecaSDag-Erling Smørgrav buffer_free(&m); 239545d5ecaSDag-Erling Smørgrav 240545d5ecaSDag-Erling Smørgrav return (0); 241545d5ecaSDag-Erling Smørgrav } 242545d5ecaSDag-Erling Smørgrav 243545d5ecaSDag-Erling Smørgrav struct passwd * 24421e764dfSDag-Erling Smørgrav mm_getpwnamallow(const char *username) 245545d5ecaSDag-Erling Smørgrav { 246545d5ecaSDag-Erling Smørgrav Buffer m; 247545d5ecaSDag-Erling Smørgrav struct passwd *pw; 248e146993eSDag-Erling Smørgrav u_int len, i; 249d4af9e69SDag-Erling Smørgrav ServerOptions *newopts; 250545d5ecaSDag-Erling Smørgrav 251545d5ecaSDag-Erling Smørgrav debug3("%s entering", __func__); 252545d5ecaSDag-Erling Smørgrav 253545d5ecaSDag-Erling Smørgrav buffer_init(&m); 25421e764dfSDag-Erling Smørgrav buffer_put_cstring(&m, username); 255545d5ecaSDag-Erling Smørgrav 256545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PWNAM, &m); 257545d5ecaSDag-Erling Smørgrav 258545d5ecaSDag-Erling Smørgrav debug3("%s: waiting for MONITOR_ANS_PWNAM", __func__); 259545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PWNAM, &m); 260545d5ecaSDag-Erling Smørgrav 261545d5ecaSDag-Erling Smørgrav if (buffer_get_char(&m) == 0) { 262d4af9e69SDag-Erling Smørgrav pw = NULL; 263d4af9e69SDag-Erling Smørgrav goto out; 264545d5ecaSDag-Erling Smørgrav } 265d4af9e69SDag-Erling Smørgrav pw = buffer_get_string(&m, &len); 266d4af9e69SDag-Erling Smørgrav if (len != sizeof(struct passwd)) 267545d5ecaSDag-Erling Smørgrav fatal("%s: struct passwd size mismatch", __func__); 268545d5ecaSDag-Erling Smørgrav pw->pw_name = buffer_get_string(&m, NULL); 269545d5ecaSDag-Erling Smørgrav pw->pw_passwd = buffer_get_string(&m, NULL); 270e4a9863fSDag-Erling Smørgrav #ifdef HAVE_STRUCT_PASSWD_PW_GECOS 271545d5ecaSDag-Erling Smørgrav pw->pw_gecos = buffer_get_string(&m, NULL); 272e4a9863fSDag-Erling Smørgrav #endif 273e4a9863fSDag-Erling Smørgrav #ifdef HAVE_STRUCT_PASSWD_PW_CLASS 274545d5ecaSDag-Erling Smørgrav pw->pw_class = buffer_get_string(&m, NULL); 27583d2307dSDag-Erling Smørgrav #endif 276545d5ecaSDag-Erling Smørgrav pw->pw_dir = buffer_get_string(&m, NULL); 277545d5ecaSDag-Erling Smørgrav pw->pw_shell = buffer_get_string(&m, NULL); 278d4af9e69SDag-Erling Smørgrav 279d4af9e69SDag-Erling Smørgrav out: 280d4af9e69SDag-Erling Smørgrav /* copy options block as a Match directive may have changed some */ 281d4af9e69SDag-Erling Smørgrav newopts = buffer_get_string(&m, &len); 282d4af9e69SDag-Erling Smørgrav if (len != sizeof(*newopts)) 283d4af9e69SDag-Erling Smørgrav fatal("%s: option block size mismatch", __func__); 284e146993eSDag-Erling Smørgrav 285e146993eSDag-Erling Smørgrav #define M_CP_STROPT(x) do { \ 286e146993eSDag-Erling Smørgrav if (newopts->x != NULL) \ 287e146993eSDag-Erling Smørgrav newopts->x = buffer_get_string(&m, NULL); \ 288e146993eSDag-Erling Smørgrav } while (0) 289e146993eSDag-Erling Smørgrav #define M_CP_STRARRAYOPT(x, nx) do { \ 290e146993eSDag-Erling Smørgrav for (i = 0; i < newopts->nx; i++) \ 291e146993eSDag-Erling Smørgrav newopts->x[i] = buffer_get_string(&m, NULL); \ 292e146993eSDag-Erling Smørgrav } while (0) 293e146993eSDag-Erling Smørgrav /* See comment in servconf.h */ 294e146993eSDag-Erling Smørgrav COPY_MATCH_STRING_OPTS(); 295e146993eSDag-Erling Smørgrav #undef M_CP_STROPT 296e146993eSDag-Erling Smørgrav #undef M_CP_STRARRAYOPT 297e146993eSDag-Erling Smørgrav 298d4af9e69SDag-Erling Smørgrav copy_set_server_options(&options, newopts, 1); 299e4a9863fSDag-Erling Smørgrav free(newopts); 300d4af9e69SDag-Erling Smørgrav 301545d5ecaSDag-Erling Smørgrav buffer_free(&m); 302545d5ecaSDag-Erling Smørgrav 303545d5ecaSDag-Erling Smørgrav return (pw); 304545d5ecaSDag-Erling Smørgrav } 305545d5ecaSDag-Erling Smørgrav 3061ec0d754SDag-Erling Smørgrav char * 3071ec0d754SDag-Erling Smørgrav mm_auth2_read_banner(void) 308545d5ecaSDag-Erling Smørgrav { 309545d5ecaSDag-Erling Smørgrav Buffer m; 310545d5ecaSDag-Erling Smørgrav char *banner; 311545d5ecaSDag-Erling Smørgrav 312545d5ecaSDag-Erling Smørgrav debug3("%s entering", __func__); 313545d5ecaSDag-Erling Smørgrav 314545d5ecaSDag-Erling Smørgrav buffer_init(&m); 315545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTH2_READ_BANNER, &m); 316545d5ecaSDag-Erling Smørgrav buffer_clear(&m); 317545d5ecaSDag-Erling Smørgrav 3181ec0d754SDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, 3191ec0d754SDag-Erling Smørgrav MONITOR_ANS_AUTH2_READ_BANNER, &m); 320545d5ecaSDag-Erling Smørgrav banner = buffer_get_string(&m, NULL); 321545d5ecaSDag-Erling Smørgrav buffer_free(&m); 322545d5ecaSDag-Erling Smørgrav 3231ec0d754SDag-Erling Smørgrav /* treat empty banner as missing banner */ 3241ec0d754SDag-Erling Smørgrav if (strlen(banner) == 0) { 325e4a9863fSDag-Erling Smørgrav free(banner); 3261ec0d754SDag-Erling Smørgrav banner = NULL; 3271ec0d754SDag-Erling Smørgrav } 328545d5ecaSDag-Erling Smørgrav return (banner); 329545d5ecaSDag-Erling Smørgrav } 330545d5ecaSDag-Erling Smørgrav 331545d5ecaSDag-Erling Smørgrav /* Inform the privileged process about service and style */ 332545d5ecaSDag-Erling Smørgrav 333545d5ecaSDag-Erling Smørgrav void 334545d5ecaSDag-Erling Smørgrav mm_inform_authserv(char *service, char *style) 335545d5ecaSDag-Erling Smørgrav { 336545d5ecaSDag-Erling Smørgrav Buffer m; 337545d5ecaSDag-Erling Smørgrav 338545d5ecaSDag-Erling Smørgrav debug3("%s entering", __func__); 339545d5ecaSDag-Erling Smørgrav 340545d5ecaSDag-Erling Smørgrav buffer_init(&m); 341545d5ecaSDag-Erling Smørgrav buffer_put_cstring(&m, service); 342545d5ecaSDag-Erling Smørgrav buffer_put_cstring(&m, style ? style : ""); 343545d5ecaSDag-Erling Smørgrav 344545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHSERV, &m); 345545d5ecaSDag-Erling Smørgrav 346545d5ecaSDag-Erling Smørgrav buffer_free(&m); 347545d5ecaSDag-Erling Smørgrav } 348545d5ecaSDag-Erling Smørgrav 349545d5ecaSDag-Erling Smørgrav /* Do the password authentication */ 350545d5ecaSDag-Erling Smørgrav int 351545d5ecaSDag-Erling Smørgrav mm_auth_password(Authctxt *authctxt, char *password) 352545d5ecaSDag-Erling Smørgrav { 353545d5ecaSDag-Erling Smørgrav Buffer m; 354545d5ecaSDag-Erling Smørgrav int authenticated = 0; 355545d5ecaSDag-Erling Smørgrav 356545d5ecaSDag-Erling Smørgrav debug3("%s entering", __func__); 357545d5ecaSDag-Erling Smørgrav 358545d5ecaSDag-Erling Smørgrav buffer_init(&m); 359545d5ecaSDag-Erling Smørgrav buffer_put_cstring(&m, password); 360545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHPASSWORD, &m); 361545d5ecaSDag-Erling Smørgrav 362545d5ecaSDag-Erling Smørgrav debug3("%s: waiting for MONITOR_ANS_AUTHPASSWORD", __func__); 363545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUTHPASSWORD, &m); 364545d5ecaSDag-Erling Smørgrav 365545d5ecaSDag-Erling Smørgrav authenticated = buffer_get_int(&m); 366*076ad2f8SDag-Erling Smørgrav #ifdef USE_PAM 367*076ad2f8SDag-Erling Smørgrav sshpam_set_maxtries_reached(buffer_get_int(&m)); 368*076ad2f8SDag-Erling Smørgrav #endif 369545d5ecaSDag-Erling Smørgrav 370545d5ecaSDag-Erling Smørgrav buffer_free(&m); 371545d5ecaSDag-Erling Smørgrav 372545d5ecaSDag-Erling Smørgrav debug3("%s: user %sauthenticated", 373545d5ecaSDag-Erling Smørgrav __func__, authenticated ? "" : "not "); 374545d5ecaSDag-Erling Smørgrav return (authenticated); 375545d5ecaSDag-Erling Smørgrav } 376545d5ecaSDag-Erling Smørgrav 377545d5ecaSDag-Erling Smørgrav int 378557f75e5SDag-Erling Smørgrav mm_user_key_allowed(struct passwd *pw, Key *key, int pubkey_auth_attempt) 379545d5ecaSDag-Erling Smørgrav { 380557f75e5SDag-Erling Smørgrav return (mm_key_allowed(MM_USERKEY, NULL, NULL, key, 381557f75e5SDag-Erling Smørgrav pubkey_auth_attempt)); 382545d5ecaSDag-Erling Smørgrav } 383545d5ecaSDag-Erling Smørgrav 384545d5ecaSDag-Erling Smørgrav int 385*076ad2f8SDag-Erling Smørgrav mm_hostbased_key_allowed(struct passwd *pw, const char *user, const char *host, 386545d5ecaSDag-Erling Smørgrav Key *key) 387545d5ecaSDag-Erling Smørgrav { 388557f75e5SDag-Erling Smørgrav return (mm_key_allowed(MM_HOSTKEY, user, host, key, 0)); 389545d5ecaSDag-Erling Smørgrav } 390545d5ecaSDag-Erling Smørgrav 391545d5ecaSDag-Erling Smørgrav int 392*076ad2f8SDag-Erling Smørgrav mm_auth_rhosts_rsa_key_allowed(struct passwd *pw, const char *user, 393*076ad2f8SDag-Erling Smørgrav const char *host, Key *key) 394545d5ecaSDag-Erling Smørgrav { 395545d5ecaSDag-Erling Smørgrav int ret; 396545d5ecaSDag-Erling Smørgrav 397545d5ecaSDag-Erling Smørgrav key->type = KEY_RSA; /* XXX hack for key_to_blob */ 398557f75e5SDag-Erling Smørgrav ret = mm_key_allowed(MM_RSAHOSTKEY, user, host, key, 0); 399545d5ecaSDag-Erling Smørgrav key->type = KEY_RSA1; 400545d5ecaSDag-Erling Smørgrav return (ret); 401545d5ecaSDag-Erling Smørgrav } 402545d5ecaSDag-Erling Smørgrav 403545d5ecaSDag-Erling Smørgrav int 404*076ad2f8SDag-Erling Smørgrav mm_key_allowed(enum mm_keytype type, const char *user, const char *host, 405*076ad2f8SDag-Erling Smørgrav Key *key, int pubkey_auth_attempt) 406545d5ecaSDag-Erling Smørgrav { 407545d5ecaSDag-Erling Smørgrav Buffer m; 408545d5ecaSDag-Erling Smørgrav u_char *blob; 409545d5ecaSDag-Erling Smørgrav u_int len; 410e73e9afaSDag-Erling Smørgrav int allowed = 0, have_forced = 0; 411545d5ecaSDag-Erling Smørgrav 412545d5ecaSDag-Erling Smørgrav debug3("%s entering", __func__); 413545d5ecaSDag-Erling Smørgrav 414545d5ecaSDag-Erling Smørgrav /* Convert the key to a blob and the pass it over */ 415545d5ecaSDag-Erling Smørgrav if (!key_to_blob(key, &blob, &len)) 416545d5ecaSDag-Erling Smørgrav return (0); 417545d5ecaSDag-Erling Smørgrav 418545d5ecaSDag-Erling Smørgrav buffer_init(&m); 419545d5ecaSDag-Erling Smørgrav buffer_put_int(&m, type); 420545d5ecaSDag-Erling Smørgrav buffer_put_cstring(&m, user ? user : ""); 421545d5ecaSDag-Erling Smørgrav buffer_put_cstring(&m, host ? host : ""); 422545d5ecaSDag-Erling Smørgrav buffer_put_string(&m, blob, len); 423557f75e5SDag-Erling Smørgrav buffer_put_int(&m, pubkey_auth_attempt); 424e4a9863fSDag-Erling Smørgrav free(blob); 425545d5ecaSDag-Erling Smørgrav 426545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYALLOWED, &m); 427545d5ecaSDag-Erling Smørgrav 428545d5ecaSDag-Erling Smørgrav debug3("%s: waiting for MONITOR_ANS_KEYALLOWED", __func__); 429545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYALLOWED, &m); 430545d5ecaSDag-Erling Smørgrav 431545d5ecaSDag-Erling Smørgrav allowed = buffer_get_int(&m); 432545d5ecaSDag-Erling Smørgrav 433e73e9afaSDag-Erling Smørgrav /* fake forced command */ 434e73e9afaSDag-Erling Smørgrav auth_clear_options(); 435e73e9afaSDag-Erling Smørgrav have_forced = buffer_get_int(&m); 436e73e9afaSDag-Erling Smørgrav forced_command = have_forced ? xstrdup("true") : NULL; 437e73e9afaSDag-Erling Smørgrav 438545d5ecaSDag-Erling Smørgrav buffer_free(&m); 439545d5ecaSDag-Erling Smørgrav 440545d5ecaSDag-Erling Smørgrav return (allowed); 441545d5ecaSDag-Erling Smørgrav } 442545d5ecaSDag-Erling Smørgrav 443545d5ecaSDag-Erling Smørgrav /* 444545d5ecaSDag-Erling Smørgrav * This key verify needs to send the key type along, because the 445545d5ecaSDag-Erling Smørgrav * privileged parent makes the decision if the key is allowed 446545d5ecaSDag-Erling Smørgrav * for authentication. 447545d5ecaSDag-Erling Smørgrav */ 448545d5ecaSDag-Erling Smørgrav 449545d5ecaSDag-Erling Smørgrav int 450545d5ecaSDag-Erling Smørgrav mm_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen) 451545d5ecaSDag-Erling Smørgrav { 452545d5ecaSDag-Erling Smørgrav Buffer m; 453545d5ecaSDag-Erling Smørgrav u_char *blob; 454545d5ecaSDag-Erling Smørgrav u_int len; 455545d5ecaSDag-Erling Smørgrav int verified = 0; 456545d5ecaSDag-Erling Smørgrav 457545d5ecaSDag-Erling Smørgrav debug3("%s entering", __func__); 458545d5ecaSDag-Erling Smørgrav 459545d5ecaSDag-Erling Smørgrav /* Convert the key to a blob and the pass it over */ 460545d5ecaSDag-Erling Smørgrav if (!key_to_blob(key, &blob, &len)) 461545d5ecaSDag-Erling Smørgrav return (0); 462545d5ecaSDag-Erling Smørgrav 463545d5ecaSDag-Erling Smørgrav buffer_init(&m); 464545d5ecaSDag-Erling Smørgrav buffer_put_string(&m, blob, len); 465545d5ecaSDag-Erling Smørgrav buffer_put_string(&m, sig, siglen); 466545d5ecaSDag-Erling Smørgrav buffer_put_string(&m, data, datalen); 467e4a9863fSDag-Erling Smørgrav free(blob); 468545d5ecaSDag-Erling Smørgrav 469545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYVERIFY, &m); 470545d5ecaSDag-Erling Smørgrav 471545d5ecaSDag-Erling Smørgrav debug3("%s: waiting for MONITOR_ANS_KEYVERIFY", __func__); 472545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYVERIFY, &m); 473545d5ecaSDag-Erling Smørgrav 474545d5ecaSDag-Erling Smørgrav verified = buffer_get_int(&m); 475545d5ecaSDag-Erling Smørgrav 476545d5ecaSDag-Erling Smørgrav buffer_free(&m); 477545d5ecaSDag-Erling Smørgrav 478545d5ecaSDag-Erling Smørgrav return (verified); 479545d5ecaSDag-Erling Smørgrav } 480545d5ecaSDag-Erling Smørgrav 481545d5ecaSDag-Erling Smørgrav void 48221e764dfSDag-Erling Smørgrav mm_send_keystate(struct monitor *monitor) 483545d5ecaSDag-Erling Smørgrav { 484bc5531deSDag-Erling Smørgrav struct ssh *ssh = active_state; /* XXX */ 485bc5531deSDag-Erling Smørgrav struct sshbuf *m; 486bc5531deSDag-Erling Smørgrav int r; 487545d5ecaSDag-Erling Smørgrav 488bc5531deSDag-Erling Smørgrav if ((m = sshbuf_new()) == NULL) 489bc5531deSDag-Erling Smørgrav fatal("%s: sshbuf_new failed", __func__); 490bc5531deSDag-Erling Smørgrav if ((r = ssh_packet_get_state(ssh, m)) != 0) 491bc5531deSDag-Erling Smørgrav fatal("%s: get_state failed: %s", 492bc5531deSDag-Erling Smørgrav __func__, ssh_err(r)); 493bc5531deSDag-Erling Smørgrav mm_request_send(monitor->m_recvfd, MONITOR_REQ_KEYEXPORT, m); 494545d5ecaSDag-Erling Smørgrav debug3("%s: Finished sending state", __func__); 495bc5531deSDag-Erling Smørgrav sshbuf_free(m); 496545d5ecaSDag-Erling Smørgrav } 497545d5ecaSDag-Erling Smørgrav 498545d5ecaSDag-Erling Smørgrav int 499333ee039SDag-Erling Smørgrav mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen) 500545d5ecaSDag-Erling Smørgrav { 501545d5ecaSDag-Erling Smørgrav Buffer m; 50221e764dfSDag-Erling Smørgrav char *p, *msg; 503d4af9e69SDag-Erling Smørgrav int success = 0, tmp1 = -1, tmp2 = -1; 504d4af9e69SDag-Erling Smørgrav 505d4af9e69SDag-Erling Smørgrav /* Kludge: ensure there are fds free to receive the pty/tty */ 506d4af9e69SDag-Erling Smørgrav if ((tmp1 = dup(pmonitor->m_recvfd)) == -1 || 507d4af9e69SDag-Erling Smørgrav (tmp2 = dup(pmonitor->m_recvfd)) == -1) { 508d4af9e69SDag-Erling Smørgrav error("%s: cannot allocate fds for pty", __func__); 509d4af9e69SDag-Erling Smørgrav if (tmp1 > 0) 510d4af9e69SDag-Erling Smørgrav close(tmp1); 511d4af9e69SDag-Erling Smørgrav if (tmp2 > 0) 512d4af9e69SDag-Erling Smørgrav close(tmp2); 513d4af9e69SDag-Erling Smørgrav return 0; 514d4af9e69SDag-Erling Smørgrav } 515d4af9e69SDag-Erling Smørgrav close(tmp1); 516d4af9e69SDag-Erling Smørgrav close(tmp2); 517545d5ecaSDag-Erling Smørgrav 518545d5ecaSDag-Erling Smørgrav buffer_init(&m); 519545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTY, &m); 520545d5ecaSDag-Erling Smørgrav 521545d5ecaSDag-Erling Smørgrav debug3("%s: waiting for MONITOR_ANS_PTY", __func__); 522545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PTY, &m); 523545d5ecaSDag-Erling Smørgrav 524545d5ecaSDag-Erling Smørgrav success = buffer_get_int(&m); 525545d5ecaSDag-Erling Smørgrav if (success == 0) { 526545d5ecaSDag-Erling Smørgrav debug3("%s: pty alloc failed", __func__); 527545d5ecaSDag-Erling Smørgrav buffer_free(&m); 528545d5ecaSDag-Erling Smørgrav return (0); 529545d5ecaSDag-Erling Smørgrav } 530545d5ecaSDag-Erling Smørgrav p = buffer_get_string(&m, NULL); 53121e764dfSDag-Erling Smørgrav msg = buffer_get_string(&m, NULL); 532545d5ecaSDag-Erling Smørgrav buffer_free(&m); 533545d5ecaSDag-Erling Smørgrav 534545d5ecaSDag-Erling Smørgrav strlcpy(namebuf, p, namebuflen); /* Possible truncation */ 535e4a9863fSDag-Erling Smørgrav free(p); 536545d5ecaSDag-Erling Smørgrav 53721e764dfSDag-Erling Smørgrav buffer_append(&loginmsg, msg, strlen(msg)); 538e4a9863fSDag-Erling Smørgrav free(msg); 53921e764dfSDag-Erling Smørgrav 540d4af9e69SDag-Erling Smørgrav if ((*ptyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1 || 541d4af9e69SDag-Erling Smørgrav (*ttyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1) 542d4af9e69SDag-Erling Smørgrav fatal("%s: receive fds failed", __func__); 543545d5ecaSDag-Erling Smørgrav 544545d5ecaSDag-Erling Smørgrav /* Success */ 545545d5ecaSDag-Erling Smørgrav return (1); 546545d5ecaSDag-Erling Smørgrav } 547545d5ecaSDag-Erling Smørgrav 548545d5ecaSDag-Erling Smørgrav void 5491ec0d754SDag-Erling Smørgrav mm_session_pty_cleanup2(Session *s) 550545d5ecaSDag-Erling Smørgrav { 551545d5ecaSDag-Erling Smørgrav Buffer m; 552545d5ecaSDag-Erling Smørgrav 553545d5ecaSDag-Erling Smørgrav if (s->ttyfd == -1) 554545d5ecaSDag-Erling Smørgrav return; 555545d5ecaSDag-Erling Smørgrav buffer_init(&m); 556545d5ecaSDag-Erling Smørgrav buffer_put_cstring(&m, s->tty); 557545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTYCLEANUP, &m); 558545d5ecaSDag-Erling Smørgrav buffer_free(&m); 559545d5ecaSDag-Erling Smørgrav 560545d5ecaSDag-Erling Smørgrav /* closed dup'ed master */ 561d4af9e69SDag-Erling Smørgrav if (s->ptymaster != -1 && close(s->ptymaster) < 0) 562d4af9e69SDag-Erling Smørgrav error("close(s->ptymaster/%d): %s", 563d4af9e69SDag-Erling Smørgrav s->ptymaster, strerror(errno)); 564545d5ecaSDag-Erling Smørgrav 565545d5ecaSDag-Erling Smørgrav /* unlink pty from session */ 566545d5ecaSDag-Erling Smørgrav s->ttyfd = -1; 567545d5ecaSDag-Erling Smørgrav } 568545d5ecaSDag-Erling Smørgrav 56983d2307dSDag-Erling Smørgrav #ifdef USE_PAM 57083d2307dSDag-Erling Smørgrav void 5715962c0e9SDag-Erling Smørgrav mm_start_pam(Authctxt *authctxt) 57283d2307dSDag-Erling Smørgrav { 57383d2307dSDag-Erling Smørgrav Buffer m; 57483d2307dSDag-Erling Smørgrav 57583d2307dSDag-Erling Smørgrav debug3("%s entering", __func__); 576cf2b5f3bSDag-Erling Smørgrav if (!options.use_pam) 577cf2b5f3bSDag-Erling Smørgrav fatal("UsePAM=no, but ended up in %s anyway", __func__); 57883d2307dSDag-Erling Smørgrav 57983d2307dSDag-Erling Smørgrav buffer_init(&m); 58083d2307dSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_START, &m); 58183d2307dSDag-Erling Smørgrav 58283d2307dSDag-Erling Smørgrav buffer_free(&m); 58383d2307dSDag-Erling Smørgrav } 584382d19eeSDag-Erling Smørgrav 585cf2b5f3bSDag-Erling Smørgrav u_int 586cf2b5f3bSDag-Erling Smørgrav mm_do_pam_account(void) 587cf2b5f3bSDag-Erling Smørgrav { 588cf2b5f3bSDag-Erling Smørgrav Buffer m; 589cf2b5f3bSDag-Erling Smørgrav u_int ret; 590aa49c926SDag-Erling Smørgrav char *msg; 591cf2b5f3bSDag-Erling Smørgrav 592cf2b5f3bSDag-Erling Smørgrav debug3("%s entering", __func__); 593cf2b5f3bSDag-Erling Smørgrav if (!options.use_pam) 594cf2b5f3bSDag-Erling Smørgrav fatal("UsePAM=no, but ended up in %s anyway", __func__); 595cf2b5f3bSDag-Erling Smørgrav 596cf2b5f3bSDag-Erling Smørgrav buffer_init(&m); 597cf2b5f3bSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_ACCOUNT, &m); 598cf2b5f3bSDag-Erling Smørgrav 599cf2b5f3bSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, 600cf2b5f3bSDag-Erling Smørgrav MONITOR_ANS_PAM_ACCOUNT, &m); 601cf2b5f3bSDag-Erling Smørgrav ret = buffer_get_int(&m); 602aa49c926SDag-Erling Smørgrav msg = buffer_get_string(&m, NULL); 603aa49c926SDag-Erling Smørgrav buffer_append(&loginmsg, msg, strlen(msg)); 604e4a9863fSDag-Erling Smørgrav free(msg); 605cf2b5f3bSDag-Erling Smørgrav 606cf2b5f3bSDag-Erling Smørgrav buffer_free(&m); 607cf2b5f3bSDag-Erling Smørgrav 608cf2b5f3bSDag-Erling Smørgrav debug3("%s returning %d", __func__, ret); 609cf2b5f3bSDag-Erling Smørgrav 610cf2b5f3bSDag-Erling Smørgrav return (ret); 611cf2b5f3bSDag-Erling Smørgrav } 612cf2b5f3bSDag-Erling Smørgrav 613382d19eeSDag-Erling Smørgrav void * 614cf2b5f3bSDag-Erling Smørgrav mm_sshpam_init_ctx(Authctxt *authctxt) 615382d19eeSDag-Erling Smørgrav { 616382d19eeSDag-Erling Smørgrav Buffer m; 617382d19eeSDag-Erling Smørgrav int success; 618382d19eeSDag-Erling Smørgrav 619382d19eeSDag-Erling Smørgrav debug3("%s", __func__); 620382d19eeSDag-Erling Smørgrav buffer_init(&m); 621382d19eeSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_INIT_CTX, &m); 622382d19eeSDag-Erling Smørgrav debug3("%s: waiting for MONITOR_ANS_PAM_INIT_CTX", __func__); 623382d19eeSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_INIT_CTX, &m); 624382d19eeSDag-Erling Smørgrav success = buffer_get_int(&m); 625382d19eeSDag-Erling Smørgrav if (success == 0) { 626382d19eeSDag-Erling Smørgrav debug3("%s: pam_init_ctx failed", __func__); 627382d19eeSDag-Erling Smørgrav buffer_free(&m); 628382d19eeSDag-Erling Smørgrav return (NULL); 629382d19eeSDag-Erling Smørgrav } 630382d19eeSDag-Erling Smørgrav buffer_free(&m); 631382d19eeSDag-Erling Smørgrav return (authctxt); 632382d19eeSDag-Erling Smørgrav } 633382d19eeSDag-Erling Smørgrav 634382d19eeSDag-Erling Smørgrav int 635cf2b5f3bSDag-Erling Smørgrav mm_sshpam_query(void *ctx, char **name, char **info, 636382d19eeSDag-Erling Smørgrav u_int *num, char ***prompts, u_int **echo_on) 637382d19eeSDag-Erling Smørgrav { 638382d19eeSDag-Erling Smørgrav Buffer m; 639d4ecd108SDag-Erling Smørgrav u_int i; 640d4ecd108SDag-Erling Smørgrav int ret; 641382d19eeSDag-Erling Smørgrav 642382d19eeSDag-Erling Smørgrav debug3("%s", __func__); 643382d19eeSDag-Erling Smørgrav buffer_init(&m); 644382d19eeSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_QUERY, &m); 645382d19eeSDag-Erling Smørgrav debug3("%s: waiting for MONITOR_ANS_PAM_QUERY", __func__); 646382d19eeSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_QUERY, &m); 647382d19eeSDag-Erling Smørgrav ret = buffer_get_int(&m); 648382d19eeSDag-Erling Smørgrav debug3("%s: pam_query returned %d", __func__, ret); 649382d19eeSDag-Erling Smørgrav *name = buffer_get_string(&m, NULL); 650382d19eeSDag-Erling Smørgrav *info = buffer_get_string(&m, NULL); 651*076ad2f8SDag-Erling Smørgrav sshpam_set_maxtries_reached(buffer_get_int(&m)); 652382d19eeSDag-Erling Smørgrav *num = buffer_get_int(&m); 653333ee039SDag-Erling Smørgrav if (*num > PAM_MAX_NUM_MSG) 654333ee039SDag-Erling Smørgrav fatal("%s: recieved %u PAM messages, expected <= %u", 655333ee039SDag-Erling Smørgrav __func__, *num, PAM_MAX_NUM_MSG); 656333ee039SDag-Erling Smørgrav *prompts = xcalloc((*num + 1), sizeof(char *)); 657333ee039SDag-Erling Smørgrav *echo_on = xcalloc((*num + 1), sizeof(u_int)); 658382d19eeSDag-Erling Smørgrav for (i = 0; i < *num; ++i) { 659382d19eeSDag-Erling Smørgrav (*prompts)[i] = buffer_get_string(&m, NULL); 660382d19eeSDag-Erling Smørgrav (*echo_on)[i] = buffer_get_int(&m); 661382d19eeSDag-Erling Smørgrav } 662382d19eeSDag-Erling Smørgrav buffer_free(&m); 663382d19eeSDag-Erling Smørgrav return (ret); 664382d19eeSDag-Erling Smørgrav } 665382d19eeSDag-Erling Smørgrav 666382d19eeSDag-Erling Smørgrav int 667cf2b5f3bSDag-Erling Smørgrav mm_sshpam_respond(void *ctx, u_int num, char **resp) 668382d19eeSDag-Erling Smørgrav { 669382d19eeSDag-Erling Smørgrav Buffer m; 670d4ecd108SDag-Erling Smørgrav u_int i; 671d4ecd108SDag-Erling Smørgrav int ret; 672382d19eeSDag-Erling Smørgrav 673382d19eeSDag-Erling Smørgrav debug3("%s", __func__); 674382d19eeSDag-Erling Smørgrav buffer_init(&m); 675382d19eeSDag-Erling Smørgrav buffer_put_int(&m, num); 676382d19eeSDag-Erling Smørgrav for (i = 0; i < num; ++i) 677382d19eeSDag-Erling Smørgrav buffer_put_cstring(&m, resp[i]); 678382d19eeSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_RESPOND, &m); 679382d19eeSDag-Erling Smørgrav debug3("%s: waiting for MONITOR_ANS_PAM_RESPOND", __func__); 680382d19eeSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_RESPOND, &m); 681382d19eeSDag-Erling Smørgrav ret = buffer_get_int(&m); 682382d19eeSDag-Erling Smørgrav debug3("%s: pam_respond returned %d", __func__, ret); 683382d19eeSDag-Erling Smørgrav buffer_free(&m); 684382d19eeSDag-Erling Smørgrav return (ret); 685382d19eeSDag-Erling Smørgrav } 686382d19eeSDag-Erling Smørgrav 687382d19eeSDag-Erling Smørgrav void 688cf2b5f3bSDag-Erling Smørgrav mm_sshpam_free_ctx(void *ctxtp) 689382d19eeSDag-Erling Smørgrav { 690382d19eeSDag-Erling Smørgrav Buffer m; 691382d19eeSDag-Erling Smørgrav 692382d19eeSDag-Erling Smørgrav debug3("%s", __func__); 693382d19eeSDag-Erling Smørgrav buffer_init(&m); 694382d19eeSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_FREE_CTX, &m); 695382d19eeSDag-Erling Smørgrav debug3("%s: waiting for MONITOR_ANS_PAM_FREE_CTX", __func__); 696382d19eeSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_FREE_CTX, &m); 697382d19eeSDag-Erling Smørgrav buffer_free(&m); 698382d19eeSDag-Erling Smørgrav } 69983d2307dSDag-Erling Smørgrav #endif /* USE_PAM */ 70083d2307dSDag-Erling Smørgrav 701545d5ecaSDag-Erling Smørgrav /* Request process termination */ 702545d5ecaSDag-Erling Smørgrav 703545d5ecaSDag-Erling Smørgrav void 704545d5ecaSDag-Erling Smørgrav mm_terminate(void) 705545d5ecaSDag-Erling Smørgrav { 706545d5ecaSDag-Erling Smørgrav Buffer m; 707545d5ecaSDag-Erling Smørgrav 708545d5ecaSDag-Erling Smørgrav buffer_init(&m); 709545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_TERM, &m); 710545d5ecaSDag-Erling Smørgrav buffer_free(&m); 711545d5ecaSDag-Erling Smørgrav } 712545d5ecaSDag-Erling Smørgrav 713a0ee8cc6SDag-Erling Smørgrav #ifdef WITH_SSH1 714545d5ecaSDag-Erling Smørgrav int 715545d5ecaSDag-Erling Smørgrav mm_ssh1_session_key(BIGNUM *num) 716545d5ecaSDag-Erling Smørgrav { 717545d5ecaSDag-Erling Smørgrav int rsafail; 718545d5ecaSDag-Erling Smørgrav Buffer m; 719545d5ecaSDag-Erling Smørgrav 720545d5ecaSDag-Erling Smørgrav buffer_init(&m); 721545d5ecaSDag-Erling Smørgrav buffer_put_bignum2(&m, num); 722545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SESSKEY, &m); 723545d5ecaSDag-Erling Smørgrav 724545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SESSKEY, &m); 725545d5ecaSDag-Erling Smørgrav 726545d5ecaSDag-Erling Smørgrav rsafail = buffer_get_int(&m); 727545d5ecaSDag-Erling Smørgrav buffer_get_bignum2(&m, num); 728545d5ecaSDag-Erling Smørgrav 729545d5ecaSDag-Erling Smørgrav buffer_free(&m); 730545d5ecaSDag-Erling Smørgrav 731545d5ecaSDag-Erling Smørgrav return (rsafail); 732545d5ecaSDag-Erling Smørgrav } 733a0ee8cc6SDag-Erling Smørgrav #endif 734545d5ecaSDag-Erling Smørgrav 735545d5ecaSDag-Erling Smørgrav static void 736545d5ecaSDag-Erling Smørgrav mm_chall_setup(char **name, char **infotxt, u_int *numprompts, 737545d5ecaSDag-Erling Smørgrav char ***prompts, u_int **echo_on) 738545d5ecaSDag-Erling Smørgrav { 739545d5ecaSDag-Erling Smørgrav *name = xstrdup(""); 740545d5ecaSDag-Erling Smørgrav *infotxt = xstrdup(""); 741545d5ecaSDag-Erling Smørgrav *numprompts = 1; 742333ee039SDag-Erling Smørgrav *prompts = xcalloc(*numprompts, sizeof(char *)); 743333ee039SDag-Erling Smørgrav *echo_on = xcalloc(*numprompts, sizeof(u_int)); 744545d5ecaSDag-Erling Smørgrav (*echo_on)[0] = 0; 745545d5ecaSDag-Erling Smørgrav } 746545d5ecaSDag-Erling Smørgrav 747545d5ecaSDag-Erling Smørgrav int 748545d5ecaSDag-Erling Smørgrav mm_bsdauth_query(void *ctx, char **name, char **infotxt, 749545d5ecaSDag-Erling Smørgrav u_int *numprompts, char ***prompts, u_int **echo_on) 750545d5ecaSDag-Erling Smørgrav { 751545d5ecaSDag-Erling Smørgrav Buffer m; 752e73e9afaSDag-Erling Smørgrav u_int success; 753545d5ecaSDag-Erling Smørgrav char *challenge; 754545d5ecaSDag-Erling Smørgrav 755545d5ecaSDag-Erling Smørgrav debug3("%s: entering", __func__); 756545d5ecaSDag-Erling Smørgrav 757545d5ecaSDag-Erling Smørgrav buffer_init(&m); 758545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHQUERY, &m); 759545d5ecaSDag-Erling Smørgrav 760545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_BSDAUTHQUERY, 761545d5ecaSDag-Erling Smørgrav &m); 762e73e9afaSDag-Erling Smørgrav success = buffer_get_int(&m); 763e73e9afaSDag-Erling Smørgrav if (success == 0) { 764545d5ecaSDag-Erling Smørgrav debug3("%s: no challenge", __func__); 765545d5ecaSDag-Erling Smørgrav buffer_free(&m); 766545d5ecaSDag-Erling Smørgrav return (-1); 767545d5ecaSDag-Erling Smørgrav } 768545d5ecaSDag-Erling Smørgrav 769545d5ecaSDag-Erling Smørgrav /* Get the challenge, and format the response */ 770545d5ecaSDag-Erling Smørgrav challenge = buffer_get_string(&m, NULL); 771545d5ecaSDag-Erling Smørgrav buffer_free(&m); 772545d5ecaSDag-Erling Smørgrav 773545d5ecaSDag-Erling Smørgrav mm_chall_setup(name, infotxt, numprompts, prompts, echo_on); 774545d5ecaSDag-Erling Smørgrav (*prompts)[0] = challenge; 775545d5ecaSDag-Erling Smørgrav 776545d5ecaSDag-Erling Smørgrav debug3("%s: received challenge: %s", __func__, challenge); 777545d5ecaSDag-Erling Smørgrav 778545d5ecaSDag-Erling Smørgrav return (0); 779545d5ecaSDag-Erling Smørgrav } 780545d5ecaSDag-Erling Smørgrav 781545d5ecaSDag-Erling Smørgrav int 782545d5ecaSDag-Erling Smørgrav mm_bsdauth_respond(void *ctx, u_int numresponses, char **responses) 783545d5ecaSDag-Erling Smørgrav { 784545d5ecaSDag-Erling Smørgrav Buffer m; 785545d5ecaSDag-Erling Smørgrav int authok; 786545d5ecaSDag-Erling Smørgrav 787545d5ecaSDag-Erling Smørgrav debug3("%s: entering", __func__); 788545d5ecaSDag-Erling Smørgrav if (numresponses != 1) 789545d5ecaSDag-Erling Smørgrav return (-1); 790545d5ecaSDag-Erling Smørgrav 791545d5ecaSDag-Erling Smørgrav buffer_init(&m); 792545d5ecaSDag-Erling Smørgrav buffer_put_cstring(&m, responses[0]); 793545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHRESPOND, &m); 794545d5ecaSDag-Erling Smørgrav 795545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, 796545d5ecaSDag-Erling Smørgrav MONITOR_ANS_BSDAUTHRESPOND, &m); 797545d5ecaSDag-Erling Smørgrav 798545d5ecaSDag-Erling Smørgrav authok = buffer_get_int(&m); 799545d5ecaSDag-Erling Smørgrav buffer_free(&m); 800545d5ecaSDag-Erling Smørgrav 801545d5ecaSDag-Erling Smørgrav return ((authok == 0) ? -1 : 0); 802545d5ecaSDag-Erling Smørgrav } 803545d5ecaSDag-Erling Smørgrav 804edb557f8SDag-Erling Smørgrav #ifdef SKEY 805545d5ecaSDag-Erling Smørgrav int 806545d5ecaSDag-Erling Smørgrav mm_skey_query(void *ctx, char **name, char **infotxt, 807545d5ecaSDag-Erling Smørgrav u_int *numprompts, char ***prompts, u_int **echo_on) 808545d5ecaSDag-Erling Smørgrav { 809545d5ecaSDag-Erling Smørgrav Buffer m; 810e73e9afaSDag-Erling Smørgrav u_int success; 811333ee039SDag-Erling Smørgrav char *challenge; 812545d5ecaSDag-Erling Smørgrav 813545d5ecaSDag-Erling Smørgrav debug3("%s: entering", __func__); 814545d5ecaSDag-Erling Smørgrav 815545d5ecaSDag-Erling Smørgrav buffer_init(&m); 816545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SKEYQUERY, &m); 817545d5ecaSDag-Erling Smørgrav 818545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SKEYQUERY, 819545d5ecaSDag-Erling Smørgrav &m); 820e73e9afaSDag-Erling Smørgrav success = buffer_get_int(&m); 821e73e9afaSDag-Erling Smørgrav if (success == 0) { 822545d5ecaSDag-Erling Smørgrav debug3("%s: no challenge", __func__); 823545d5ecaSDag-Erling Smørgrav buffer_free(&m); 824545d5ecaSDag-Erling Smørgrav return (-1); 825545d5ecaSDag-Erling Smørgrav } 826545d5ecaSDag-Erling Smørgrav 827545d5ecaSDag-Erling Smørgrav /* Get the challenge, and format the response */ 828545d5ecaSDag-Erling Smørgrav challenge = buffer_get_string(&m, NULL); 829545d5ecaSDag-Erling Smørgrav buffer_free(&m); 830545d5ecaSDag-Erling Smørgrav 831545d5ecaSDag-Erling Smørgrav debug3("%s: received challenge: %s", __func__, challenge); 832545d5ecaSDag-Erling Smørgrav 833545d5ecaSDag-Erling Smørgrav mm_chall_setup(name, infotxt, numprompts, prompts, echo_on); 834545d5ecaSDag-Erling Smørgrav 835333ee039SDag-Erling Smørgrav xasprintf(*prompts, "%s%s", challenge, SKEY_PROMPT); 836e4a9863fSDag-Erling Smørgrav free(challenge); 837545d5ecaSDag-Erling Smørgrav 838545d5ecaSDag-Erling Smørgrav return (0); 839545d5ecaSDag-Erling Smørgrav } 840545d5ecaSDag-Erling Smørgrav 841545d5ecaSDag-Erling Smørgrav int 842545d5ecaSDag-Erling Smørgrav mm_skey_respond(void *ctx, u_int numresponses, char **responses) 843545d5ecaSDag-Erling Smørgrav { 844545d5ecaSDag-Erling Smørgrav Buffer m; 845545d5ecaSDag-Erling Smørgrav int authok; 846545d5ecaSDag-Erling Smørgrav 847545d5ecaSDag-Erling Smørgrav debug3("%s: entering", __func__); 848545d5ecaSDag-Erling Smørgrav if (numresponses != 1) 849545d5ecaSDag-Erling Smørgrav return (-1); 850545d5ecaSDag-Erling Smørgrav 851545d5ecaSDag-Erling Smørgrav buffer_init(&m); 852545d5ecaSDag-Erling Smørgrav buffer_put_cstring(&m, responses[0]); 853545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SKEYRESPOND, &m); 854545d5ecaSDag-Erling Smørgrav 855545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, 856545d5ecaSDag-Erling Smørgrav MONITOR_ANS_SKEYRESPOND, &m); 857545d5ecaSDag-Erling Smørgrav 858545d5ecaSDag-Erling Smørgrav authok = buffer_get_int(&m); 859545d5ecaSDag-Erling Smørgrav buffer_free(&m); 860545d5ecaSDag-Erling Smørgrav 861545d5ecaSDag-Erling Smørgrav return ((authok == 0) ? -1 : 0); 862545d5ecaSDag-Erling Smørgrav } 86321e764dfSDag-Erling Smørgrav #endif /* SKEY */ 864545d5ecaSDag-Erling Smørgrav 865545d5ecaSDag-Erling Smørgrav void 866545d5ecaSDag-Erling Smørgrav mm_ssh1_session_id(u_char session_id[16]) 867545d5ecaSDag-Erling Smørgrav { 868545d5ecaSDag-Erling Smørgrav Buffer m; 869545d5ecaSDag-Erling Smørgrav int i; 870545d5ecaSDag-Erling Smørgrav 871545d5ecaSDag-Erling Smørgrav debug3("%s entering", __func__); 872545d5ecaSDag-Erling Smørgrav 873545d5ecaSDag-Erling Smørgrav buffer_init(&m); 874545d5ecaSDag-Erling Smørgrav for (i = 0; i < 16; i++) 875545d5ecaSDag-Erling Smørgrav buffer_put_char(&m, session_id[i]); 876545d5ecaSDag-Erling Smørgrav 877545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SESSID, &m); 878545d5ecaSDag-Erling Smørgrav buffer_free(&m); 879545d5ecaSDag-Erling Smørgrav } 880545d5ecaSDag-Erling Smørgrav 881a0ee8cc6SDag-Erling Smørgrav #ifdef WITH_SSH1 882545d5ecaSDag-Erling Smørgrav int 883545d5ecaSDag-Erling Smørgrav mm_auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey) 884545d5ecaSDag-Erling Smørgrav { 885545d5ecaSDag-Erling Smørgrav Buffer m; 886545d5ecaSDag-Erling Smørgrav Key *key; 887545d5ecaSDag-Erling Smørgrav u_char *blob; 888545d5ecaSDag-Erling Smørgrav u_int blen; 889e73e9afaSDag-Erling Smørgrav int allowed = 0, have_forced = 0; 890545d5ecaSDag-Erling Smørgrav 891545d5ecaSDag-Erling Smørgrav debug3("%s entering", __func__); 892545d5ecaSDag-Erling Smørgrav 893545d5ecaSDag-Erling Smørgrav buffer_init(&m); 894545d5ecaSDag-Erling Smørgrav buffer_put_bignum2(&m, client_n); 895545d5ecaSDag-Erling Smørgrav 896545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSAKEYALLOWED, &m); 897545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSAKEYALLOWED, &m); 898545d5ecaSDag-Erling Smørgrav 899545d5ecaSDag-Erling Smørgrav allowed = buffer_get_int(&m); 900545d5ecaSDag-Erling Smørgrav 901e73e9afaSDag-Erling Smørgrav /* fake forced command */ 902e73e9afaSDag-Erling Smørgrav auth_clear_options(); 903e73e9afaSDag-Erling Smørgrav have_forced = buffer_get_int(&m); 904e73e9afaSDag-Erling Smørgrav forced_command = have_forced ? xstrdup("true") : NULL; 905e73e9afaSDag-Erling Smørgrav 906545d5ecaSDag-Erling Smørgrav if (allowed && rkey != NULL) { 907545d5ecaSDag-Erling Smørgrav blob = buffer_get_string(&m, &blen); 908545d5ecaSDag-Erling Smørgrav if ((key = key_from_blob(blob, blen)) == NULL) 909545d5ecaSDag-Erling Smørgrav fatal("%s: key_from_blob failed", __func__); 910545d5ecaSDag-Erling Smørgrav *rkey = key; 911e4a9863fSDag-Erling Smørgrav free(blob); 912545d5ecaSDag-Erling Smørgrav } 913545d5ecaSDag-Erling Smørgrav buffer_free(&m); 914545d5ecaSDag-Erling Smørgrav 915545d5ecaSDag-Erling Smørgrav return (allowed); 916545d5ecaSDag-Erling Smørgrav } 917545d5ecaSDag-Erling Smørgrav 918545d5ecaSDag-Erling Smørgrav BIGNUM * 919545d5ecaSDag-Erling Smørgrav mm_auth_rsa_generate_challenge(Key *key) 920545d5ecaSDag-Erling Smørgrav { 921545d5ecaSDag-Erling Smørgrav Buffer m; 922545d5ecaSDag-Erling Smørgrav BIGNUM *challenge; 923545d5ecaSDag-Erling Smørgrav u_char *blob; 924545d5ecaSDag-Erling Smørgrav u_int blen; 925545d5ecaSDag-Erling Smørgrav 926545d5ecaSDag-Erling Smørgrav debug3("%s entering", __func__); 927545d5ecaSDag-Erling Smørgrav 928545d5ecaSDag-Erling Smørgrav if ((challenge = BN_new()) == NULL) 929545d5ecaSDag-Erling Smørgrav fatal("%s: BN_new failed", __func__); 930545d5ecaSDag-Erling Smørgrav 931545d5ecaSDag-Erling Smørgrav key->type = KEY_RSA; /* XXX cheat for key_to_blob */ 932545d5ecaSDag-Erling Smørgrav if (key_to_blob(key, &blob, &blen) == 0) 933545d5ecaSDag-Erling Smørgrav fatal("%s: key_to_blob failed", __func__); 934545d5ecaSDag-Erling Smørgrav key->type = KEY_RSA1; 935545d5ecaSDag-Erling Smørgrav 936545d5ecaSDag-Erling Smørgrav buffer_init(&m); 937545d5ecaSDag-Erling Smørgrav buffer_put_string(&m, blob, blen); 938e4a9863fSDag-Erling Smørgrav free(blob); 939545d5ecaSDag-Erling Smørgrav 940545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSACHALLENGE, &m); 941545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSACHALLENGE, &m); 942545d5ecaSDag-Erling Smørgrav 943545d5ecaSDag-Erling Smørgrav buffer_get_bignum2(&m, challenge); 944545d5ecaSDag-Erling Smørgrav buffer_free(&m); 945545d5ecaSDag-Erling Smørgrav 946545d5ecaSDag-Erling Smørgrav return (challenge); 947545d5ecaSDag-Erling Smørgrav } 948545d5ecaSDag-Erling Smørgrav 949545d5ecaSDag-Erling Smørgrav int 950545d5ecaSDag-Erling Smørgrav mm_auth_rsa_verify_response(Key *key, BIGNUM *p, u_char response[16]) 951545d5ecaSDag-Erling Smørgrav { 952545d5ecaSDag-Erling Smørgrav Buffer m; 953545d5ecaSDag-Erling Smørgrav u_char *blob; 954545d5ecaSDag-Erling Smørgrav u_int blen; 955545d5ecaSDag-Erling Smørgrav int success = 0; 956545d5ecaSDag-Erling Smørgrav 957545d5ecaSDag-Erling Smørgrav debug3("%s entering", __func__); 958545d5ecaSDag-Erling Smørgrav 959545d5ecaSDag-Erling Smørgrav key->type = KEY_RSA; /* XXX cheat for key_to_blob */ 960545d5ecaSDag-Erling Smørgrav if (key_to_blob(key, &blob, &blen) == 0) 961545d5ecaSDag-Erling Smørgrav fatal("%s: key_to_blob failed", __func__); 962545d5ecaSDag-Erling Smørgrav key->type = KEY_RSA1; 963545d5ecaSDag-Erling Smørgrav 964545d5ecaSDag-Erling Smørgrav buffer_init(&m); 965545d5ecaSDag-Erling Smørgrav buffer_put_string(&m, blob, blen); 966545d5ecaSDag-Erling Smørgrav buffer_put_string(&m, response, 16); 967e4a9863fSDag-Erling Smørgrav free(blob); 968545d5ecaSDag-Erling Smørgrav 969545d5ecaSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSARESPONSE, &m); 970545d5ecaSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSARESPONSE, &m); 971545d5ecaSDag-Erling Smørgrav 972545d5ecaSDag-Erling Smørgrav success = buffer_get_int(&m); 973545d5ecaSDag-Erling Smørgrav buffer_free(&m); 974545d5ecaSDag-Erling Smørgrav 975545d5ecaSDag-Erling Smørgrav return (success); 976545d5ecaSDag-Erling Smørgrav } 977a0ee8cc6SDag-Erling Smørgrav #endif 978f388f5efSDag-Erling Smørgrav 979aa49c926SDag-Erling Smørgrav #ifdef SSH_AUDIT_EVENTS 980aa49c926SDag-Erling Smørgrav void 981aa49c926SDag-Erling Smørgrav mm_audit_event(ssh_audit_event_t event) 982aa49c926SDag-Erling Smørgrav { 983aa49c926SDag-Erling Smørgrav Buffer m; 984aa49c926SDag-Erling Smørgrav 985aa49c926SDag-Erling Smørgrav debug3("%s entering", __func__); 986aa49c926SDag-Erling Smørgrav 987aa49c926SDag-Erling Smørgrav buffer_init(&m); 988aa49c926SDag-Erling Smørgrav buffer_put_int(&m, event); 989aa49c926SDag-Erling Smørgrav 990aa49c926SDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_EVENT, &m); 991aa49c926SDag-Erling Smørgrav buffer_free(&m); 992aa49c926SDag-Erling Smørgrav } 993aa49c926SDag-Erling Smørgrav 994aa49c926SDag-Erling Smørgrav void 995aa49c926SDag-Erling Smørgrav mm_audit_run_command(const char *command) 996aa49c926SDag-Erling Smørgrav { 997aa49c926SDag-Erling Smørgrav Buffer m; 998aa49c926SDag-Erling Smørgrav 999aa49c926SDag-Erling Smørgrav debug3("%s entering command %s", __func__, command); 1000aa49c926SDag-Erling Smørgrav 1001aa49c926SDag-Erling Smørgrav buffer_init(&m); 1002aa49c926SDag-Erling Smørgrav buffer_put_cstring(&m, command); 1003aa49c926SDag-Erling Smørgrav 1004aa49c926SDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, &m); 1005aa49c926SDag-Erling Smørgrav buffer_free(&m); 1006aa49c926SDag-Erling Smørgrav } 1007aa49c926SDag-Erling Smørgrav #endif /* SSH_AUDIT_EVENTS */ 1008aa49c926SDag-Erling Smørgrav 1009cf2b5f3bSDag-Erling Smørgrav #ifdef GSSAPI 1010cf2b5f3bSDag-Erling Smørgrav OM_uint32 101121e764dfSDag-Erling Smørgrav mm_ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID goid) 1012f388f5efSDag-Erling Smørgrav { 1013f388f5efSDag-Erling Smørgrav Buffer m; 1014cf2b5f3bSDag-Erling Smørgrav OM_uint32 major; 1015f388f5efSDag-Erling Smørgrav 1016cf2b5f3bSDag-Erling Smørgrav /* Client doesn't get to see the context */ 1017cf2b5f3bSDag-Erling Smørgrav *ctx = NULL; 1018f388f5efSDag-Erling Smørgrav 1019f388f5efSDag-Erling Smørgrav buffer_init(&m); 102021e764dfSDag-Erling Smørgrav buffer_put_string(&m, goid->elements, goid->length); 1021f388f5efSDag-Erling Smørgrav 1022cf2b5f3bSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSETUP, &m); 1023cf2b5f3bSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSETUP, &m); 1024f388f5efSDag-Erling Smørgrav 1025cf2b5f3bSDag-Erling Smørgrav major = buffer_get_int(&m); 1026cf2b5f3bSDag-Erling Smørgrav 1027f388f5efSDag-Erling Smørgrav buffer_free(&m); 1028cf2b5f3bSDag-Erling Smørgrav return (major); 1029f388f5efSDag-Erling Smørgrav } 1030f388f5efSDag-Erling Smørgrav 1031cf2b5f3bSDag-Erling Smørgrav OM_uint32 1032cf2b5f3bSDag-Erling Smørgrav mm_ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *in, 1033cf2b5f3bSDag-Erling Smørgrav gss_buffer_desc *out, OM_uint32 *flags) 1034f388f5efSDag-Erling Smørgrav { 1035f388f5efSDag-Erling Smørgrav Buffer m; 1036cf2b5f3bSDag-Erling Smørgrav OM_uint32 major; 1037f388f5efSDag-Erling Smørgrav u_int len; 1038f388f5efSDag-Erling Smørgrav 1039cf2b5f3bSDag-Erling Smørgrav buffer_init(&m); 1040cf2b5f3bSDag-Erling Smørgrav buffer_put_string(&m, in->value, in->length); 1041cf2b5f3bSDag-Erling Smørgrav 1042cf2b5f3bSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSTEP, &m); 1043cf2b5f3bSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSTEP, &m); 1044cf2b5f3bSDag-Erling Smørgrav 1045cf2b5f3bSDag-Erling Smørgrav major = buffer_get_int(&m); 1046cf2b5f3bSDag-Erling Smørgrav out->value = buffer_get_string(&m, &len); 1047cf2b5f3bSDag-Erling Smørgrav out->length = len; 1048cf2b5f3bSDag-Erling Smørgrav if (flags) 1049cf2b5f3bSDag-Erling Smørgrav *flags = buffer_get_int(&m); 1050f388f5efSDag-Erling Smørgrav 1051f388f5efSDag-Erling Smørgrav buffer_free(&m); 1052cf2b5f3bSDag-Erling Smørgrav 1053cf2b5f3bSDag-Erling Smørgrav return (major); 1054f388f5efSDag-Erling Smørgrav } 1055cf2b5f3bSDag-Erling Smørgrav 10561ec0d754SDag-Erling Smørgrav OM_uint32 10571ec0d754SDag-Erling Smørgrav mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) 10581ec0d754SDag-Erling Smørgrav { 10591ec0d754SDag-Erling Smørgrav Buffer m; 10601ec0d754SDag-Erling Smørgrav OM_uint32 major; 10611ec0d754SDag-Erling Smørgrav 10621ec0d754SDag-Erling Smørgrav buffer_init(&m); 10631ec0d754SDag-Erling Smørgrav buffer_put_string(&m, gssbuf->value, gssbuf->length); 10641ec0d754SDag-Erling Smørgrav buffer_put_string(&m, gssmic->value, gssmic->length); 10651ec0d754SDag-Erling Smørgrav 10661ec0d754SDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSCHECKMIC, &m); 10671ec0d754SDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSCHECKMIC, 10681ec0d754SDag-Erling Smørgrav &m); 10691ec0d754SDag-Erling Smørgrav 10701ec0d754SDag-Erling Smørgrav major = buffer_get_int(&m); 10711ec0d754SDag-Erling Smørgrav buffer_free(&m); 10721ec0d754SDag-Erling Smørgrav return(major); 10731ec0d754SDag-Erling Smørgrav } 10741ec0d754SDag-Erling Smørgrav 1075cf2b5f3bSDag-Erling Smørgrav int 1076cf2b5f3bSDag-Erling Smørgrav mm_ssh_gssapi_userok(char *user) 1077cf2b5f3bSDag-Erling Smørgrav { 1078cf2b5f3bSDag-Erling Smørgrav Buffer m; 1079cf2b5f3bSDag-Erling Smørgrav int authenticated = 0; 1080cf2b5f3bSDag-Erling Smørgrav 1081cf2b5f3bSDag-Erling Smørgrav buffer_init(&m); 1082cf2b5f3bSDag-Erling Smørgrav 1083cf2b5f3bSDag-Erling Smørgrav mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, &m); 1084cf2b5f3bSDag-Erling Smørgrav mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUSEROK, 1085cf2b5f3bSDag-Erling Smørgrav &m); 1086cf2b5f3bSDag-Erling Smørgrav 1087cf2b5f3bSDag-Erling Smørgrav authenticated = buffer_get_int(&m); 1088cf2b5f3bSDag-Erling Smørgrav 1089cf2b5f3bSDag-Erling Smørgrav buffer_free(&m); 1090cf2b5f3bSDag-Erling Smørgrav debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not "); 1091cf2b5f3bSDag-Erling Smørgrav return (authenticated); 1092cf2b5f3bSDag-Erling Smørgrav } 1093cf2b5f3bSDag-Erling Smørgrav #endif /* GSSAPI */ 1094cce7d346SDag-Erling Smørgrav 1095