monitor_wrap.c revision 113911
198675Sdes/* 298675Sdes * Copyright 2002 Niels Provos <provos@citi.umich.edu> 398675Sdes * Copyright 2002 Markus Friedl <markus@openbsd.org> 498675Sdes * All rights reserved. 598675Sdes * 698675Sdes * Redistribution and use in source and binary forms, with or without 798675Sdes * modification, are permitted provided that the following conditions 898675Sdes * are met: 998675Sdes * 1. Redistributions of source code must retain the above copyright 1098675Sdes * notice, this list of conditions and the following disclaimer. 1198675Sdes * 2. Redistributions in binary form must reproduce the above copyright 1298675Sdes * notice, this list of conditions and the following disclaimer in the 1398675Sdes * documentation and/or other materials provided with the distribution. 1498675Sdes * 1598675Sdes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1698675Sdes * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1798675Sdes * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1898675Sdes * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 1998675Sdes * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2098675Sdes * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2198675Sdes * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2298675Sdes * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2398675Sdes * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2498675Sdes * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2598675Sdes */ 2698675Sdes 2798675Sdes#include "includes.h" 28113911SdesRCSID("$OpenBSD: monitor_wrap.c,v 1.24 2003/04/01 10:22:21 markus Exp $"); 2999052SdesRCSID("$FreeBSD: head/crypto/openssh/monitor_wrap.c 113911 2003-04-23 17:13:13Z des $"); 3098675Sdes 3198675Sdes#include <openssl/bn.h> 3298675Sdes#include <openssl/dh.h> 3398675Sdes 3498675Sdes#include "ssh.h" 3598675Sdes#include "dh.h" 3698675Sdes#include "kex.h" 3798675Sdes#include "auth.h" 38113911Sdes#include "auth-options.h" 3998675Sdes#include "buffer.h" 4098675Sdes#include "bufaux.h" 4198675Sdes#include "packet.h" 4298675Sdes#include "mac.h" 4398675Sdes#include "log.h" 4498675Sdes#include "zlib.h" 4598675Sdes#include "monitor.h" 4698675Sdes#include "monitor_wrap.h" 4798675Sdes#include "xmalloc.h" 4898675Sdes#include "atomicio.h" 4998675Sdes#include "monitor_fdpass.h" 5098675Sdes#include "getput.h" 5198675Sdes 5298675Sdes#include "auth.h" 5398675Sdes#include "channels.h" 5498675Sdes#include "session.h" 5598675Sdes 5698675Sdes/* Imports */ 5798675Sdesextern int compat20; 5898675Sdesextern Newkeys *newkeys[]; 5998675Sdesextern z_stream incoming_stream; 6098675Sdesextern z_stream outgoing_stream; 6198675Sdesextern struct monitor *pmonitor; 6298675Sdesextern Buffer input, output; 6398675Sdes 6498675Sdesvoid 6598675Sdesmm_request_send(int socket, enum monitor_reqtype type, Buffer *m) 6698675Sdes{ 67106130Sdes u_int mlen = buffer_len(m); 6898675Sdes u_char buf[5]; 6998675Sdes 7098675Sdes debug3("%s entering: type %d", __func__, type); 7198675Sdes 7298675Sdes PUT_32BIT(buf, mlen + 1); 7398675Sdes buf[4] = (u_char) type; /* 1st byte of payload is mesg-type */ 7498675Sdes if (atomicio(write, socket, buf, sizeof(buf)) != sizeof(buf)) 7598675Sdes fatal("%s: write", __func__); 7698675Sdes if (atomicio(write, socket, buffer_ptr(m), mlen) != mlen) 7798675Sdes fatal("%s: write", __func__); 7898675Sdes} 7998675Sdes 8098675Sdesvoid 8198675Sdesmm_request_receive(int socket, Buffer *m) 8298675Sdes{ 8398675Sdes u_char buf[4]; 84106130Sdes u_int msg_len; 8598675Sdes ssize_t res; 8698675Sdes 8798675Sdes debug3("%s entering", __func__); 8898675Sdes 8998675Sdes res = atomicio(read, socket, buf, sizeof(buf)); 9098675Sdes if (res != sizeof(buf)) { 9198675Sdes if (res == 0) 9298675Sdes fatal_cleanup(); 9398675Sdes fatal("%s: read: %ld", __func__, (long)res); 9498675Sdes } 9598675Sdes msg_len = GET_32BIT(buf); 9698675Sdes if (msg_len > 256 * 1024) 9798675Sdes fatal("%s: read: bad msg_len %d", __func__, msg_len); 9898675Sdes buffer_clear(m); 9998675Sdes buffer_append_space(m, msg_len); 10098675Sdes res = atomicio(read, socket, buffer_ptr(m), msg_len); 10198675Sdes if (res != msg_len) 10298675Sdes fatal("%s: read: %ld != msg_len", __func__, (long)res); 10398675Sdes} 10498675Sdes 10598675Sdesvoid 10698675Sdesmm_request_receive_expect(int socket, enum monitor_reqtype type, Buffer *m) 10798675Sdes{ 10898675Sdes u_char rtype; 10998675Sdes 11098675Sdes debug3("%s entering: type %d", __func__, type); 11198675Sdes 11298675Sdes mm_request_receive(socket, m); 11398675Sdes rtype = buffer_get_char(m); 11498675Sdes if (rtype != type) 11598675Sdes fatal("%s: read: rtype %d != type %d", __func__, 11698675Sdes rtype, type); 11798675Sdes} 11898675Sdes 11998675SdesDH * 12098675Sdesmm_choose_dh(int min, int nbits, int max) 12198675Sdes{ 12298675Sdes BIGNUM *p, *g; 12398675Sdes int success = 0; 12498675Sdes Buffer m; 12598675Sdes 12698675Sdes buffer_init(&m); 12798675Sdes buffer_put_int(&m, min); 12898675Sdes buffer_put_int(&m, nbits); 12998675Sdes buffer_put_int(&m, max); 13098675Sdes 13198675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_MODULI, &m); 13298675Sdes 13398675Sdes debug3("%s: waiting for MONITOR_ANS_MODULI", __func__); 13498675Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_MODULI, &m); 13598675Sdes 13698675Sdes success = buffer_get_char(&m); 13798675Sdes if (success == 0) 13898675Sdes fatal("%s: MONITOR_ANS_MODULI failed", __func__); 13998675Sdes 14098675Sdes if ((p = BN_new()) == NULL) 14198675Sdes fatal("%s: BN_new failed", __func__); 14298675Sdes if ((g = BN_new()) == NULL) 14398675Sdes fatal("%s: BN_new failed", __func__); 14498675Sdes buffer_get_bignum2(&m, p); 14598675Sdes buffer_get_bignum2(&m, g); 14698675Sdes 14798675Sdes debug3("%s: remaining %d", __func__, buffer_len(&m)); 14898675Sdes buffer_free(&m); 14998675Sdes 15098675Sdes return (dh_new_group(g, p)); 15198675Sdes} 15298675Sdes 15398675Sdesint 15498675Sdesmm_key_sign(Key *key, u_char **sigp, u_int *lenp, u_char *data, u_int datalen) 15598675Sdes{ 15698675Sdes Kex *kex = *pmonitor->m_pkex; 15798675Sdes Buffer m; 15898675Sdes 15998675Sdes debug3("%s entering", __func__); 16098675Sdes 16198675Sdes buffer_init(&m); 16298675Sdes buffer_put_int(&m, kex->host_key_index(key)); 16398675Sdes buffer_put_string(&m, data, datalen); 16498675Sdes 16598675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SIGN, &m); 16698675Sdes 16798675Sdes debug3("%s: waiting for MONITOR_ANS_SIGN", __func__); 16898675Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SIGN, &m); 16998675Sdes *sigp = buffer_get_string(&m, lenp); 17098675Sdes buffer_free(&m); 17198675Sdes 17298675Sdes return (0); 17398675Sdes} 17498675Sdes 17598675Sdesstruct passwd * 17698675Sdesmm_getpwnamallow(const char *login) 17798675Sdes{ 17898675Sdes Buffer m; 17998675Sdes struct passwd *pw; 18098675Sdes u_int pwlen; 18198675Sdes 18298675Sdes debug3("%s entering", __func__); 18398675Sdes 18498675Sdes buffer_init(&m); 18598675Sdes buffer_put_cstring(&m, login); 18698675Sdes 18798675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PWNAM, &m); 18898675Sdes 18998675Sdes debug3("%s: waiting for MONITOR_ANS_PWNAM", __func__); 19098675Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PWNAM, &m); 19198675Sdes 19298675Sdes if (buffer_get_char(&m) == 0) { 19398675Sdes buffer_free(&m); 19498675Sdes return (NULL); 19598675Sdes } 19698675Sdes pw = buffer_get_string(&m, &pwlen); 19798675Sdes if (pwlen != sizeof(struct passwd)) 19898675Sdes fatal("%s: struct passwd size mismatch", __func__); 19998675Sdes pw->pw_name = buffer_get_string(&m, NULL); 20098675Sdes pw->pw_passwd = buffer_get_string(&m, NULL); 20198675Sdes pw->pw_gecos = buffer_get_string(&m, NULL); 20298937Sdes#ifdef HAVE_PW_CLASS_IN_PASSWD 20398675Sdes pw->pw_class = buffer_get_string(&m, NULL); 20498937Sdes#endif 20598675Sdes pw->pw_dir = buffer_get_string(&m, NULL); 20698675Sdes pw->pw_shell = buffer_get_string(&m, NULL); 20798675Sdes buffer_free(&m); 20898675Sdes 20998675Sdes return (pw); 21098675Sdes} 21198675Sdes 212106130Sdeschar *mm_auth2_read_banner(void) 21398675Sdes{ 21498675Sdes Buffer m; 21598675Sdes char *banner; 21698675Sdes 21798675Sdes debug3("%s entering", __func__); 21898675Sdes 21998675Sdes buffer_init(&m); 22098675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTH2_READ_BANNER, &m); 22198675Sdes buffer_clear(&m); 22298675Sdes 22398675Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUTH2_READ_BANNER, &m); 22498675Sdes banner = buffer_get_string(&m, NULL); 22598675Sdes buffer_free(&m); 22698675Sdes 22798675Sdes return (banner); 22898675Sdes} 22998675Sdes 23098675Sdes/* Inform the privileged process about service and style */ 23198675Sdes 23298675Sdesvoid 23398675Sdesmm_inform_authserv(char *service, char *style) 23498675Sdes{ 23598675Sdes Buffer m; 23698675Sdes 23798675Sdes debug3("%s entering", __func__); 23898675Sdes 23998675Sdes buffer_init(&m); 24098675Sdes buffer_put_cstring(&m, service); 24198675Sdes buffer_put_cstring(&m, style ? style : ""); 24298675Sdes 24398675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHSERV, &m); 24498675Sdes 24598675Sdes buffer_free(&m); 24698675Sdes} 24798675Sdes 24898675Sdes/* Do the password authentication */ 24998675Sdesint 25098675Sdesmm_auth_password(Authctxt *authctxt, char *password) 25198675Sdes{ 25298675Sdes Buffer m; 25398675Sdes int authenticated = 0; 25498675Sdes 25598675Sdes debug3("%s entering", __func__); 25698675Sdes 25798675Sdes buffer_init(&m); 25898675Sdes buffer_put_cstring(&m, password); 25998675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHPASSWORD, &m); 26098675Sdes 26198675Sdes debug3("%s: waiting for MONITOR_ANS_AUTHPASSWORD", __func__); 26298675Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUTHPASSWORD, &m); 26398675Sdes 26498675Sdes authenticated = buffer_get_int(&m); 26598675Sdes 26698675Sdes buffer_free(&m); 26798675Sdes 26898675Sdes debug3("%s: user %sauthenticated", 26998675Sdes __func__, authenticated ? "" : "not "); 27098675Sdes return (authenticated); 27198675Sdes} 27298675Sdes 27398675Sdesint 27498675Sdesmm_user_key_allowed(struct passwd *pw, Key *key) 27598675Sdes{ 27698675Sdes return (mm_key_allowed(MM_USERKEY, NULL, NULL, key)); 27798675Sdes} 27898675Sdes 27998675Sdesint 28098675Sdesmm_hostbased_key_allowed(struct passwd *pw, char *user, char *host, 28198675Sdes Key *key) 28298675Sdes{ 28398675Sdes return (mm_key_allowed(MM_HOSTKEY, user, host, key)); 28498675Sdes} 28598675Sdes 28698675Sdesint 28798675Sdesmm_auth_rhosts_rsa_key_allowed(struct passwd *pw, char *user, 28898675Sdes char *host, Key *key) 28998675Sdes{ 29098675Sdes int ret; 29198675Sdes 29298675Sdes key->type = KEY_RSA; /* XXX hack for key_to_blob */ 29398675Sdes ret = mm_key_allowed(MM_RSAHOSTKEY, user, host, key); 29498675Sdes key->type = KEY_RSA1; 29598675Sdes return (ret); 29698675Sdes} 29798675Sdes 29898675Sdesstatic void 29998675Sdesmm_send_debug(Buffer *m) 30098675Sdes{ 30198675Sdes char *msg; 30298675Sdes 30398675Sdes while (buffer_len(m)) { 30498675Sdes msg = buffer_get_string(m, NULL); 30598675Sdes debug3("%s: Sending debug: %s", __func__, msg); 30698675Sdes packet_send_debug("%s", msg); 30798675Sdes xfree(msg); 30898675Sdes } 30998675Sdes} 31098675Sdes 31198675Sdesint 31298675Sdesmm_key_allowed(enum mm_keytype type, char *user, char *host, Key *key) 31398675Sdes{ 31498675Sdes Buffer m; 31598675Sdes u_char *blob; 31698675Sdes u_int len; 317113911Sdes int allowed = 0, have_forced = 0; 31898675Sdes 31998675Sdes debug3("%s entering", __func__); 32098675Sdes 32198675Sdes /* Convert the key to a blob and the pass it over */ 32298675Sdes if (!key_to_blob(key, &blob, &len)) 32398675Sdes return (0); 32498675Sdes 32598675Sdes buffer_init(&m); 32698675Sdes buffer_put_int(&m, type); 32798675Sdes buffer_put_cstring(&m, user ? user : ""); 32898675Sdes buffer_put_cstring(&m, host ? host : ""); 32998675Sdes buffer_put_string(&m, blob, len); 33098675Sdes xfree(blob); 33198675Sdes 33298675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYALLOWED, &m); 33398675Sdes 33498675Sdes debug3("%s: waiting for MONITOR_ANS_KEYALLOWED", __func__); 33598675Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYALLOWED, &m); 33698675Sdes 33798675Sdes allowed = buffer_get_int(&m); 33898675Sdes 339113911Sdes /* fake forced command */ 340113911Sdes auth_clear_options(); 341113911Sdes have_forced = buffer_get_int(&m); 342113911Sdes forced_command = have_forced ? xstrdup("true") : NULL; 343113911Sdes 34498675Sdes /* Send potential debug messages */ 34598675Sdes mm_send_debug(&m); 34698675Sdes 34798675Sdes buffer_free(&m); 34898675Sdes 34998675Sdes return (allowed); 35098675Sdes} 35198675Sdes 35298675Sdes/* 35398675Sdes * This key verify needs to send the key type along, because the 35498675Sdes * privileged parent makes the decision if the key is allowed 35598675Sdes * for authentication. 35698675Sdes */ 35798675Sdes 35898675Sdesint 35998675Sdesmm_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen) 36098675Sdes{ 36198675Sdes Buffer m; 36298675Sdes u_char *blob; 36398675Sdes u_int len; 36498675Sdes int verified = 0; 36598675Sdes 36698675Sdes debug3("%s entering", __func__); 36798675Sdes 36898675Sdes /* Convert the key to a blob and the pass it over */ 36998675Sdes if (!key_to_blob(key, &blob, &len)) 37098675Sdes return (0); 37198675Sdes 37298675Sdes buffer_init(&m); 37398675Sdes buffer_put_string(&m, blob, len); 37498675Sdes buffer_put_string(&m, sig, siglen); 37598675Sdes buffer_put_string(&m, data, datalen); 37698675Sdes xfree(blob); 37798675Sdes 37898675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYVERIFY, &m); 37998675Sdes 38098675Sdes debug3("%s: waiting for MONITOR_ANS_KEYVERIFY", __func__); 38198675Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYVERIFY, &m); 38298675Sdes 38398675Sdes verified = buffer_get_int(&m); 38498675Sdes 38598675Sdes buffer_free(&m); 38698675Sdes 38798675Sdes return (verified); 38898675Sdes} 38998675Sdes 39098675Sdes/* Export key state after authentication */ 39198675SdesNewkeys * 39298675Sdesmm_newkeys_from_blob(u_char *blob, int blen) 39398675Sdes{ 39498675Sdes Buffer b; 39598675Sdes u_int len; 39698675Sdes Newkeys *newkey = NULL; 39798675Sdes Enc *enc; 39898675Sdes Mac *mac; 39998675Sdes Comp *comp; 40098675Sdes 40198675Sdes debug3("%s: %p(%d)", __func__, blob, blen); 40298675Sdes#ifdef DEBUG_PK 40398675Sdes dump_base64(stderr, blob, blen); 40498675Sdes#endif 40598675Sdes buffer_init(&b); 40698675Sdes buffer_append(&b, blob, blen); 40798675Sdes 40898675Sdes newkey = xmalloc(sizeof(*newkey)); 40998675Sdes enc = &newkey->enc; 41098675Sdes mac = &newkey->mac; 41198675Sdes comp = &newkey->comp; 41298675Sdes 41398675Sdes /* Enc structure */ 41498675Sdes enc->name = buffer_get_string(&b, NULL); 41598675Sdes buffer_get(&b, &enc->cipher, sizeof(enc->cipher)); 41698675Sdes enc->enabled = buffer_get_int(&b); 41798675Sdes enc->block_size = buffer_get_int(&b); 41898675Sdes enc->key = buffer_get_string(&b, &enc->key_len); 41998675Sdes enc->iv = buffer_get_string(&b, &len); 42098675Sdes if (len != enc->block_size) 421106130Sdes fatal("%s: bad ivlen: expected %u != %u", __func__, 42298675Sdes enc->block_size, len); 42398675Sdes 42498675Sdes if (enc->name == NULL || cipher_by_name(enc->name) != enc->cipher) 42598675Sdes fatal("%s: bad cipher name %s or pointer %p", __func__, 42698675Sdes enc->name, enc->cipher); 42798675Sdes 42898675Sdes /* Mac structure */ 42998675Sdes mac->name = buffer_get_string(&b, NULL); 43098675Sdes if (mac->name == NULL || mac_init(mac, mac->name) == -1) 43198675Sdes fatal("%s: can not init mac %s", __func__, mac->name); 43298675Sdes mac->enabled = buffer_get_int(&b); 43398675Sdes mac->key = buffer_get_string(&b, &len); 43498675Sdes if (len > mac->key_len) 435106130Sdes fatal("%s: bad mac key length: %u > %d", __func__, len, 43698675Sdes mac->key_len); 43798675Sdes mac->key_len = len; 43898675Sdes 43998675Sdes /* Comp structure */ 44098675Sdes comp->type = buffer_get_int(&b); 44198675Sdes comp->enabled = buffer_get_int(&b); 44298675Sdes comp->name = buffer_get_string(&b, NULL); 44398675Sdes 44498675Sdes len = buffer_len(&b); 44598675Sdes if (len != 0) 446106130Sdes error("newkeys_from_blob: remaining bytes in blob %u", len); 44798675Sdes buffer_free(&b); 44898675Sdes return (newkey); 44998675Sdes} 45098675Sdes 45198675Sdesint 45298675Sdesmm_newkeys_to_blob(int mode, u_char **blobp, u_int *lenp) 45398675Sdes{ 45498675Sdes Buffer b; 45598675Sdes int len; 45698675Sdes Enc *enc; 45798675Sdes Mac *mac; 45898675Sdes Comp *comp; 45998675Sdes Newkeys *newkey = newkeys[mode]; 46098675Sdes 46198675Sdes debug3("%s: converting %p", __func__, newkey); 46298675Sdes 46398675Sdes if (newkey == NULL) { 46498675Sdes error("%s: newkey == NULL", __func__); 46598675Sdes return 0; 46698675Sdes } 46798675Sdes enc = &newkey->enc; 46898675Sdes mac = &newkey->mac; 46998675Sdes comp = &newkey->comp; 47098675Sdes 47198675Sdes buffer_init(&b); 47298675Sdes /* Enc structure */ 47398675Sdes buffer_put_cstring(&b, enc->name); 47498675Sdes /* The cipher struct is constant and shared, you export pointer */ 47598675Sdes buffer_append(&b, &enc->cipher, sizeof(enc->cipher)); 47698675Sdes buffer_put_int(&b, enc->enabled); 47798675Sdes buffer_put_int(&b, enc->block_size); 47898675Sdes buffer_put_string(&b, enc->key, enc->key_len); 47998675Sdes packet_get_keyiv(mode, enc->iv, enc->block_size); 48098675Sdes buffer_put_string(&b, enc->iv, enc->block_size); 48198675Sdes 48298675Sdes /* Mac structure */ 48398675Sdes buffer_put_cstring(&b, mac->name); 48498675Sdes buffer_put_int(&b, mac->enabled); 48598675Sdes buffer_put_string(&b, mac->key, mac->key_len); 48698675Sdes 48798675Sdes /* Comp structure */ 48898675Sdes buffer_put_int(&b, comp->type); 48998675Sdes buffer_put_int(&b, comp->enabled); 49098675Sdes buffer_put_cstring(&b, comp->name); 49198675Sdes 49298675Sdes len = buffer_len(&b); 493106130Sdes if (lenp != NULL) 494106130Sdes *lenp = len; 495106130Sdes if (blobp != NULL) { 496106130Sdes *blobp = xmalloc(len); 497106130Sdes memcpy(*blobp, buffer_ptr(&b), len); 498106130Sdes } 49998675Sdes memset(buffer_ptr(&b), 0, len); 50098675Sdes buffer_free(&b); 50198675Sdes return len; 50298675Sdes} 50398675Sdes 50498675Sdesstatic void 50598675Sdesmm_send_kex(Buffer *m, Kex *kex) 50698675Sdes{ 50798675Sdes buffer_put_string(m, kex->session_id, kex->session_id_len); 50898675Sdes buffer_put_int(m, kex->we_need); 50998675Sdes buffer_put_int(m, kex->hostkey_type); 51098675Sdes buffer_put_int(m, kex->kex_type); 51198675Sdes buffer_put_string(m, buffer_ptr(&kex->my), buffer_len(&kex->my)); 51298675Sdes buffer_put_string(m, buffer_ptr(&kex->peer), buffer_len(&kex->peer)); 51398675Sdes buffer_put_int(m, kex->flags); 51498675Sdes buffer_put_cstring(m, kex->client_version_string); 51598675Sdes buffer_put_cstring(m, kex->server_version_string); 51698675Sdes} 51798675Sdes 51898675Sdesvoid 51998675Sdesmm_send_keystate(struct monitor *pmonitor) 52098675Sdes{ 52198675Sdes Buffer m; 52298675Sdes u_char *blob, *p; 52398675Sdes u_int bloblen, plen; 52498675Sdes 52598675Sdes buffer_init(&m); 52698675Sdes 52798675Sdes if (!compat20) { 52898675Sdes u_char iv[24]; 52998675Sdes u_char *key; 53098675Sdes u_int ivlen, keylen; 53198675Sdes 53298675Sdes buffer_put_int(&m, packet_get_protocol_flags()); 53398675Sdes 53498675Sdes buffer_put_int(&m, packet_get_ssh1_cipher()); 53598675Sdes 53698675Sdes debug3("%s: Sending ssh1 KEY+IV", __func__); 53798675Sdes keylen = packet_get_encryption_key(NULL); 53898675Sdes key = xmalloc(keylen+1); /* add 1 if keylen == 0 */ 53998675Sdes keylen = packet_get_encryption_key(key); 54098675Sdes buffer_put_string(&m, key, keylen); 54198675Sdes memset(key, 0, keylen); 54298675Sdes xfree(key); 54398675Sdes 54498675Sdes ivlen = packet_get_keyiv_len(MODE_OUT); 54598675Sdes packet_get_keyiv(MODE_OUT, iv, ivlen); 54698675Sdes buffer_put_string(&m, iv, ivlen); 54798675Sdes ivlen = packet_get_keyiv_len(MODE_OUT); 54898675Sdes packet_get_keyiv(MODE_IN, iv, ivlen); 54998675Sdes buffer_put_string(&m, iv, ivlen); 55098675Sdes goto skip; 55198675Sdes } else { 55298675Sdes /* Kex for rekeying */ 55398675Sdes mm_send_kex(&m, *pmonitor->m_pkex); 55498675Sdes } 55598675Sdes 55698675Sdes debug3("%s: Sending new keys: %p %p", 55798675Sdes __func__, newkeys[MODE_OUT], newkeys[MODE_IN]); 55898675Sdes 55998675Sdes /* Keys from Kex */ 56098675Sdes if (!mm_newkeys_to_blob(MODE_OUT, &blob, &bloblen)) 56198675Sdes fatal("%s: conversion of newkeys failed", __func__); 56298675Sdes 56398675Sdes buffer_put_string(&m, blob, bloblen); 56498675Sdes xfree(blob); 56598675Sdes 56698675Sdes if (!mm_newkeys_to_blob(MODE_IN, &blob, &bloblen)) 56798675Sdes fatal("%s: conversion of newkeys failed", __func__); 56898675Sdes 56998675Sdes buffer_put_string(&m, blob, bloblen); 57098675Sdes xfree(blob); 57198675Sdes 57298675Sdes buffer_put_int(&m, packet_get_seqnr(MODE_OUT)); 57398675Sdes buffer_put_int(&m, packet_get_seqnr(MODE_IN)); 57498675Sdes 57598675Sdes debug3("%s: New keys have been sent", __func__); 57698675Sdes skip: 57798675Sdes /* More key context */ 57898675Sdes plen = packet_get_keycontext(MODE_OUT, NULL); 57998675Sdes p = xmalloc(plen+1); 58098675Sdes packet_get_keycontext(MODE_OUT, p); 58198675Sdes buffer_put_string(&m, p, plen); 58298675Sdes xfree(p); 58398675Sdes 58498675Sdes plen = packet_get_keycontext(MODE_IN, NULL); 58598675Sdes p = xmalloc(plen+1); 58698675Sdes packet_get_keycontext(MODE_IN, p); 58798675Sdes buffer_put_string(&m, p, plen); 58898675Sdes xfree(p); 58998675Sdes 59098675Sdes /* Compression state */ 59198675Sdes debug3("%s: Sending compression state", __func__); 59298675Sdes buffer_put_string(&m, &outgoing_stream, sizeof(outgoing_stream)); 59398675Sdes buffer_put_string(&m, &incoming_stream, sizeof(incoming_stream)); 59498675Sdes 59598675Sdes /* Network I/O buffers */ 59698675Sdes buffer_put_string(&m, buffer_ptr(&input), buffer_len(&input)); 59798675Sdes buffer_put_string(&m, buffer_ptr(&output), buffer_len(&output)); 59898675Sdes 59998675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYEXPORT, &m); 60098675Sdes debug3("%s: Finished sending state", __func__); 60198675Sdes 60298675Sdes buffer_free(&m); 60398675Sdes} 60498675Sdes 60598675Sdesint 60698675Sdesmm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen) 60798675Sdes{ 60898675Sdes Buffer m; 609106130Sdes char *p; 61098675Sdes int success = 0; 61198675Sdes 61298675Sdes buffer_init(&m); 61398675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTY, &m); 61498675Sdes 61598675Sdes debug3("%s: waiting for MONITOR_ANS_PTY", __func__); 61698675Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PTY, &m); 61798675Sdes 61898675Sdes success = buffer_get_int(&m); 61998675Sdes if (success == 0) { 62098675Sdes debug3("%s: pty alloc failed", __func__); 62198675Sdes buffer_free(&m); 62298675Sdes return (0); 62398675Sdes } 62498675Sdes p = buffer_get_string(&m, NULL); 62598675Sdes buffer_free(&m); 62698675Sdes 62798675Sdes strlcpy(namebuf, p, namebuflen); /* Possible truncation */ 62898675Sdes xfree(p); 62998675Sdes 63098675Sdes *ptyfd = mm_receive_fd(pmonitor->m_recvfd); 63198675Sdes *ttyfd = mm_receive_fd(pmonitor->m_recvfd); 63298675Sdes 63398675Sdes /* Success */ 63498675Sdes return (1); 63598675Sdes} 63698675Sdes 63798675Sdesvoid 63898675Sdesmm_session_pty_cleanup2(void *session) 63998675Sdes{ 64098675Sdes Session *s = session; 64198675Sdes Buffer m; 64298675Sdes 64398675Sdes if (s->ttyfd == -1) 64498675Sdes return; 64598675Sdes buffer_init(&m); 64698675Sdes buffer_put_cstring(&m, s->tty); 64798675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTYCLEANUP, &m); 64898675Sdes buffer_free(&m); 64998675Sdes 65098675Sdes /* closed dup'ed master */ 65198675Sdes if (close(s->ptymaster) < 0) 65298675Sdes error("close(s->ptymaster): %s", strerror(errno)); 65398675Sdes 65498675Sdes /* unlink pty from session */ 65598675Sdes s->ttyfd = -1; 65698675Sdes} 65798675Sdes 65898937Sdes#ifdef USE_PAM 65998937Sdesvoid 66098937Sdesmm_start_pam(char *user) 66198937Sdes{ 66298937Sdes Buffer m; 66398937Sdes 66498937Sdes debug3("%s entering", __func__); 66598937Sdes 66698937Sdes buffer_init(&m); 66798937Sdes buffer_put_cstring(&m, user); 66898937Sdes 66998937Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_START, &m); 67098937Sdes 67198937Sdes buffer_free(&m); 67298937Sdes} 67399052Sdes 67499052Sdesvoid * 67599052Sdesmm_pam_init_ctx(Authctxt *authctxt) 67699052Sdes{ 67799052Sdes Buffer m; 67899052Sdes int success; 67999052Sdes 68099052Sdes debug3("%s", __func__); 68199052Sdes buffer_init(&m); 68299052Sdes buffer_put_cstring(&m, authctxt->user); 68399052Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_INIT_CTX, &m); 68499052Sdes debug3("%s: waiting for MONITOR_ANS_PAM_INIT_CTX", __func__); 68599052Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_INIT_CTX, &m); 68699052Sdes success = buffer_get_int(&m); 68799052Sdes if (success == 0) { 68899052Sdes debug3("%s: pam_init_ctx failed", __func__); 68999052Sdes buffer_free(&m); 69099052Sdes return (NULL); 69199052Sdes } 69299052Sdes buffer_free(&m); 69399052Sdes return (authctxt); 69499052Sdes} 69599052Sdes 69699052Sdesint 69799052Sdesmm_pam_query(void *ctx, char **name, char **info, 69899052Sdes u_int *num, char ***prompts, u_int **echo_on) 69999052Sdes{ 70099052Sdes Buffer m; 70199052Sdes int i, ret; 70299052Sdes 70399052Sdes debug3("%s", __func__); 70499052Sdes buffer_init(&m); 70599052Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_QUERY, &m); 70699052Sdes debug3("%s: waiting for MONITOR_ANS_PAM_QUERY", __func__); 70799052Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_QUERY, &m); 70899052Sdes ret = buffer_get_int(&m); 70999052Sdes debug3("%s: pam_query returned %d", __func__, ret); 71099052Sdes *name = buffer_get_string(&m, NULL); 71199052Sdes *info = buffer_get_string(&m, NULL); 71299052Sdes *num = buffer_get_int(&m); 71399052Sdes *prompts = xmalloc((*num + 1) * sizeof(char *)); 71499052Sdes *echo_on = xmalloc((*num + 1) * sizeof(u_int)); 71599052Sdes for (i = 0; i < *num; ++i) { 71699052Sdes (*prompts)[i] = buffer_get_string(&m, NULL); 71799052Sdes (*echo_on)[i] = buffer_get_int(&m); 71899052Sdes } 71999052Sdes buffer_free(&m); 72099052Sdes return (ret); 72199052Sdes} 72299052Sdes 72399052Sdesint 72499052Sdesmm_pam_respond(void *ctx, u_int num, char **resp) 72599052Sdes{ 72699052Sdes Buffer m; 72799052Sdes int i, ret; 72899052Sdes 72999052Sdes debug3("%s", __func__); 73099052Sdes buffer_init(&m); 73199052Sdes buffer_put_int(&m, num); 73299052Sdes for (i = 0; i < num; ++i) 73399052Sdes buffer_put_cstring(&m, resp[i]); 73499052Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_RESPOND, &m); 73599052Sdes debug3("%s: waiting for MONITOR_ANS_PAM_RESPOND", __func__); 73699052Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_RESPOND, &m); 73799052Sdes ret = buffer_get_int(&m); 73899052Sdes debug3("%s: pam_respond returned %d", __func__, ret); 73999052Sdes buffer_free(&m); 74099052Sdes return (ret); 74199052Sdes} 74299052Sdes 74399052Sdesvoid 74499052Sdesmm_pam_free_ctx(void *ctxtp) 74599052Sdes{ 74699052Sdes Buffer m; 74799052Sdes 74899052Sdes debug3("%s", __func__); 74999052Sdes buffer_init(&m); 75099052Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_FREE_CTX, &m); 75199052Sdes debug3("%s: waiting for MONITOR_ANS_PAM_FREE_CTX", __func__); 75299052Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_FREE_CTX, &m); 75399052Sdes buffer_free(&m); 75499052Sdes} 75598937Sdes#endif /* USE_PAM */ 75698937Sdes 75798675Sdes/* Request process termination */ 75898675Sdes 75998675Sdesvoid 76098675Sdesmm_terminate(void) 76198675Sdes{ 76298675Sdes Buffer m; 76398675Sdes 76498675Sdes buffer_init(&m); 76598675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_TERM, &m); 76698675Sdes buffer_free(&m); 76798675Sdes} 76898675Sdes 76998675Sdesint 77098675Sdesmm_ssh1_session_key(BIGNUM *num) 77198675Sdes{ 77298675Sdes int rsafail; 77398675Sdes Buffer m; 77498675Sdes 77598675Sdes buffer_init(&m); 77698675Sdes buffer_put_bignum2(&m, num); 77798675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SESSKEY, &m); 77898675Sdes 77998675Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SESSKEY, &m); 78098675Sdes 78198675Sdes rsafail = buffer_get_int(&m); 78298675Sdes buffer_get_bignum2(&m, num); 78398675Sdes 78498675Sdes buffer_free(&m); 78598675Sdes 78698675Sdes return (rsafail); 78798675Sdes} 78898675Sdes 78998675Sdesstatic void 79098675Sdesmm_chall_setup(char **name, char **infotxt, u_int *numprompts, 79198675Sdes char ***prompts, u_int **echo_on) 79298675Sdes{ 79398675Sdes *name = xstrdup(""); 79498675Sdes *infotxt = xstrdup(""); 79598675Sdes *numprompts = 1; 796106130Sdes *prompts = xmalloc(*numprompts * sizeof(char *)); 79798675Sdes *echo_on = xmalloc(*numprompts * sizeof(u_int)); 79898675Sdes (*echo_on)[0] = 0; 79998675Sdes} 80098675Sdes 80198675Sdesint 80298675Sdesmm_bsdauth_query(void *ctx, char **name, char **infotxt, 80398675Sdes u_int *numprompts, char ***prompts, u_int **echo_on) 80498675Sdes{ 80598675Sdes Buffer m; 806113911Sdes u_int success; 80798675Sdes char *challenge; 80898675Sdes 80998675Sdes debug3("%s: entering", __func__); 81098675Sdes 81198675Sdes buffer_init(&m); 81298675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHQUERY, &m); 81398675Sdes 81498675Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_BSDAUTHQUERY, 81598675Sdes &m); 816113911Sdes success = buffer_get_int(&m); 817113911Sdes if (success == 0) { 81898675Sdes debug3("%s: no challenge", __func__); 81998675Sdes buffer_free(&m); 82098675Sdes return (-1); 82198675Sdes } 82298675Sdes 82398675Sdes /* Get the challenge, and format the response */ 82498675Sdes challenge = buffer_get_string(&m, NULL); 82598675Sdes buffer_free(&m); 82698675Sdes 82798675Sdes mm_chall_setup(name, infotxt, numprompts, prompts, echo_on); 82898675Sdes (*prompts)[0] = challenge; 82998675Sdes 83098675Sdes debug3("%s: received challenge: %s", __func__, challenge); 83198675Sdes 83298675Sdes return (0); 83398675Sdes} 83498675Sdes 83598675Sdesint 83698675Sdesmm_bsdauth_respond(void *ctx, u_int numresponses, char **responses) 83798675Sdes{ 83898675Sdes Buffer m; 83998675Sdes int authok; 84098675Sdes 84198675Sdes debug3("%s: entering", __func__); 84298675Sdes if (numresponses != 1) 84398675Sdes return (-1); 84498675Sdes 84598675Sdes buffer_init(&m); 84698675Sdes buffer_put_cstring(&m, responses[0]); 84798675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHRESPOND, &m); 84898675Sdes 84998675Sdes mm_request_receive_expect(pmonitor->m_recvfd, 85098675Sdes MONITOR_ANS_BSDAUTHRESPOND, &m); 85198675Sdes 85298675Sdes authok = buffer_get_int(&m); 85398675Sdes buffer_free(&m); 85498675Sdes 85598675Sdes return ((authok == 0) ? -1 : 0); 85698675Sdes} 85798675Sdes 85899046Sdes#ifdef SKEY 85998675Sdesint 86098675Sdesmm_skey_query(void *ctx, char **name, char **infotxt, 86198675Sdes u_int *numprompts, char ***prompts, u_int **echo_on) 86298675Sdes{ 86398675Sdes Buffer m; 864113911Sdes int len; 865113911Sdes u_int success; 86698675Sdes char *p, *challenge; 86798675Sdes 86898675Sdes debug3("%s: entering", __func__); 86998675Sdes 87098675Sdes buffer_init(&m); 87198675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SKEYQUERY, &m); 87298675Sdes 87398675Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SKEYQUERY, 87498675Sdes &m); 875113911Sdes success = buffer_get_int(&m); 876113911Sdes if (success == 0) { 87798675Sdes debug3("%s: no challenge", __func__); 87898675Sdes buffer_free(&m); 87998675Sdes return (-1); 88098675Sdes } 88198675Sdes 88298675Sdes /* Get the challenge, and format the response */ 88398675Sdes challenge = buffer_get_string(&m, NULL); 88498675Sdes buffer_free(&m); 88598675Sdes 88698675Sdes debug3("%s: received challenge: %s", __func__, challenge); 88798675Sdes 88898675Sdes mm_chall_setup(name, infotxt, numprompts, prompts, echo_on); 88998675Sdes 89098675Sdes len = strlen(challenge) + strlen(SKEY_PROMPT) + 1; 89198675Sdes p = xmalloc(len); 89298675Sdes strlcpy(p, challenge, len); 89398675Sdes strlcat(p, SKEY_PROMPT, len); 89498675Sdes (*prompts)[0] = p; 89598675Sdes xfree(challenge); 89698675Sdes 89798675Sdes return (0); 89898675Sdes} 89998675Sdes 90098675Sdesint 90198675Sdesmm_skey_respond(void *ctx, u_int numresponses, char **responses) 90298675Sdes{ 90398675Sdes Buffer m; 90498675Sdes int authok; 90598675Sdes 90698675Sdes debug3("%s: entering", __func__); 90798675Sdes if (numresponses != 1) 90898675Sdes return (-1); 90998675Sdes 91098675Sdes buffer_init(&m); 91198675Sdes buffer_put_cstring(&m, responses[0]); 91298675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SKEYRESPOND, &m); 91398675Sdes 91498675Sdes mm_request_receive_expect(pmonitor->m_recvfd, 91598675Sdes MONITOR_ANS_SKEYRESPOND, &m); 91698675Sdes 91798675Sdes authok = buffer_get_int(&m); 91898675Sdes buffer_free(&m); 91998675Sdes 92098675Sdes return ((authok == 0) ? -1 : 0); 92198675Sdes} 92299046Sdes#endif 92398675Sdes 92498675Sdesvoid 92598675Sdesmm_ssh1_session_id(u_char session_id[16]) 92698675Sdes{ 92798675Sdes Buffer m; 92898675Sdes int i; 92998675Sdes 93098675Sdes debug3("%s entering", __func__); 93198675Sdes 93298675Sdes buffer_init(&m); 93398675Sdes for (i = 0; i < 16; i++) 93498675Sdes buffer_put_char(&m, session_id[i]); 93598675Sdes 93698675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SESSID, &m); 93798675Sdes buffer_free(&m); 93898675Sdes} 93998675Sdes 94098675Sdesint 94198675Sdesmm_auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey) 94298675Sdes{ 94398675Sdes Buffer m; 94498675Sdes Key *key; 94598675Sdes u_char *blob; 94698675Sdes u_int blen; 947113911Sdes int allowed = 0, have_forced = 0; 94898675Sdes 94998675Sdes debug3("%s entering", __func__); 95098675Sdes 95198675Sdes buffer_init(&m); 95298675Sdes buffer_put_bignum2(&m, client_n); 95398675Sdes 95498675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSAKEYALLOWED, &m); 95598675Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSAKEYALLOWED, &m); 95698675Sdes 95798675Sdes allowed = buffer_get_int(&m); 95898675Sdes 959113911Sdes /* fake forced command */ 960113911Sdes auth_clear_options(); 961113911Sdes have_forced = buffer_get_int(&m); 962113911Sdes forced_command = have_forced ? xstrdup("true") : NULL; 963113911Sdes 96498675Sdes if (allowed && rkey != NULL) { 96598675Sdes blob = buffer_get_string(&m, &blen); 96698675Sdes if ((key = key_from_blob(blob, blen)) == NULL) 96798675Sdes fatal("%s: key_from_blob failed", __func__); 96898675Sdes *rkey = key; 96998675Sdes xfree(blob); 97098675Sdes } 97198675Sdes mm_send_debug(&m); 97298675Sdes buffer_free(&m); 97398675Sdes 97498675Sdes return (allowed); 97598675Sdes} 97698675Sdes 97798675SdesBIGNUM * 97898675Sdesmm_auth_rsa_generate_challenge(Key *key) 97998675Sdes{ 98098675Sdes Buffer m; 98198675Sdes BIGNUM *challenge; 98298675Sdes u_char *blob; 98398675Sdes u_int blen; 98498675Sdes 98598675Sdes debug3("%s entering", __func__); 98698675Sdes 98798675Sdes if ((challenge = BN_new()) == NULL) 98898675Sdes fatal("%s: BN_new failed", __func__); 98998675Sdes 99098675Sdes key->type = KEY_RSA; /* XXX cheat for key_to_blob */ 99198675Sdes if (key_to_blob(key, &blob, &blen) == 0) 99298675Sdes fatal("%s: key_to_blob failed", __func__); 99398675Sdes key->type = KEY_RSA1; 99498675Sdes 99598675Sdes buffer_init(&m); 99698675Sdes buffer_put_string(&m, blob, blen); 99798675Sdes xfree(blob); 99898675Sdes 99998675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSACHALLENGE, &m); 100098675Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSACHALLENGE, &m); 100198675Sdes 100298675Sdes buffer_get_bignum2(&m, challenge); 100398675Sdes buffer_free(&m); 100498675Sdes 100598675Sdes return (challenge); 100698675Sdes} 100798675Sdes 100898675Sdesint 100998675Sdesmm_auth_rsa_verify_response(Key *key, BIGNUM *p, u_char response[16]) 101098675Sdes{ 101198675Sdes Buffer m; 101298675Sdes u_char *blob; 101398675Sdes u_int blen; 101498675Sdes int success = 0; 101598675Sdes 101698675Sdes debug3("%s entering", __func__); 101798675Sdes 101898675Sdes key->type = KEY_RSA; /* XXX cheat for key_to_blob */ 101998675Sdes if (key_to_blob(key, &blob, &blen) == 0) 102098675Sdes fatal("%s: key_to_blob failed", __func__); 102198675Sdes key->type = KEY_RSA1; 102298675Sdes 102398675Sdes buffer_init(&m); 102498675Sdes buffer_put_string(&m, blob, blen); 102598675Sdes buffer_put_string(&m, response, 16); 102698675Sdes xfree(blob); 102798675Sdes 102898675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSARESPONSE, &m); 102998675Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSARESPONSE, &m); 103098675Sdes 103198675Sdes success = buffer_get_int(&m); 103298675Sdes buffer_free(&m); 103398675Sdes 103498675Sdes return (success); 103598675Sdes} 1036106130Sdes 1037106130Sdes#ifdef KRB4 1038106130Sdesint 1039106130Sdesmm_auth_krb4(Authctxt *authctxt, void *_auth, char **client, void *_reply) 1040106130Sdes{ 1041106130Sdes KTEXT auth, reply; 1042106130Sdes Buffer m; 1043106130Sdes u_int rlen; 1044106130Sdes int success = 0; 1045106130Sdes char *p; 1046106130Sdes 1047106130Sdes debug3("%s entering", __func__); 1048106130Sdes auth = _auth; 1049106130Sdes reply = _reply; 1050106130Sdes 1051106130Sdes buffer_init(&m); 1052106130Sdes buffer_put_string(&m, auth->dat, auth->length); 1053106130Sdes 1054106130Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KRB4, &m); 1055106130Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KRB4, &m); 1056106130Sdes 1057106130Sdes success = buffer_get_int(&m); 1058106130Sdes if (success) { 1059106130Sdes *client = buffer_get_string(&m, NULL); 1060106130Sdes p = buffer_get_string(&m, &rlen); 1061106130Sdes if (rlen >= MAX_KTXT_LEN) 1062106130Sdes fatal("%s: reply from monitor too large", __func__); 1063106130Sdes reply->length = rlen; 1064106130Sdes memcpy(reply->dat, p, rlen); 1065106130Sdes memset(p, 0, rlen); 1066106130Sdes xfree(p); 1067106130Sdes } 1068106130Sdes buffer_free(&m); 1069113911Sdes return (success); 1070106130Sdes} 1071106130Sdes#endif 1072106130Sdes 1073106130Sdes#ifdef KRB5 1074106130Sdesint 1075106130Sdesmm_auth_krb5(void *ctx, void *argp, char **userp, void *resp) 1076106130Sdes{ 1077106130Sdes krb5_data *tkt, *reply; 1078106130Sdes Buffer m; 1079106130Sdes int success; 1080106130Sdes 1081106130Sdes debug3("%s entering", __func__); 1082106130Sdes tkt = (krb5_data *) argp; 1083106130Sdes reply = (krb5_data *) resp; 1084106130Sdes 1085106130Sdes buffer_init(&m); 1086106130Sdes buffer_put_string(&m, tkt->data, tkt->length); 1087106130Sdes 1088106130Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KRB5, &m); 1089106130Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KRB5, &m); 1090106130Sdes 1091106130Sdes success = buffer_get_int(&m); 1092106130Sdes if (success) { 1093106130Sdes u_int len; 1094106130Sdes 1095106130Sdes *userp = buffer_get_string(&m, NULL); 1096106130Sdes reply->data = buffer_get_string(&m, &len); 1097106130Sdes reply->length = len; 1098106130Sdes } else { 1099106130Sdes memset(reply, 0, sizeof(*reply)); 1100106130Sdes *userp = NULL; 1101106130Sdes } 1102106130Sdes 1103106130Sdes buffer_free(&m); 1104106130Sdes return (success); 1105106130Sdes} 1106106130Sdes#endif 1107