1323124Sdes/* $OpenBSD: monitor_wrap.c,v 1.88 2016/03/07 19:02:43 djm Exp $ */ 298675Sdes/* 398675Sdes * Copyright 2002 Niels Provos <provos@citi.umich.edu> 498675Sdes * Copyright 2002 Markus Friedl <markus@openbsd.org> 598675Sdes * All rights reserved. 698675Sdes * 798675Sdes * Redistribution and use in source and binary forms, with or without 898675Sdes * modification, are permitted provided that the following conditions 998675Sdes * are met: 1098675Sdes * 1. Redistributions of source code must retain the above copyright 1198675Sdes * notice, this list of conditions and the following disclaimer. 1298675Sdes * 2. Redistributions in binary form must reproduce the above copyright 1398675Sdes * notice, this list of conditions and the following disclaimer in the 1498675Sdes * documentation and/or other materials provided with the distribution. 1598675Sdes * 1698675Sdes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1798675Sdes * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1898675Sdes * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1998675Sdes * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2098675Sdes * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2198675Sdes * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2298675Sdes * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2398675Sdes * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2498675Sdes * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2598675Sdes * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2698675Sdes */ 2798675Sdes 2898675Sdes#include "includes.h" 2998675Sdes 30162856Sdes#include <sys/types.h> 31162856Sdes#include <sys/uio.h> 32162856Sdes 33162856Sdes#include <errno.h> 34162856Sdes#include <pwd.h> 35162856Sdes#include <signal.h> 36162856Sdes#include <stdarg.h> 37162856Sdes#include <stdio.h> 38162856Sdes#include <string.h> 39162856Sdes#include <unistd.h> 40162856Sdes 41295367Sdes#ifdef WITH_OPENSSL 4298675Sdes#include <openssl/bn.h> 4398675Sdes#include <openssl/dh.h> 44192595Sdes#include <openssl/evp.h> 45295367Sdes#endif 4698675Sdes 47181111Sdes#include "openbsd-compat/sys-queue.h" 48162856Sdes#include "xmalloc.h" 4998675Sdes#include "ssh.h" 50295367Sdes#ifdef WITH_OPENSSL 5198675Sdes#include "dh.h" 52295367Sdes#endif 53162856Sdes#include "buffer.h" 54162856Sdes#include "key.h" 55162856Sdes#include "cipher.h" 5698675Sdes#include "kex.h" 57162856Sdes#include "hostfile.h" 5898675Sdes#include "auth.h" 59113911Sdes#include "auth-options.h" 6098675Sdes#include "packet.h" 6198675Sdes#include "mac.h" 6298675Sdes#include "log.h" 63323124Sdes#include "auth-pam.h" 64128460Sdes#ifdef TARGET_OS_MAC /* XXX Broken krb5 headers on Mac */ 65128460Sdes#undef TARGET_OS_MAC 6698675Sdes#include "zlib.h" 67128460Sdes#define TARGET_OS_MAC 1 68128460Sdes#else 69128460Sdes#include "zlib.h" 70128460Sdes#endif 7198675Sdes#include "monitor.h" 72162856Sdes#ifdef GSSAPI 73162856Sdes#include "ssh-gss.h" 74162856Sdes#endif 7598675Sdes#include "monitor_wrap.h" 7698675Sdes#include "atomicio.h" 7798675Sdes#include "monitor_fdpass.h" 78162856Sdes#include "misc.h" 79221420Sdes#include "uuencode.h" 8098675Sdes 8198675Sdes#include "channels.h" 8298675Sdes#include "session.h" 83181111Sdes#include "servconf.h" 8498675Sdes 85295367Sdes#include "ssherr.h" 86295367Sdes 8798675Sdes/* Imports */ 8898675Sdesextern int compat20; 8998675Sdesextern z_stream incoming_stream; 9098675Sdesextern z_stream outgoing_stream; 9198675Sdesextern struct monitor *pmonitor; 92137019Sdesextern Buffer loginmsg; 93124211Sdesextern ServerOptions options; 9498675Sdes 95226046Sdesvoid 96226046Sdesmm_log_handler(LogLevel level, const char *msg, void *ctx) 97226046Sdes{ 98226046Sdes Buffer log_msg; 99226046Sdes struct monitor *mon = (struct monitor *)ctx; 100226046Sdes 101226046Sdes if (mon->m_log_sendfd == -1) 102226046Sdes fatal("%s: no log channel", __func__); 103226046Sdes 104226046Sdes buffer_init(&log_msg); 105226046Sdes /* 106226046Sdes * Placeholder for packet length. Will be filled in with the actual 107226046Sdes * packet length once the packet has been constucted. This saves 108226046Sdes * fragile math. 109226046Sdes */ 110226046Sdes buffer_put_int(&log_msg, 0); 111226046Sdes 112226046Sdes buffer_put_int(&log_msg, level); 113226046Sdes buffer_put_cstring(&log_msg, msg); 114226046Sdes put_u32(buffer_ptr(&log_msg), buffer_len(&log_msg) - 4); 115226046Sdes if (atomicio(vwrite, mon->m_log_sendfd, buffer_ptr(&log_msg), 116226046Sdes buffer_len(&log_msg)) != buffer_len(&log_msg)) 117226046Sdes fatal("%s: write: %s", __func__, strerror(errno)); 118226046Sdes buffer_free(&log_msg); 119226046Sdes} 120226046Sdes 121126277Sdesint 122126277Sdesmm_is_monitor(void) 123126277Sdes{ 124126277Sdes /* 125126277Sdes * m_pid is only set in the privileged part, and 126126277Sdes * points to the unprivileged child. 127126277Sdes */ 128126277Sdes return (pmonitor && pmonitor->m_pid > 0); 129126277Sdes} 130126277Sdes 13198675Sdesvoid 132137019Sdesmm_request_send(int sock, enum monitor_reqtype type, Buffer *m) 13398675Sdes{ 134106130Sdes u_int mlen = buffer_len(m); 13598675Sdes u_char buf[5]; 13698675Sdes 13798675Sdes debug3("%s entering: type %d", __func__, type); 13898675Sdes 139162856Sdes put_u32(buf, mlen + 1); 14098675Sdes buf[4] = (u_char) type; /* 1st byte of payload is mesg-type */ 141137019Sdes if (atomicio(vwrite, sock, buf, sizeof(buf)) != sizeof(buf)) 142149753Sdes fatal("%s: write: %s", __func__, strerror(errno)); 143137019Sdes if (atomicio(vwrite, sock, buffer_ptr(m), mlen) != mlen) 144149753Sdes fatal("%s: write: %s", __func__, strerror(errno)); 14598675Sdes} 14698675Sdes 14798675Sdesvoid 148137019Sdesmm_request_receive(int sock, Buffer *m) 14998675Sdes{ 15098675Sdes u_char buf[4]; 151106130Sdes u_int msg_len; 15298675Sdes 15398675Sdes debug3("%s entering", __func__); 15498675Sdes 155149753Sdes if (atomicio(read, sock, buf, sizeof(buf)) != sizeof(buf)) { 156149753Sdes if (errno == EPIPE) 157126277Sdes cleanup_exit(255); 158149753Sdes fatal("%s: read: %s", __func__, strerror(errno)); 15998675Sdes } 160162856Sdes msg_len = get_u32(buf); 16198675Sdes if (msg_len > 256 * 1024) 16298675Sdes fatal("%s: read: bad msg_len %d", __func__, msg_len); 16398675Sdes buffer_clear(m); 16498675Sdes buffer_append_space(m, msg_len); 165149753Sdes if (atomicio(read, sock, buffer_ptr(m), msg_len) != msg_len) 166149753Sdes fatal("%s: read: %s", __func__, strerror(errno)); 16798675Sdes} 16898675Sdes 16998675Sdesvoid 170137019Sdesmm_request_receive_expect(int sock, enum monitor_reqtype type, Buffer *m) 17198675Sdes{ 17298675Sdes u_char rtype; 17398675Sdes 17498675Sdes debug3("%s entering: type %d", __func__, type); 17598675Sdes 176137019Sdes mm_request_receive(sock, m); 17798675Sdes rtype = buffer_get_char(m); 17898675Sdes if (rtype != type) 17998675Sdes fatal("%s: read: rtype %d != type %d", __func__, 18098675Sdes rtype, type); 18198675Sdes} 18298675Sdes 183295367Sdes#ifdef WITH_OPENSSL 18498675SdesDH * 18598675Sdesmm_choose_dh(int min, int nbits, int max) 18698675Sdes{ 18798675Sdes BIGNUM *p, *g; 18898675Sdes int success = 0; 18998675Sdes Buffer m; 19098675Sdes 19198675Sdes buffer_init(&m); 19298675Sdes buffer_put_int(&m, min); 19398675Sdes buffer_put_int(&m, nbits); 19498675Sdes buffer_put_int(&m, max); 19598675Sdes 19698675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_MODULI, &m); 19798675Sdes 19898675Sdes debug3("%s: waiting for MONITOR_ANS_MODULI", __func__); 19998675Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_MODULI, &m); 20098675Sdes 20198675Sdes success = buffer_get_char(&m); 20298675Sdes if (success == 0) 20398675Sdes fatal("%s: MONITOR_ANS_MODULI failed", __func__); 20498675Sdes 20598675Sdes if ((p = BN_new()) == NULL) 20698675Sdes fatal("%s: BN_new failed", __func__); 20798675Sdes if ((g = BN_new()) == NULL) 20898675Sdes fatal("%s: BN_new failed", __func__); 20998675Sdes buffer_get_bignum2(&m, p); 21098675Sdes buffer_get_bignum2(&m, g); 21198675Sdes 21298675Sdes debug3("%s: remaining %d", __func__, buffer_len(&m)); 21398675Sdes buffer_free(&m); 21498675Sdes 21598675Sdes return (dh_new_group(g, p)); 21698675Sdes} 217295367Sdes#endif 21898675Sdes 21998675Sdesint 220295367Sdesmm_key_sign(Key *key, u_char **sigp, u_int *lenp, 221296781Sdes const u_char *data, u_int datalen, const char *hostkey_alg) 22298675Sdes{ 223295367Sdes struct kex *kex = *pmonitor->m_pkex; 22498675Sdes Buffer m; 22598675Sdes 22698675Sdes debug3("%s entering", __func__); 22798675Sdes 22898675Sdes buffer_init(&m); 229295367Sdes buffer_put_int(&m, kex->host_key_index(key, 0, active_state)); 23098675Sdes buffer_put_string(&m, data, datalen); 231296781Sdes buffer_put_cstring(&m, hostkey_alg); 23298675Sdes 23398675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SIGN, &m); 23498675Sdes 23598675Sdes debug3("%s: waiting for MONITOR_ANS_SIGN", __func__); 23698675Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SIGN, &m); 23798675Sdes *sigp = buffer_get_string(&m, lenp); 23898675Sdes buffer_free(&m); 23998675Sdes 24098675Sdes return (0); 24198675Sdes} 24298675Sdes 24398675Sdesstruct passwd * 244137019Sdesmm_getpwnamallow(const char *username) 24598675Sdes{ 24698675Sdes Buffer m; 24798675Sdes struct passwd *pw; 248226046Sdes u_int len, i; 249181111Sdes ServerOptions *newopts; 25098675Sdes 25198675Sdes debug3("%s entering", __func__); 25298675Sdes 25398675Sdes buffer_init(&m); 254137019Sdes buffer_put_cstring(&m, username); 25598675Sdes 25698675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PWNAM, &m); 25798675Sdes 25898675Sdes debug3("%s: waiting for MONITOR_ANS_PWNAM", __func__); 25998675Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PWNAM, &m); 26098675Sdes 26198675Sdes if (buffer_get_char(&m) == 0) { 262181111Sdes pw = NULL; 263181111Sdes goto out; 26498675Sdes } 265181111Sdes pw = buffer_get_string(&m, &len); 266181111Sdes if (len != sizeof(struct passwd)) 26798675Sdes fatal("%s: struct passwd size mismatch", __func__); 26898675Sdes pw->pw_name = buffer_get_string(&m, NULL); 26998675Sdes pw->pw_passwd = buffer_get_string(&m, NULL); 270255767Sdes#ifdef HAVE_STRUCT_PASSWD_PW_GECOS 27198675Sdes pw->pw_gecos = buffer_get_string(&m, NULL); 272255767Sdes#endif 273255767Sdes#ifdef HAVE_STRUCT_PASSWD_PW_CLASS 27498675Sdes pw->pw_class = buffer_get_string(&m, NULL); 27598937Sdes#endif 27698675Sdes pw->pw_dir = buffer_get_string(&m, NULL); 27798675Sdes pw->pw_shell = buffer_get_string(&m, NULL); 278181111Sdes 279181111Sdesout: 280181111Sdes /* copy options block as a Match directive may have changed some */ 281181111Sdes newopts = buffer_get_string(&m, &len); 282181111Sdes if (len != sizeof(*newopts)) 283181111Sdes fatal("%s: option block size mismatch", __func__); 284226046Sdes 285226046Sdes#define M_CP_STROPT(x) do { \ 286226046Sdes if (newopts->x != NULL) \ 287226046Sdes newopts->x = buffer_get_string(&m, NULL); \ 288226046Sdes } while (0) 289226046Sdes#define M_CP_STRARRAYOPT(x, nx) do { \ 290226046Sdes for (i = 0; i < newopts->nx; i++) \ 291226046Sdes newopts->x[i] = buffer_get_string(&m, NULL); \ 292226046Sdes } while (0) 293226046Sdes /* See comment in servconf.h */ 294226046Sdes COPY_MATCH_STRING_OPTS(); 295226046Sdes#undef M_CP_STROPT 296226046Sdes#undef M_CP_STRARRAYOPT 297226046Sdes 298181111Sdes copy_set_server_options(&options, newopts, 1); 299255767Sdes free(newopts); 300181111Sdes 30198675Sdes buffer_free(&m); 30298675Sdes 30398675Sdes return (pw); 30498675Sdes} 30598675Sdes 306126277Sdeschar * 307126277Sdesmm_auth2_read_banner(void) 30898675Sdes{ 30998675Sdes Buffer m; 31098675Sdes char *banner; 31198675Sdes 31298675Sdes debug3("%s entering", __func__); 31398675Sdes 31498675Sdes buffer_init(&m); 31598675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTH2_READ_BANNER, &m); 31698675Sdes buffer_clear(&m); 31798675Sdes 318126277Sdes mm_request_receive_expect(pmonitor->m_recvfd, 319126277Sdes MONITOR_ANS_AUTH2_READ_BANNER, &m); 32098675Sdes banner = buffer_get_string(&m, NULL); 32198675Sdes buffer_free(&m); 32298675Sdes 323126277Sdes /* treat empty banner as missing banner */ 324126277Sdes if (strlen(banner) == 0) { 325255767Sdes free(banner); 326126277Sdes banner = NULL; 327126277Sdes } 32898675Sdes return (banner); 32998675Sdes} 33098675Sdes 33198675Sdes/* Inform the privileged process about service and style */ 33298675Sdes 33398675Sdesvoid 33498675Sdesmm_inform_authserv(char *service, char *style) 33598675Sdes{ 33698675Sdes Buffer m; 33798675Sdes 33898675Sdes debug3("%s entering", __func__); 33998675Sdes 34098675Sdes buffer_init(&m); 34198675Sdes buffer_put_cstring(&m, service); 34298675Sdes buffer_put_cstring(&m, style ? style : ""); 34398675Sdes 34498675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHSERV, &m); 34598675Sdes 34698675Sdes buffer_free(&m); 34798675Sdes} 34898675Sdes 34998675Sdes/* Do the password authentication */ 35098675Sdesint 35198675Sdesmm_auth_password(Authctxt *authctxt, char *password) 35298675Sdes{ 35398675Sdes Buffer m; 35498675Sdes int authenticated = 0; 35598675Sdes 35698675Sdes debug3("%s entering", __func__); 35798675Sdes 35898675Sdes buffer_init(&m); 35998675Sdes buffer_put_cstring(&m, password); 36098675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHPASSWORD, &m); 36198675Sdes 36298675Sdes debug3("%s: waiting for MONITOR_ANS_AUTHPASSWORD", __func__); 36398675Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUTHPASSWORD, &m); 36498675Sdes 36598675Sdes authenticated = buffer_get_int(&m); 366323124Sdes#ifdef USE_PAM 367323124Sdes sshpam_set_maxtries_reached(buffer_get_int(&m)); 368323124Sdes#endif 36998675Sdes 37098675Sdes buffer_free(&m); 37198675Sdes 37298675Sdes debug3("%s: user %sauthenticated", 37398675Sdes __func__, authenticated ? "" : "not "); 37498675Sdes return (authenticated); 37598675Sdes} 37698675Sdes 37798675Sdesint 378295367Sdesmm_user_key_allowed(struct passwd *pw, Key *key, int pubkey_auth_attempt) 37998675Sdes{ 380295367Sdes return (mm_key_allowed(MM_USERKEY, NULL, NULL, key, 381295367Sdes pubkey_auth_attempt)); 38298675Sdes} 38398675Sdes 38498675Sdesint 385323124Sdesmm_hostbased_key_allowed(struct passwd *pw, const char *user, const char *host, 38698675Sdes Key *key) 38798675Sdes{ 388295367Sdes return (mm_key_allowed(MM_HOSTKEY, user, host, key, 0)); 38998675Sdes} 39098675Sdes 39198675Sdesint 392323124Sdesmm_auth_rhosts_rsa_key_allowed(struct passwd *pw, const char *user, 393323124Sdes const char *host, Key *key) 39498675Sdes{ 39598675Sdes int ret; 39698675Sdes 39798675Sdes key->type = KEY_RSA; /* XXX hack for key_to_blob */ 398295367Sdes ret = mm_key_allowed(MM_RSAHOSTKEY, user, host, key, 0); 39998675Sdes key->type = KEY_RSA1; 40098675Sdes return (ret); 40198675Sdes} 40298675Sdes 40398675Sdesint 404323124Sdesmm_key_allowed(enum mm_keytype type, const char *user, const char *host, 405323124Sdes Key *key, int pubkey_auth_attempt) 40698675Sdes{ 40798675Sdes Buffer m; 40898675Sdes u_char *blob; 40998675Sdes u_int len; 410113911Sdes int allowed = 0, have_forced = 0; 41198675Sdes 41298675Sdes debug3("%s entering", __func__); 41398675Sdes 41498675Sdes /* Convert the key to a blob and the pass it over */ 41598675Sdes if (!key_to_blob(key, &blob, &len)) 41698675Sdes return (0); 41798675Sdes 41898675Sdes buffer_init(&m); 41998675Sdes buffer_put_int(&m, type); 42098675Sdes buffer_put_cstring(&m, user ? user : ""); 42198675Sdes buffer_put_cstring(&m, host ? host : ""); 42298675Sdes buffer_put_string(&m, blob, len); 423295367Sdes buffer_put_int(&m, pubkey_auth_attempt); 424255767Sdes free(blob); 42598675Sdes 42698675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYALLOWED, &m); 42798675Sdes 42898675Sdes debug3("%s: waiting for MONITOR_ANS_KEYALLOWED", __func__); 42998675Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYALLOWED, &m); 43098675Sdes 43198675Sdes allowed = buffer_get_int(&m); 43298675Sdes 433113911Sdes /* fake forced command */ 434113911Sdes auth_clear_options(); 435113911Sdes have_forced = buffer_get_int(&m); 436113911Sdes forced_command = have_forced ? xstrdup("true") : NULL; 437113911Sdes 43898675Sdes buffer_free(&m); 43998675Sdes 44098675Sdes return (allowed); 44198675Sdes} 44298675Sdes 44398675Sdes/* 44498675Sdes * This key verify needs to send the key type along, because the 44598675Sdes * privileged parent makes the decision if the key is allowed 44698675Sdes * for authentication. 44798675Sdes */ 44898675Sdes 44998675Sdesint 45098675Sdesmm_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen) 45198675Sdes{ 45298675Sdes Buffer m; 45398675Sdes u_char *blob; 45498675Sdes u_int len; 45598675Sdes int verified = 0; 45698675Sdes 45798675Sdes debug3("%s entering", __func__); 45898675Sdes 45998675Sdes /* Convert the key to a blob and the pass it over */ 46098675Sdes if (!key_to_blob(key, &blob, &len)) 46198675Sdes return (0); 46298675Sdes 46398675Sdes buffer_init(&m); 46498675Sdes buffer_put_string(&m, blob, len); 46598675Sdes buffer_put_string(&m, sig, siglen); 46698675Sdes buffer_put_string(&m, data, datalen); 467255767Sdes free(blob); 46898675Sdes 46998675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYVERIFY, &m); 47098675Sdes 47198675Sdes debug3("%s: waiting for MONITOR_ANS_KEYVERIFY", __func__); 47298675Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYVERIFY, &m); 47398675Sdes 47498675Sdes verified = buffer_get_int(&m); 47598675Sdes 47698675Sdes buffer_free(&m); 47798675Sdes 47898675Sdes return (verified); 47998675Sdes} 48098675Sdes 48198675Sdesvoid 482137019Sdesmm_send_keystate(struct monitor *monitor) 48398675Sdes{ 484295367Sdes struct ssh *ssh = active_state; /* XXX */ 485295367Sdes struct sshbuf *m; 486295367Sdes int r; 48798675Sdes 488295367Sdes if ((m = sshbuf_new()) == NULL) 489295367Sdes fatal("%s: sshbuf_new failed", __func__); 490295367Sdes if ((r = ssh_packet_get_state(ssh, m)) != 0) 491295367Sdes fatal("%s: get_state failed: %s", 492295367Sdes __func__, ssh_err(r)); 493295367Sdes mm_request_send(monitor->m_recvfd, MONITOR_REQ_KEYEXPORT, m); 49498675Sdes debug3("%s: Finished sending state", __func__); 495295367Sdes sshbuf_free(m); 49698675Sdes} 49798675Sdes 49898675Sdesint 499162856Sdesmm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen) 50098675Sdes{ 50198675Sdes Buffer m; 502137019Sdes char *p, *msg; 503181111Sdes int success = 0, tmp1 = -1, tmp2 = -1; 50498675Sdes 505181111Sdes /* Kludge: ensure there are fds free to receive the pty/tty */ 506181111Sdes if ((tmp1 = dup(pmonitor->m_recvfd)) == -1 || 507181111Sdes (tmp2 = dup(pmonitor->m_recvfd)) == -1) { 508181111Sdes error("%s: cannot allocate fds for pty", __func__); 509181111Sdes if (tmp1 > 0) 510181111Sdes close(tmp1); 511181111Sdes if (tmp2 > 0) 512181111Sdes close(tmp2); 513181111Sdes return 0; 514181111Sdes } 515181111Sdes close(tmp1); 516181111Sdes close(tmp2); 517181111Sdes 51898675Sdes buffer_init(&m); 51998675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTY, &m); 52098675Sdes 52198675Sdes debug3("%s: waiting for MONITOR_ANS_PTY", __func__); 52298675Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PTY, &m); 52398675Sdes 52498675Sdes success = buffer_get_int(&m); 52598675Sdes if (success == 0) { 52698675Sdes debug3("%s: pty alloc failed", __func__); 52798675Sdes buffer_free(&m); 52898675Sdes return (0); 52998675Sdes } 53098675Sdes p = buffer_get_string(&m, NULL); 531137019Sdes msg = buffer_get_string(&m, NULL); 53298675Sdes buffer_free(&m); 53398675Sdes 53498675Sdes strlcpy(namebuf, p, namebuflen); /* Possible truncation */ 535255767Sdes free(p); 53698675Sdes 537137019Sdes buffer_append(&loginmsg, msg, strlen(msg)); 538255767Sdes free(msg); 539137019Sdes 540181111Sdes if ((*ptyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1 || 541181111Sdes (*ttyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1) 542181111Sdes fatal("%s: receive fds failed", __func__); 54398675Sdes 54498675Sdes /* Success */ 54598675Sdes return (1); 54698675Sdes} 54798675Sdes 54898675Sdesvoid 549126277Sdesmm_session_pty_cleanup2(Session *s) 55098675Sdes{ 55198675Sdes Buffer m; 55298675Sdes 55398675Sdes if (s->ttyfd == -1) 55498675Sdes return; 55598675Sdes buffer_init(&m); 55698675Sdes buffer_put_cstring(&m, s->tty); 55798675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTYCLEANUP, &m); 55898675Sdes buffer_free(&m); 55998675Sdes 56098675Sdes /* closed dup'ed master */ 561181111Sdes if (s->ptymaster != -1 && close(s->ptymaster) < 0) 562181111Sdes error("close(s->ptymaster/%d): %s", 563181111Sdes s->ptymaster, strerror(errno)); 56498675Sdes 56598675Sdes /* unlink pty from session */ 56698675Sdes s->ttyfd = -1; 56798675Sdes} 56898675Sdes 56998937Sdes#ifdef USE_PAM 57098937Sdesvoid 571128460Sdesmm_start_pam(Authctxt *authctxt) 57298937Sdes{ 57398937Sdes Buffer m; 57498937Sdes 57598937Sdes debug3("%s entering", __func__); 576124211Sdes if (!options.use_pam) 577124211Sdes fatal("UsePAM=no, but ended up in %s anyway", __func__); 57898937Sdes 57998937Sdes buffer_init(&m); 58098937Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_START, &m); 58198937Sdes 58298937Sdes buffer_free(&m); 58398937Sdes} 58499052Sdes 585124211Sdesu_int 586124211Sdesmm_do_pam_account(void) 587124211Sdes{ 588124211Sdes Buffer m; 589124211Sdes u_int ret; 590147005Sdes char *msg; 591124211Sdes 592124211Sdes debug3("%s entering", __func__); 593124211Sdes if (!options.use_pam) 594124211Sdes fatal("UsePAM=no, but ended up in %s anyway", __func__); 595124211Sdes 596124211Sdes buffer_init(&m); 597124211Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_ACCOUNT, &m); 598124211Sdes 599126277Sdes mm_request_receive_expect(pmonitor->m_recvfd, 600124211Sdes MONITOR_ANS_PAM_ACCOUNT, &m); 601124211Sdes ret = buffer_get_int(&m); 602147005Sdes msg = buffer_get_string(&m, NULL); 603147005Sdes buffer_append(&loginmsg, msg, strlen(msg)); 604255767Sdes free(msg); 605124211Sdes 606124211Sdes buffer_free(&m); 607126277Sdes 608124211Sdes debug3("%s returning %d", __func__, ret); 609124211Sdes 610124211Sdes return (ret); 611124211Sdes} 612124211Sdes 61399052Sdesvoid * 614124211Sdesmm_sshpam_init_ctx(Authctxt *authctxt) 61599052Sdes{ 61699052Sdes Buffer m; 61799052Sdes int success; 61899052Sdes 61999052Sdes debug3("%s", __func__); 62099052Sdes buffer_init(&m); 62199052Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_INIT_CTX, &m); 62299052Sdes debug3("%s: waiting for MONITOR_ANS_PAM_INIT_CTX", __func__); 62399052Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_INIT_CTX, &m); 62499052Sdes success = buffer_get_int(&m); 62599052Sdes if (success == 0) { 62699052Sdes debug3("%s: pam_init_ctx failed", __func__); 62799052Sdes buffer_free(&m); 62899052Sdes return (NULL); 62999052Sdes } 63099052Sdes buffer_free(&m); 63199052Sdes return (authctxt); 63299052Sdes} 63399052Sdes 63499052Sdesint 635124211Sdesmm_sshpam_query(void *ctx, char **name, char **info, 63699052Sdes u_int *num, char ***prompts, u_int **echo_on) 63799052Sdes{ 63899052Sdes Buffer m; 639149753Sdes u_int i; 640149753Sdes int ret; 64199052Sdes 64299052Sdes debug3("%s", __func__); 64399052Sdes buffer_init(&m); 64499052Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_QUERY, &m); 64599052Sdes debug3("%s: waiting for MONITOR_ANS_PAM_QUERY", __func__); 64699052Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_QUERY, &m); 64799052Sdes ret = buffer_get_int(&m); 64899052Sdes debug3("%s: pam_query returned %d", __func__, ret); 64999052Sdes *name = buffer_get_string(&m, NULL); 65099052Sdes *info = buffer_get_string(&m, NULL); 651323124Sdes sshpam_set_maxtries_reached(buffer_get_int(&m)); 65299052Sdes *num = buffer_get_int(&m); 653162856Sdes if (*num > PAM_MAX_NUM_MSG) 654162856Sdes fatal("%s: recieved %u PAM messages, expected <= %u", 655162856Sdes __func__, *num, PAM_MAX_NUM_MSG); 656162856Sdes *prompts = xcalloc((*num + 1), sizeof(char *)); 657162856Sdes *echo_on = xcalloc((*num + 1), sizeof(u_int)); 65899052Sdes for (i = 0; i < *num; ++i) { 65999052Sdes (*prompts)[i] = buffer_get_string(&m, NULL); 66099052Sdes (*echo_on)[i] = buffer_get_int(&m); 66199052Sdes } 66299052Sdes buffer_free(&m); 66399052Sdes return (ret); 66499052Sdes} 66599052Sdes 66699052Sdesint 667124211Sdesmm_sshpam_respond(void *ctx, u_int num, char **resp) 66899052Sdes{ 66999052Sdes Buffer m; 670149753Sdes u_int i; 671149753Sdes int ret; 67299052Sdes 67399052Sdes debug3("%s", __func__); 67499052Sdes buffer_init(&m); 67599052Sdes buffer_put_int(&m, num); 67699052Sdes for (i = 0; i < num; ++i) 67799052Sdes buffer_put_cstring(&m, resp[i]); 67899052Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_RESPOND, &m); 67999052Sdes debug3("%s: waiting for MONITOR_ANS_PAM_RESPOND", __func__); 68099052Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_RESPOND, &m); 68199052Sdes ret = buffer_get_int(&m); 68299052Sdes debug3("%s: pam_respond returned %d", __func__, ret); 68399052Sdes buffer_free(&m); 68499052Sdes return (ret); 68599052Sdes} 68699052Sdes 68799052Sdesvoid 688124211Sdesmm_sshpam_free_ctx(void *ctxtp) 68999052Sdes{ 69099052Sdes Buffer m; 69199052Sdes 69299052Sdes debug3("%s", __func__); 69399052Sdes buffer_init(&m); 69499052Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_FREE_CTX, &m); 69599052Sdes debug3("%s: waiting for MONITOR_ANS_PAM_FREE_CTX", __func__); 69699052Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_FREE_CTX, &m); 69799052Sdes buffer_free(&m); 69899052Sdes} 69998937Sdes#endif /* USE_PAM */ 70098937Sdes 70198675Sdes/* Request process termination */ 70298675Sdes 70398675Sdesvoid 70498675Sdesmm_terminate(void) 70598675Sdes{ 70698675Sdes Buffer m; 70798675Sdes 70898675Sdes buffer_init(&m); 70998675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_TERM, &m); 71098675Sdes buffer_free(&m); 71198675Sdes} 71298675Sdes 713295367Sdes#ifdef WITH_SSH1 71498675Sdesint 71598675Sdesmm_ssh1_session_key(BIGNUM *num) 71698675Sdes{ 71798675Sdes int rsafail; 71898675Sdes Buffer m; 71998675Sdes 72098675Sdes buffer_init(&m); 72198675Sdes buffer_put_bignum2(&m, num); 72298675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SESSKEY, &m); 72398675Sdes 72498675Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SESSKEY, &m); 72598675Sdes 72698675Sdes rsafail = buffer_get_int(&m); 72798675Sdes buffer_get_bignum2(&m, num); 72898675Sdes 72998675Sdes buffer_free(&m); 73098675Sdes 73198675Sdes return (rsafail); 73298675Sdes} 733295367Sdes#endif 73498675Sdes 73598675Sdesstatic void 73698675Sdesmm_chall_setup(char **name, char **infotxt, u_int *numprompts, 73798675Sdes char ***prompts, u_int **echo_on) 73898675Sdes{ 73998675Sdes *name = xstrdup(""); 74098675Sdes *infotxt = xstrdup(""); 74198675Sdes *numprompts = 1; 742162856Sdes *prompts = xcalloc(*numprompts, sizeof(char *)); 743162856Sdes *echo_on = xcalloc(*numprompts, sizeof(u_int)); 74498675Sdes (*echo_on)[0] = 0; 74598675Sdes} 74698675Sdes 74798675Sdesint 74898675Sdesmm_bsdauth_query(void *ctx, char **name, char **infotxt, 74998675Sdes u_int *numprompts, char ***prompts, u_int **echo_on) 75098675Sdes{ 75198675Sdes Buffer m; 752113911Sdes u_int success; 75398675Sdes char *challenge; 75498675Sdes 75598675Sdes debug3("%s: entering", __func__); 75698675Sdes 75798675Sdes buffer_init(&m); 75898675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHQUERY, &m); 75998675Sdes 76098675Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_BSDAUTHQUERY, 76198675Sdes &m); 762113911Sdes success = buffer_get_int(&m); 763113911Sdes if (success == 0) { 76498675Sdes debug3("%s: no challenge", __func__); 76598675Sdes buffer_free(&m); 76698675Sdes return (-1); 76798675Sdes } 76898675Sdes 76998675Sdes /* Get the challenge, and format the response */ 77098675Sdes challenge = buffer_get_string(&m, NULL); 77198675Sdes buffer_free(&m); 77298675Sdes 77398675Sdes mm_chall_setup(name, infotxt, numprompts, prompts, echo_on); 77498675Sdes (*prompts)[0] = challenge; 77598675Sdes 77698675Sdes debug3("%s: received challenge: %s", __func__, challenge); 77798675Sdes 77898675Sdes return (0); 77998675Sdes} 78098675Sdes 78198675Sdesint 78298675Sdesmm_bsdauth_respond(void *ctx, u_int numresponses, char **responses) 78398675Sdes{ 78498675Sdes Buffer m; 78598675Sdes int authok; 78698675Sdes 78798675Sdes debug3("%s: entering", __func__); 78898675Sdes if (numresponses != 1) 78998675Sdes return (-1); 79098675Sdes 79198675Sdes buffer_init(&m); 79298675Sdes buffer_put_cstring(&m, responses[0]); 79398675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHRESPOND, &m); 79498675Sdes 79598675Sdes mm_request_receive_expect(pmonitor->m_recvfd, 79698675Sdes MONITOR_ANS_BSDAUTHRESPOND, &m); 79798675Sdes 79898675Sdes authok = buffer_get_int(&m); 79998675Sdes buffer_free(&m); 80098675Sdes 80198675Sdes return ((authok == 0) ? -1 : 0); 80298675Sdes} 80398675Sdes 80499046Sdes#ifdef SKEY 80598675Sdesint 80698675Sdesmm_skey_query(void *ctx, char **name, char **infotxt, 80798675Sdes u_int *numprompts, char ***prompts, u_int **echo_on) 80898675Sdes{ 80998675Sdes Buffer m; 810113911Sdes u_int success; 811162856Sdes char *challenge; 81298675Sdes 81398675Sdes debug3("%s: entering", __func__); 81498675Sdes 81598675Sdes buffer_init(&m); 81698675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SKEYQUERY, &m); 81798675Sdes 81898675Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SKEYQUERY, 81998675Sdes &m); 820113911Sdes success = buffer_get_int(&m); 821113911Sdes if (success == 0) { 82298675Sdes debug3("%s: no challenge", __func__); 82398675Sdes buffer_free(&m); 82498675Sdes return (-1); 82598675Sdes } 82698675Sdes 82798675Sdes /* Get the challenge, and format the response */ 82898675Sdes challenge = buffer_get_string(&m, NULL); 82998675Sdes buffer_free(&m); 83098675Sdes 83198675Sdes debug3("%s: received challenge: %s", __func__, challenge); 83298675Sdes 83398675Sdes mm_chall_setup(name, infotxt, numprompts, prompts, echo_on); 83498675Sdes 835162856Sdes xasprintf(*prompts, "%s%s", challenge, SKEY_PROMPT); 836255767Sdes free(challenge); 83798675Sdes 83898675Sdes return (0); 83998675Sdes} 84098675Sdes 84198675Sdesint 84298675Sdesmm_skey_respond(void *ctx, u_int numresponses, char **responses) 84398675Sdes{ 84498675Sdes Buffer m; 84598675Sdes int authok; 84698675Sdes 84798675Sdes debug3("%s: entering", __func__); 84898675Sdes if (numresponses != 1) 84998675Sdes return (-1); 85098675Sdes 85198675Sdes buffer_init(&m); 85298675Sdes buffer_put_cstring(&m, responses[0]); 85398675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SKEYRESPOND, &m); 85498675Sdes 85598675Sdes mm_request_receive_expect(pmonitor->m_recvfd, 85698675Sdes MONITOR_ANS_SKEYRESPOND, &m); 85798675Sdes 85898675Sdes authok = buffer_get_int(&m); 85998675Sdes buffer_free(&m); 86098675Sdes 86198675Sdes return ((authok == 0) ? -1 : 0); 86298675Sdes} 863137019Sdes#endif /* SKEY */ 86498675Sdes 86598675Sdesvoid 86698675Sdesmm_ssh1_session_id(u_char session_id[16]) 86798675Sdes{ 86898675Sdes Buffer m; 86998675Sdes int i; 87098675Sdes 87198675Sdes debug3("%s entering", __func__); 87298675Sdes 87398675Sdes buffer_init(&m); 87498675Sdes for (i = 0; i < 16; i++) 87598675Sdes buffer_put_char(&m, session_id[i]); 87698675Sdes 87798675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SESSID, &m); 87898675Sdes buffer_free(&m); 87998675Sdes} 88098675Sdes 881295367Sdes#ifdef WITH_SSH1 88298675Sdesint 88398675Sdesmm_auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey) 88498675Sdes{ 88598675Sdes Buffer m; 88698675Sdes Key *key; 88798675Sdes u_char *blob; 88898675Sdes u_int blen; 889113911Sdes int allowed = 0, have_forced = 0; 89098675Sdes 89198675Sdes debug3("%s entering", __func__); 89298675Sdes 89398675Sdes buffer_init(&m); 89498675Sdes buffer_put_bignum2(&m, client_n); 89598675Sdes 89698675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSAKEYALLOWED, &m); 89798675Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSAKEYALLOWED, &m); 89898675Sdes 89998675Sdes allowed = buffer_get_int(&m); 90098675Sdes 901113911Sdes /* fake forced command */ 902113911Sdes auth_clear_options(); 903113911Sdes have_forced = buffer_get_int(&m); 904113911Sdes forced_command = have_forced ? xstrdup("true") : NULL; 905113911Sdes 90698675Sdes if (allowed && rkey != NULL) { 90798675Sdes blob = buffer_get_string(&m, &blen); 90898675Sdes if ((key = key_from_blob(blob, blen)) == NULL) 90998675Sdes fatal("%s: key_from_blob failed", __func__); 91098675Sdes *rkey = key; 911255767Sdes free(blob); 91298675Sdes } 91398675Sdes buffer_free(&m); 91498675Sdes 91598675Sdes return (allowed); 91698675Sdes} 91798675Sdes 91898675SdesBIGNUM * 91998675Sdesmm_auth_rsa_generate_challenge(Key *key) 92098675Sdes{ 92198675Sdes Buffer m; 92298675Sdes BIGNUM *challenge; 92398675Sdes u_char *blob; 92498675Sdes u_int blen; 92598675Sdes 92698675Sdes debug3("%s entering", __func__); 92798675Sdes 92898675Sdes if ((challenge = BN_new()) == NULL) 92998675Sdes fatal("%s: BN_new failed", __func__); 93098675Sdes 93198675Sdes key->type = KEY_RSA; /* XXX cheat for key_to_blob */ 93298675Sdes if (key_to_blob(key, &blob, &blen) == 0) 93398675Sdes fatal("%s: key_to_blob failed", __func__); 93498675Sdes key->type = KEY_RSA1; 93598675Sdes 93698675Sdes buffer_init(&m); 93798675Sdes buffer_put_string(&m, blob, blen); 938255767Sdes free(blob); 93998675Sdes 94098675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSACHALLENGE, &m); 94198675Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSACHALLENGE, &m); 94298675Sdes 94398675Sdes buffer_get_bignum2(&m, challenge); 94498675Sdes buffer_free(&m); 94598675Sdes 94698675Sdes return (challenge); 94798675Sdes} 94898675Sdes 94998675Sdesint 95098675Sdesmm_auth_rsa_verify_response(Key *key, BIGNUM *p, u_char response[16]) 95198675Sdes{ 95298675Sdes Buffer m; 95398675Sdes u_char *blob; 95498675Sdes u_int blen; 95598675Sdes int success = 0; 95698675Sdes 95798675Sdes debug3("%s entering", __func__); 95898675Sdes 95998675Sdes key->type = KEY_RSA; /* XXX cheat for key_to_blob */ 96098675Sdes if (key_to_blob(key, &blob, &blen) == 0) 96198675Sdes fatal("%s: key_to_blob failed", __func__); 96298675Sdes key->type = KEY_RSA1; 96398675Sdes 96498675Sdes buffer_init(&m); 96598675Sdes buffer_put_string(&m, blob, blen); 96698675Sdes buffer_put_string(&m, response, 16); 967255767Sdes free(blob); 96898675Sdes 96998675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSARESPONSE, &m); 97098675Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSARESPONSE, &m); 97198675Sdes 97298675Sdes success = buffer_get_int(&m); 97398675Sdes buffer_free(&m); 97498675Sdes 97598675Sdes return (success); 97698675Sdes} 977295367Sdes#endif 978106130Sdes 979147005Sdes#ifdef SSH_AUDIT_EVENTS 980147005Sdesvoid 981147005Sdesmm_audit_event(ssh_audit_event_t event) 982147005Sdes{ 983147005Sdes Buffer m; 984147005Sdes 985147005Sdes debug3("%s entering", __func__); 986147005Sdes 987147005Sdes buffer_init(&m); 988147005Sdes buffer_put_int(&m, event); 989147005Sdes 990147005Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_EVENT, &m); 991147005Sdes buffer_free(&m); 992147005Sdes} 993147005Sdes 994147005Sdesvoid 995147005Sdesmm_audit_run_command(const char *command) 996147005Sdes{ 997147005Sdes Buffer m; 998147005Sdes 999147005Sdes debug3("%s entering command %s", __func__, command); 1000147005Sdes 1001147005Sdes buffer_init(&m); 1002147005Sdes buffer_put_cstring(&m, command); 1003147005Sdes 1004147005Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUDIT_COMMAND, &m); 1005147005Sdes buffer_free(&m); 1006147005Sdes} 1007147005Sdes#endif /* SSH_AUDIT_EVENTS */ 1008147005Sdes 1009124211Sdes#ifdef GSSAPI 1010124211SdesOM_uint32 1011137019Sdesmm_ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID goid) 1012106130Sdes{ 1013124211Sdes Buffer m; 1014124211Sdes OM_uint32 major; 1015106130Sdes 1016124211Sdes /* Client doesn't get to see the context */ 1017124211Sdes *ctx = NULL; 1018106130Sdes 1019106130Sdes buffer_init(&m); 1020137019Sdes buffer_put_string(&m, goid->elements, goid->length); 1021106130Sdes 1022124211Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSETUP, &m); 1023124211Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSETUP, &m); 1024106130Sdes 1025124211Sdes major = buffer_get_int(&m); 1026124211Sdes 1027106130Sdes buffer_free(&m); 1028124211Sdes return (major); 1029106130Sdes} 1030106130Sdes 1031124211SdesOM_uint32 1032124211Sdesmm_ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *in, 1033124211Sdes gss_buffer_desc *out, OM_uint32 *flags) 1034124211Sdes{ 1035124211Sdes Buffer m; 1036124211Sdes OM_uint32 major; 1037124211Sdes u_int len; 1038124211Sdes 1039124211Sdes buffer_init(&m); 1040124211Sdes buffer_put_string(&m, in->value, in->length); 1041124211Sdes 1042124211Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSTEP, &m); 1043124211Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSTEP, &m); 1044124211Sdes 1045124211Sdes major = buffer_get_int(&m); 1046124211Sdes out->value = buffer_get_string(&m, &len); 1047124211Sdes out->length = len; 1048124211Sdes if (flags) 1049124211Sdes *flags = buffer_get_int(&m); 1050124211Sdes 1051124211Sdes buffer_free(&m); 1052124211Sdes 1053124211Sdes return (major); 1054124211Sdes} 1055124211Sdes 1056126277SdesOM_uint32 1057126277Sdesmm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) 1058126277Sdes{ 1059126277Sdes Buffer m; 1060126277Sdes OM_uint32 major; 1061126277Sdes 1062126277Sdes buffer_init(&m); 1063126277Sdes buffer_put_string(&m, gssbuf->value, gssbuf->length); 1064126277Sdes buffer_put_string(&m, gssmic->value, gssmic->length); 1065126277Sdes 1066126277Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSCHECKMIC, &m); 1067126277Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSCHECKMIC, 1068126277Sdes &m); 1069126277Sdes 1070126277Sdes major = buffer_get_int(&m); 1071126277Sdes buffer_free(&m); 1072126277Sdes return(major); 1073126277Sdes} 1074126277Sdes 1075106130Sdesint 1076124211Sdesmm_ssh_gssapi_userok(char *user) 1077106130Sdes{ 1078106130Sdes Buffer m; 1079124211Sdes int authenticated = 0; 1080106130Sdes 1081106130Sdes buffer_init(&m); 1082106130Sdes 1083124211Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, &m); 1084124211Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUSEROK, 1085124211Sdes &m); 1086106130Sdes 1087124211Sdes authenticated = buffer_get_int(&m); 1088106130Sdes 1089106130Sdes buffer_free(&m); 1090124211Sdes debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not "); 1091124211Sdes return (authenticated); 1092106130Sdes} 1093124211Sdes#endif /* GSSAPI */ 1094192595Sdes 1095