monitor_wrap.c revision 124211
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" 28124211SdesRCSID("$OpenBSD: monitor_wrap.c,v 1.31 2003/08/28 12:54:34 markus Exp $"); 2999052SdesRCSID("$FreeBSD: head/crypto/openssh/monitor_wrap.c 124211 2004-01-07 11:16:27Z 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" 51124211Sdes#include "servconf.h" 5298675Sdes 5398675Sdes#include "auth.h" 5498675Sdes#include "channels.h" 5598675Sdes#include "session.h" 5698675Sdes 57124211Sdes#ifdef GSSAPI 58124211Sdes#include "ssh-gss.h" 59124211Sdes#endif 60124211Sdes 6198675Sdes/* Imports */ 6298675Sdesextern int compat20; 6398675Sdesextern Newkeys *newkeys[]; 6498675Sdesextern z_stream incoming_stream; 6598675Sdesextern z_stream outgoing_stream; 6698675Sdesextern struct monitor *pmonitor; 6798675Sdesextern Buffer input, output; 68124211Sdesextern ServerOptions options; 6998675Sdes 7098675Sdesvoid 7198675Sdesmm_request_send(int socket, enum monitor_reqtype type, Buffer *m) 7298675Sdes{ 73106130Sdes u_int mlen = buffer_len(m); 7498675Sdes u_char buf[5]; 7598675Sdes 7698675Sdes debug3("%s entering: type %d", __func__, type); 7798675Sdes 7898675Sdes PUT_32BIT(buf, mlen + 1); 7998675Sdes buf[4] = (u_char) type; /* 1st byte of payload is mesg-type */ 80124211Sdes if (atomicio(vwrite, socket, buf, sizeof(buf)) != sizeof(buf)) 8198675Sdes fatal("%s: write", __func__); 82124211Sdes if (atomicio(vwrite, socket, buffer_ptr(m), mlen) != mlen) 8398675Sdes fatal("%s: write", __func__); 8498675Sdes} 8598675Sdes 8698675Sdesvoid 8798675Sdesmm_request_receive(int socket, Buffer *m) 8898675Sdes{ 8998675Sdes u_char buf[4]; 90106130Sdes u_int msg_len; 9198675Sdes ssize_t res; 9298675Sdes 9398675Sdes debug3("%s entering", __func__); 9498675Sdes 9598675Sdes res = atomicio(read, socket, buf, sizeof(buf)); 9698675Sdes if (res != sizeof(buf)) { 9798675Sdes if (res == 0) 9898675Sdes fatal_cleanup(); 9998675Sdes fatal("%s: read: %ld", __func__, (long)res); 10098675Sdes } 10198675Sdes msg_len = GET_32BIT(buf); 10298675Sdes if (msg_len > 256 * 1024) 10398675Sdes fatal("%s: read: bad msg_len %d", __func__, msg_len); 10498675Sdes buffer_clear(m); 10598675Sdes buffer_append_space(m, msg_len); 10698675Sdes res = atomicio(read, socket, buffer_ptr(m), msg_len); 10798675Sdes if (res != msg_len) 10898675Sdes fatal("%s: read: %ld != msg_len", __func__, (long)res); 10998675Sdes} 11098675Sdes 11198675Sdesvoid 11298675Sdesmm_request_receive_expect(int socket, enum monitor_reqtype type, Buffer *m) 11398675Sdes{ 11498675Sdes u_char rtype; 11598675Sdes 11698675Sdes debug3("%s entering: type %d", __func__, type); 11798675Sdes 11898675Sdes mm_request_receive(socket, m); 11998675Sdes rtype = buffer_get_char(m); 12098675Sdes if (rtype != type) 12198675Sdes fatal("%s: read: rtype %d != type %d", __func__, 12298675Sdes rtype, type); 12398675Sdes} 12498675Sdes 12598675SdesDH * 12698675Sdesmm_choose_dh(int min, int nbits, int max) 12798675Sdes{ 12898675Sdes BIGNUM *p, *g; 12998675Sdes int success = 0; 13098675Sdes Buffer m; 13198675Sdes 13298675Sdes buffer_init(&m); 13398675Sdes buffer_put_int(&m, min); 13498675Sdes buffer_put_int(&m, nbits); 13598675Sdes buffer_put_int(&m, max); 13698675Sdes 13798675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_MODULI, &m); 13898675Sdes 13998675Sdes debug3("%s: waiting for MONITOR_ANS_MODULI", __func__); 14098675Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_MODULI, &m); 14198675Sdes 14298675Sdes success = buffer_get_char(&m); 14398675Sdes if (success == 0) 14498675Sdes fatal("%s: MONITOR_ANS_MODULI failed", __func__); 14598675Sdes 14698675Sdes if ((p = BN_new()) == NULL) 14798675Sdes fatal("%s: BN_new failed", __func__); 14898675Sdes if ((g = BN_new()) == NULL) 14998675Sdes fatal("%s: BN_new failed", __func__); 15098675Sdes buffer_get_bignum2(&m, p); 15198675Sdes buffer_get_bignum2(&m, g); 15298675Sdes 15398675Sdes debug3("%s: remaining %d", __func__, buffer_len(&m)); 15498675Sdes buffer_free(&m); 15598675Sdes 15698675Sdes return (dh_new_group(g, p)); 15798675Sdes} 15898675Sdes 15998675Sdesint 16098675Sdesmm_key_sign(Key *key, u_char **sigp, u_int *lenp, u_char *data, u_int datalen) 16198675Sdes{ 16298675Sdes Kex *kex = *pmonitor->m_pkex; 16398675Sdes Buffer m; 16498675Sdes 16598675Sdes debug3("%s entering", __func__); 16698675Sdes 16798675Sdes buffer_init(&m); 16898675Sdes buffer_put_int(&m, kex->host_key_index(key)); 16998675Sdes buffer_put_string(&m, data, datalen); 17098675Sdes 17198675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SIGN, &m); 17298675Sdes 17398675Sdes debug3("%s: waiting for MONITOR_ANS_SIGN", __func__); 17498675Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SIGN, &m); 17598675Sdes *sigp = buffer_get_string(&m, lenp); 17698675Sdes buffer_free(&m); 17798675Sdes 17898675Sdes return (0); 17998675Sdes} 18098675Sdes 18198675Sdesstruct passwd * 18298675Sdesmm_getpwnamallow(const char *login) 18398675Sdes{ 18498675Sdes Buffer m; 18598675Sdes struct passwd *pw; 18698675Sdes u_int pwlen; 18798675Sdes 18898675Sdes debug3("%s entering", __func__); 18998675Sdes 19098675Sdes buffer_init(&m); 19198675Sdes buffer_put_cstring(&m, login); 19298675Sdes 19398675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PWNAM, &m); 19498675Sdes 19598675Sdes debug3("%s: waiting for MONITOR_ANS_PWNAM", __func__); 19698675Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PWNAM, &m); 19798675Sdes 19898675Sdes if (buffer_get_char(&m) == 0) { 19998675Sdes buffer_free(&m); 20098675Sdes return (NULL); 20198675Sdes } 20298675Sdes pw = buffer_get_string(&m, &pwlen); 20398675Sdes if (pwlen != sizeof(struct passwd)) 20498675Sdes fatal("%s: struct passwd size mismatch", __func__); 20598675Sdes pw->pw_name = buffer_get_string(&m, NULL); 20698675Sdes pw->pw_passwd = buffer_get_string(&m, NULL); 20798675Sdes pw->pw_gecos = buffer_get_string(&m, NULL); 20898937Sdes#ifdef HAVE_PW_CLASS_IN_PASSWD 20998675Sdes pw->pw_class = buffer_get_string(&m, NULL); 21098937Sdes#endif 21198675Sdes pw->pw_dir = buffer_get_string(&m, NULL); 21298675Sdes pw->pw_shell = buffer_get_string(&m, NULL); 21398675Sdes buffer_free(&m); 21498675Sdes 21598675Sdes return (pw); 21698675Sdes} 21798675Sdes 218106130Sdeschar *mm_auth2_read_banner(void) 21998675Sdes{ 22098675Sdes Buffer m; 22198675Sdes char *banner; 22298675Sdes 22398675Sdes debug3("%s entering", __func__); 22498675Sdes 22598675Sdes buffer_init(&m); 22698675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTH2_READ_BANNER, &m); 22798675Sdes buffer_clear(&m); 22898675Sdes 22998675Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUTH2_READ_BANNER, &m); 23098675Sdes banner = buffer_get_string(&m, NULL); 23198675Sdes buffer_free(&m); 23298675Sdes 23398675Sdes return (banner); 23498675Sdes} 23598675Sdes 23698675Sdes/* Inform the privileged process about service and style */ 23798675Sdes 23898675Sdesvoid 23998675Sdesmm_inform_authserv(char *service, char *style) 24098675Sdes{ 24198675Sdes Buffer m; 24298675Sdes 24398675Sdes debug3("%s entering", __func__); 24498675Sdes 24598675Sdes buffer_init(&m); 24698675Sdes buffer_put_cstring(&m, service); 24798675Sdes buffer_put_cstring(&m, style ? style : ""); 24898675Sdes 24998675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHSERV, &m); 25098675Sdes 25198675Sdes buffer_free(&m); 25298675Sdes} 25398675Sdes 25498675Sdes/* Do the password authentication */ 25598675Sdesint 25698675Sdesmm_auth_password(Authctxt *authctxt, char *password) 25798675Sdes{ 25898675Sdes Buffer m; 25998675Sdes int authenticated = 0; 26098675Sdes 26198675Sdes debug3("%s entering", __func__); 26298675Sdes 26398675Sdes buffer_init(&m); 26498675Sdes buffer_put_cstring(&m, password); 26598675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHPASSWORD, &m); 26698675Sdes 26798675Sdes debug3("%s: waiting for MONITOR_ANS_AUTHPASSWORD", __func__); 26898675Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUTHPASSWORD, &m); 26998675Sdes 27098675Sdes authenticated = buffer_get_int(&m); 27198675Sdes 27298675Sdes buffer_free(&m); 27398675Sdes 27498675Sdes debug3("%s: user %sauthenticated", 27598675Sdes __func__, authenticated ? "" : "not "); 27698675Sdes return (authenticated); 27798675Sdes} 27898675Sdes 27998675Sdesint 28098675Sdesmm_user_key_allowed(struct passwd *pw, Key *key) 28198675Sdes{ 28298675Sdes return (mm_key_allowed(MM_USERKEY, NULL, NULL, key)); 28398675Sdes} 28498675Sdes 28598675Sdesint 28698675Sdesmm_hostbased_key_allowed(struct passwd *pw, char *user, char *host, 28798675Sdes Key *key) 28898675Sdes{ 28998675Sdes return (mm_key_allowed(MM_HOSTKEY, user, host, key)); 29098675Sdes} 29198675Sdes 29298675Sdesint 29398675Sdesmm_auth_rhosts_rsa_key_allowed(struct passwd *pw, char *user, 29498675Sdes char *host, Key *key) 29598675Sdes{ 29698675Sdes int ret; 29798675Sdes 29898675Sdes key->type = KEY_RSA; /* XXX hack for key_to_blob */ 29998675Sdes ret = mm_key_allowed(MM_RSAHOSTKEY, user, host, key); 30098675Sdes key->type = KEY_RSA1; 30198675Sdes return (ret); 30298675Sdes} 30398675Sdes 30498675Sdesstatic void 30598675Sdesmm_send_debug(Buffer *m) 30698675Sdes{ 30798675Sdes char *msg; 30898675Sdes 30998675Sdes while (buffer_len(m)) { 31098675Sdes msg = buffer_get_string(m, NULL); 31198675Sdes debug3("%s: Sending debug: %s", __func__, msg); 31298675Sdes packet_send_debug("%s", msg); 31398675Sdes xfree(msg); 31498675Sdes } 31598675Sdes} 31698675Sdes 31798675Sdesint 31898675Sdesmm_key_allowed(enum mm_keytype type, char *user, char *host, Key *key) 31998675Sdes{ 32098675Sdes Buffer m; 32198675Sdes u_char *blob; 32298675Sdes u_int len; 323113911Sdes int allowed = 0, have_forced = 0; 32498675Sdes 32598675Sdes debug3("%s entering", __func__); 32698675Sdes 32798675Sdes /* Convert the key to a blob and the pass it over */ 32898675Sdes if (!key_to_blob(key, &blob, &len)) 32998675Sdes return (0); 33098675Sdes 33198675Sdes buffer_init(&m); 33298675Sdes buffer_put_int(&m, type); 33398675Sdes buffer_put_cstring(&m, user ? user : ""); 33498675Sdes buffer_put_cstring(&m, host ? host : ""); 33598675Sdes buffer_put_string(&m, blob, len); 33698675Sdes xfree(blob); 33798675Sdes 33898675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYALLOWED, &m); 33998675Sdes 34098675Sdes debug3("%s: waiting for MONITOR_ANS_KEYALLOWED", __func__); 34198675Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYALLOWED, &m); 34298675Sdes 34398675Sdes allowed = buffer_get_int(&m); 34498675Sdes 345113911Sdes /* fake forced command */ 346113911Sdes auth_clear_options(); 347113911Sdes have_forced = buffer_get_int(&m); 348113911Sdes forced_command = have_forced ? xstrdup("true") : NULL; 349113911Sdes 35098675Sdes /* Send potential debug messages */ 35198675Sdes mm_send_debug(&m); 35298675Sdes 35398675Sdes buffer_free(&m); 35498675Sdes 35598675Sdes return (allowed); 35698675Sdes} 35798675Sdes 35898675Sdes/* 35998675Sdes * This key verify needs to send the key type along, because the 36098675Sdes * privileged parent makes the decision if the key is allowed 36198675Sdes * for authentication. 36298675Sdes */ 36398675Sdes 36498675Sdesint 36598675Sdesmm_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen) 36698675Sdes{ 36798675Sdes Buffer m; 36898675Sdes u_char *blob; 36998675Sdes u_int len; 37098675Sdes int verified = 0; 37198675Sdes 37298675Sdes debug3("%s entering", __func__); 37398675Sdes 37498675Sdes /* Convert the key to a blob and the pass it over */ 37598675Sdes if (!key_to_blob(key, &blob, &len)) 37698675Sdes return (0); 37798675Sdes 37898675Sdes buffer_init(&m); 37998675Sdes buffer_put_string(&m, blob, len); 38098675Sdes buffer_put_string(&m, sig, siglen); 38198675Sdes buffer_put_string(&m, data, datalen); 38298675Sdes xfree(blob); 38398675Sdes 38498675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYVERIFY, &m); 38598675Sdes 38698675Sdes debug3("%s: waiting for MONITOR_ANS_KEYVERIFY", __func__); 38798675Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYVERIFY, &m); 38898675Sdes 38998675Sdes verified = buffer_get_int(&m); 39098675Sdes 39198675Sdes buffer_free(&m); 39298675Sdes 39398675Sdes return (verified); 39498675Sdes} 39598675Sdes 39698675Sdes/* Export key state after authentication */ 39798675SdesNewkeys * 39898675Sdesmm_newkeys_from_blob(u_char *blob, int blen) 39998675Sdes{ 40098675Sdes Buffer b; 40198675Sdes u_int len; 40298675Sdes Newkeys *newkey = NULL; 40398675Sdes Enc *enc; 40498675Sdes Mac *mac; 40598675Sdes Comp *comp; 40698675Sdes 40798675Sdes debug3("%s: %p(%d)", __func__, blob, blen); 40898675Sdes#ifdef DEBUG_PK 40998675Sdes dump_base64(stderr, blob, blen); 41098675Sdes#endif 41198675Sdes buffer_init(&b); 41298675Sdes buffer_append(&b, blob, blen); 41398675Sdes 41498675Sdes newkey = xmalloc(sizeof(*newkey)); 41598675Sdes enc = &newkey->enc; 41698675Sdes mac = &newkey->mac; 41798675Sdes comp = &newkey->comp; 41898675Sdes 41998675Sdes /* Enc structure */ 42098675Sdes enc->name = buffer_get_string(&b, NULL); 42198675Sdes buffer_get(&b, &enc->cipher, sizeof(enc->cipher)); 42298675Sdes enc->enabled = buffer_get_int(&b); 42398675Sdes enc->block_size = buffer_get_int(&b); 42498675Sdes enc->key = buffer_get_string(&b, &enc->key_len); 42598675Sdes enc->iv = buffer_get_string(&b, &len); 42698675Sdes if (len != enc->block_size) 427106130Sdes fatal("%s: bad ivlen: expected %u != %u", __func__, 42898675Sdes enc->block_size, len); 42998675Sdes 43098675Sdes if (enc->name == NULL || cipher_by_name(enc->name) != enc->cipher) 43198675Sdes fatal("%s: bad cipher name %s or pointer %p", __func__, 43298675Sdes enc->name, enc->cipher); 43398675Sdes 43498675Sdes /* Mac structure */ 43598675Sdes mac->name = buffer_get_string(&b, NULL); 43698675Sdes if (mac->name == NULL || mac_init(mac, mac->name) == -1) 43798675Sdes fatal("%s: can not init mac %s", __func__, mac->name); 43898675Sdes mac->enabled = buffer_get_int(&b); 43998675Sdes mac->key = buffer_get_string(&b, &len); 44098675Sdes if (len > mac->key_len) 441106130Sdes fatal("%s: bad mac key length: %u > %d", __func__, len, 44298675Sdes mac->key_len); 44398675Sdes mac->key_len = len; 44498675Sdes 44598675Sdes /* Comp structure */ 44698675Sdes comp->type = buffer_get_int(&b); 44798675Sdes comp->enabled = buffer_get_int(&b); 44898675Sdes comp->name = buffer_get_string(&b, NULL); 44998675Sdes 45098675Sdes len = buffer_len(&b); 45198675Sdes if (len != 0) 452106130Sdes error("newkeys_from_blob: remaining bytes in blob %u", len); 45398675Sdes buffer_free(&b); 45498675Sdes return (newkey); 45598675Sdes} 45698675Sdes 45798675Sdesint 45898675Sdesmm_newkeys_to_blob(int mode, u_char **blobp, u_int *lenp) 45998675Sdes{ 46098675Sdes Buffer b; 46198675Sdes int len; 46298675Sdes Enc *enc; 46398675Sdes Mac *mac; 46498675Sdes Comp *comp; 46598675Sdes Newkeys *newkey = newkeys[mode]; 46698675Sdes 46798675Sdes debug3("%s: converting %p", __func__, newkey); 46898675Sdes 46998675Sdes if (newkey == NULL) { 47098675Sdes error("%s: newkey == NULL", __func__); 47198675Sdes return 0; 47298675Sdes } 47398675Sdes enc = &newkey->enc; 47498675Sdes mac = &newkey->mac; 47598675Sdes comp = &newkey->comp; 47698675Sdes 47798675Sdes buffer_init(&b); 47898675Sdes /* Enc structure */ 47998675Sdes buffer_put_cstring(&b, enc->name); 48098675Sdes /* The cipher struct is constant and shared, you export pointer */ 48198675Sdes buffer_append(&b, &enc->cipher, sizeof(enc->cipher)); 48298675Sdes buffer_put_int(&b, enc->enabled); 48398675Sdes buffer_put_int(&b, enc->block_size); 48498675Sdes buffer_put_string(&b, enc->key, enc->key_len); 48598675Sdes packet_get_keyiv(mode, enc->iv, enc->block_size); 48698675Sdes buffer_put_string(&b, enc->iv, enc->block_size); 48798675Sdes 48898675Sdes /* Mac structure */ 48998675Sdes buffer_put_cstring(&b, mac->name); 49098675Sdes buffer_put_int(&b, mac->enabled); 49198675Sdes buffer_put_string(&b, mac->key, mac->key_len); 49298675Sdes 49398675Sdes /* Comp structure */ 49498675Sdes buffer_put_int(&b, comp->type); 49598675Sdes buffer_put_int(&b, comp->enabled); 49698675Sdes buffer_put_cstring(&b, comp->name); 49798675Sdes 49898675Sdes len = buffer_len(&b); 499106130Sdes if (lenp != NULL) 500106130Sdes *lenp = len; 501106130Sdes if (blobp != NULL) { 502106130Sdes *blobp = xmalloc(len); 503106130Sdes memcpy(*blobp, buffer_ptr(&b), len); 504106130Sdes } 50598675Sdes memset(buffer_ptr(&b), 0, len); 50698675Sdes buffer_free(&b); 50798675Sdes return len; 50898675Sdes} 50998675Sdes 51098675Sdesstatic void 51198675Sdesmm_send_kex(Buffer *m, Kex *kex) 51298675Sdes{ 51398675Sdes buffer_put_string(m, kex->session_id, kex->session_id_len); 51498675Sdes buffer_put_int(m, kex->we_need); 51598675Sdes buffer_put_int(m, kex->hostkey_type); 51698675Sdes buffer_put_int(m, kex->kex_type); 51798675Sdes buffer_put_string(m, buffer_ptr(&kex->my), buffer_len(&kex->my)); 51898675Sdes buffer_put_string(m, buffer_ptr(&kex->peer), buffer_len(&kex->peer)); 51998675Sdes buffer_put_int(m, kex->flags); 52098675Sdes buffer_put_cstring(m, kex->client_version_string); 52198675Sdes buffer_put_cstring(m, kex->server_version_string); 52298675Sdes} 52398675Sdes 52498675Sdesvoid 52598675Sdesmm_send_keystate(struct monitor *pmonitor) 52698675Sdes{ 52798675Sdes Buffer m; 52898675Sdes u_char *blob, *p; 52998675Sdes u_int bloblen, plen; 530124211Sdes u_int32_t seqnr, packets; 531124211Sdes u_int64_t blocks; 53298675Sdes 53398675Sdes buffer_init(&m); 53498675Sdes 53598675Sdes if (!compat20) { 53698675Sdes u_char iv[24]; 53798675Sdes u_char *key; 53898675Sdes u_int ivlen, keylen; 53998675Sdes 54098675Sdes buffer_put_int(&m, packet_get_protocol_flags()); 54198675Sdes 54298675Sdes buffer_put_int(&m, packet_get_ssh1_cipher()); 54398675Sdes 54498675Sdes debug3("%s: Sending ssh1 KEY+IV", __func__); 54598675Sdes keylen = packet_get_encryption_key(NULL); 54698675Sdes key = xmalloc(keylen+1); /* add 1 if keylen == 0 */ 54798675Sdes keylen = packet_get_encryption_key(key); 54898675Sdes buffer_put_string(&m, key, keylen); 54998675Sdes memset(key, 0, keylen); 55098675Sdes xfree(key); 55198675Sdes 55298675Sdes ivlen = packet_get_keyiv_len(MODE_OUT); 55398675Sdes packet_get_keyiv(MODE_OUT, iv, ivlen); 55498675Sdes buffer_put_string(&m, iv, ivlen); 55598675Sdes ivlen = packet_get_keyiv_len(MODE_OUT); 55698675Sdes packet_get_keyiv(MODE_IN, iv, ivlen); 55798675Sdes buffer_put_string(&m, iv, ivlen); 55898675Sdes goto skip; 55998675Sdes } else { 56098675Sdes /* Kex for rekeying */ 56198675Sdes mm_send_kex(&m, *pmonitor->m_pkex); 56298675Sdes } 56398675Sdes 56498675Sdes debug3("%s: Sending new keys: %p %p", 56598675Sdes __func__, newkeys[MODE_OUT], newkeys[MODE_IN]); 56698675Sdes 56798675Sdes /* Keys from Kex */ 56898675Sdes if (!mm_newkeys_to_blob(MODE_OUT, &blob, &bloblen)) 56998675Sdes fatal("%s: conversion of newkeys failed", __func__); 57098675Sdes 57198675Sdes buffer_put_string(&m, blob, bloblen); 57298675Sdes xfree(blob); 57398675Sdes 57498675Sdes if (!mm_newkeys_to_blob(MODE_IN, &blob, &bloblen)) 57598675Sdes fatal("%s: conversion of newkeys failed", __func__); 57698675Sdes 57798675Sdes buffer_put_string(&m, blob, bloblen); 57898675Sdes xfree(blob); 57998675Sdes 580124211Sdes packet_get_state(MODE_OUT, &seqnr, &blocks, &packets); 581124211Sdes buffer_put_int(&m, seqnr); 582124211Sdes buffer_put_int64(&m, blocks); 583124211Sdes buffer_put_int(&m, packets); 584124211Sdes packet_get_state(MODE_IN, &seqnr, &blocks, &packets); 585124211Sdes buffer_put_int(&m, seqnr); 586124211Sdes buffer_put_int64(&m, blocks); 587124211Sdes buffer_put_int(&m, packets); 58898675Sdes 58998675Sdes debug3("%s: New keys have been sent", __func__); 59098675Sdes skip: 59198675Sdes /* More key context */ 59298675Sdes plen = packet_get_keycontext(MODE_OUT, NULL); 59398675Sdes p = xmalloc(plen+1); 59498675Sdes packet_get_keycontext(MODE_OUT, p); 59598675Sdes buffer_put_string(&m, p, plen); 59698675Sdes xfree(p); 59798675Sdes 59898675Sdes plen = packet_get_keycontext(MODE_IN, NULL); 59998675Sdes p = xmalloc(plen+1); 60098675Sdes packet_get_keycontext(MODE_IN, p); 60198675Sdes buffer_put_string(&m, p, plen); 60298675Sdes xfree(p); 60398675Sdes 60498675Sdes /* Compression state */ 60598675Sdes debug3("%s: Sending compression state", __func__); 60698675Sdes buffer_put_string(&m, &outgoing_stream, sizeof(outgoing_stream)); 60798675Sdes buffer_put_string(&m, &incoming_stream, sizeof(incoming_stream)); 60898675Sdes 60998675Sdes /* Network I/O buffers */ 61098675Sdes buffer_put_string(&m, buffer_ptr(&input), buffer_len(&input)); 61198675Sdes buffer_put_string(&m, buffer_ptr(&output), buffer_len(&output)); 61298675Sdes 61398675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYEXPORT, &m); 61498675Sdes debug3("%s: Finished sending state", __func__); 61598675Sdes 61698675Sdes buffer_free(&m); 61798675Sdes} 61898675Sdes 61998675Sdesint 62098675Sdesmm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen) 62198675Sdes{ 62298675Sdes Buffer m; 623106130Sdes char *p; 62498675Sdes int success = 0; 62598675Sdes 62698675Sdes buffer_init(&m); 62798675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTY, &m); 62898675Sdes 62998675Sdes debug3("%s: waiting for MONITOR_ANS_PTY", __func__); 63098675Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PTY, &m); 63198675Sdes 63298675Sdes success = buffer_get_int(&m); 63398675Sdes if (success == 0) { 63498675Sdes debug3("%s: pty alloc failed", __func__); 63598675Sdes buffer_free(&m); 63698675Sdes return (0); 63798675Sdes } 63898675Sdes p = buffer_get_string(&m, NULL); 63998675Sdes buffer_free(&m); 64098675Sdes 64198675Sdes strlcpy(namebuf, p, namebuflen); /* Possible truncation */ 64298675Sdes xfree(p); 64398675Sdes 64498675Sdes *ptyfd = mm_receive_fd(pmonitor->m_recvfd); 64598675Sdes *ttyfd = mm_receive_fd(pmonitor->m_recvfd); 64698675Sdes 64798675Sdes /* Success */ 64898675Sdes return (1); 64998675Sdes} 65098675Sdes 65198675Sdesvoid 65298675Sdesmm_session_pty_cleanup2(void *session) 65398675Sdes{ 65498675Sdes Session *s = session; 65598675Sdes Buffer m; 65698675Sdes 65798675Sdes if (s->ttyfd == -1) 65898675Sdes return; 65998675Sdes buffer_init(&m); 66098675Sdes buffer_put_cstring(&m, s->tty); 66198675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTYCLEANUP, &m); 66298675Sdes buffer_free(&m); 66398675Sdes 66498675Sdes /* closed dup'ed master */ 66598675Sdes if (close(s->ptymaster) < 0) 66698675Sdes error("close(s->ptymaster): %s", strerror(errno)); 66798675Sdes 66898675Sdes /* unlink pty from session */ 66998675Sdes s->ttyfd = -1; 67098675Sdes} 67198675Sdes 67298937Sdes#ifdef USE_PAM 67398937Sdesvoid 67498937Sdesmm_start_pam(char *user) 67598937Sdes{ 67698937Sdes Buffer m; 67798937Sdes 67898937Sdes debug3("%s entering", __func__); 679124211Sdes if (!options.use_pam) 680124211Sdes fatal("UsePAM=no, but ended up in %s anyway", __func__); 68198937Sdes 68298937Sdes buffer_init(&m); 68398937Sdes buffer_put_cstring(&m, user); 68498937Sdes 68598937Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_START, &m); 68698937Sdes 68798937Sdes buffer_free(&m); 68898937Sdes} 68999052Sdes 690124211Sdesu_int 691124211Sdesmm_do_pam_account(void) 692124211Sdes{ 693124211Sdes Buffer m; 694124211Sdes u_int ret; 695124211Sdes 696124211Sdes debug3("%s entering", __func__); 697124211Sdes if (!options.use_pam) 698124211Sdes fatal("UsePAM=no, but ended up in %s anyway", __func__); 699124211Sdes 700124211Sdes buffer_init(&m); 701124211Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_ACCOUNT, &m); 702124211Sdes 703124211Sdes mm_request_receive_expect(pmonitor->m_recvfd, 704124211Sdes MONITOR_ANS_PAM_ACCOUNT, &m); 705124211Sdes ret = buffer_get_int(&m); 706124211Sdes 707124211Sdes buffer_free(&m); 708124211Sdes 709124211Sdes debug3("%s returning %d", __func__, ret); 710124211Sdes 711124211Sdes return (ret); 712124211Sdes} 713124211Sdes 71499052Sdesvoid * 715124211Sdesmm_sshpam_init_ctx(Authctxt *authctxt) 71699052Sdes{ 71799052Sdes Buffer m; 71899052Sdes int success; 71999052Sdes 72099052Sdes debug3("%s", __func__); 72199052Sdes buffer_init(&m); 72299052Sdes buffer_put_cstring(&m, authctxt->user); 72399052Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_INIT_CTX, &m); 72499052Sdes debug3("%s: waiting for MONITOR_ANS_PAM_INIT_CTX", __func__); 72599052Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_INIT_CTX, &m); 72699052Sdes success = buffer_get_int(&m); 72799052Sdes if (success == 0) { 72899052Sdes debug3("%s: pam_init_ctx failed", __func__); 72999052Sdes buffer_free(&m); 73099052Sdes return (NULL); 73199052Sdes } 73299052Sdes buffer_free(&m); 73399052Sdes return (authctxt); 73499052Sdes} 73599052Sdes 73699052Sdesint 737124211Sdesmm_sshpam_query(void *ctx, char **name, char **info, 73899052Sdes u_int *num, char ***prompts, u_int **echo_on) 73999052Sdes{ 74099052Sdes Buffer m; 74199052Sdes int i, ret; 74299052Sdes 74399052Sdes debug3("%s", __func__); 74499052Sdes buffer_init(&m); 74599052Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_QUERY, &m); 74699052Sdes debug3("%s: waiting for MONITOR_ANS_PAM_QUERY", __func__); 74799052Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_QUERY, &m); 74899052Sdes ret = buffer_get_int(&m); 74999052Sdes debug3("%s: pam_query returned %d", __func__, ret); 75099052Sdes *name = buffer_get_string(&m, NULL); 75199052Sdes *info = buffer_get_string(&m, NULL); 75299052Sdes *num = buffer_get_int(&m); 75399052Sdes *prompts = xmalloc((*num + 1) * sizeof(char *)); 75499052Sdes *echo_on = xmalloc((*num + 1) * sizeof(u_int)); 75599052Sdes for (i = 0; i < *num; ++i) { 75699052Sdes (*prompts)[i] = buffer_get_string(&m, NULL); 75799052Sdes (*echo_on)[i] = buffer_get_int(&m); 75899052Sdes } 75999052Sdes buffer_free(&m); 76099052Sdes return (ret); 76199052Sdes} 76299052Sdes 76399052Sdesint 764124211Sdesmm_sshpam_respond(void *ctx, u_int num, char **resp) 76599052Sdes{ 76699052Sdes Buffer m; 76799052Sdes int i, ret; 76899052Sdes 76999052Sdes debug3("%s", __func__); 77099052Sdes buffer_init(&m); 77199052Sdes buffer_put_int(&m, num); 77299052Sdes for (i = 0; i < num; ++i) 77399052Sdes buffer_put_cstring(&m, resp[i]); 77499052Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_RESPOND, &m); 77599052Sdes debug3("%s: waiting for MONITOR_ANS_PAM_RESPOND", __func__); 77699052Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_RESPOND, &m); 77799052Sdes ret = buffer_get_int(&m); 77899052Sdes debug3("%s: pam_respond returned %d", __func__, ret); 77999052Sdes buffer_free(&m); 78099052Sdes return (ret); 78199052Sdes} 78299052Sdes 78399052Sdesvoid 784124211Sdesmm_sshpam_free_ctx(void *ctxtp) 78599052Sdes{ 78699052Sdes Buffer m; 78799052Sdes 78899052Sdes debug3("%s", __func__); 78999052Sdes buffer_init(&m); 79099052Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_FREE_CTX, &m); 79199052Sdes debug3("%s: waiting for MONITOR_ANS_PAM_FREE_CTX", __func__); 79299052Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_FREE_CTX, &m); 79399052Sdes buffer_free(&m); 79499052Sdes} 79598937Sdes#endif /* USE_PAM */ 79698937Sdes 79798675Sdes/* Request process termination */ 79898675Sdes 79998675Sdesvoid 80098675Sdesmm_terminate(void) 80198675Sdes{ 80298675Sdes Buffer m; 80398675Sdes 80498675Sdes buffer_init(&m); 80598675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_TERM, &m); 80698675Sdes buffer_free(&m); 80798675Sdes} 80898675Sdes 80998675Sdesint 81098675Sdesmm_ssh1_session_key(BIGNUM *num) 81198675Sdes{ 81298675Sdes int rsafail; 81398675Sdes Buffer m; 81498675Sdes 81598675Sdes buffer_init(&m); 81698675Sdes buffer_put_bignum2(&m, num); 81798675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SESSKEY, &m); 81898675Sdes 81998675Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SESSKEY, &m); 82098675Sdes 82198675Sdes rsafail = buffer_get_int(&m); 82298675Sdes buffer_get_bignum2(&m, num); 82398675Sdes 82498675Sdes buffer_free(&m); 82598675Sdes 82698675Sdes return (rsafail); 82798675Sdes} 82898675Sdes 82998675Sdesstatic void 83098675Sdesmm_chall_setup(char **name, char **infotxt, u_int *numprompts, 83198675Sdes char ***prompts, u_int **echo_on) 83298675Sdes{ 83398675Sdes *name = xstrdup(""); 83498675Sdes *infotxt = xstrdup(""); 83598675Sdes *numprompts = 1; 836106130Sdes *prompts = xmalloc(*numprompts * sizeof(char *)); 83798675Sdes *echo_on = xmalloc(*numprompts * sizeof(u_int)); 83898675Sdes (*echo_on)[0] = 0; 83998675Sdes} 84098675Sdes 84198675Sdesint 84298675Sdesmm_bsdauth_query(void *ctx, char **name, char **infotxt, 84398675Sdes u_int *numprompts, char ***prompts, u_int **echo_on) 84498675Sdes{ 84598675Sdes Buffer m; 846113911Sdes u_int success; 84798675Sdes char *challenge; 84898675Sdes 84998675Sdes debug3("%s: entering", __func__); 85098675Sdes 85198675Sdes buffer_init(&m); 85298675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHQUERY, &m); 85398675Sdes 85498675Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_BSDAUTHQUERY, 85598675Sdes &m); 856113911Sdes success = buffer_get_int(&m); 857113911Sdes if (success == 0) { 85898675Sdes debug3("%s: no challenge", __func__); 85998675Sdes buffer_free(&m); 86098675Sdes return (-1); 86198675Sdes } 86298675Sdes 86398675Sdes /* Get the challenge, and format the response */ 86498675Sdes challenge = buffer_get_string(&m, NULL); 86598675Sdes buffer_free(&m); 86698675Sdes 86798675Sdes mm_chall_setup(name, infotxt, numprompts, prompts, echo_on); 86898675Sdes (*prompts)[0] = challenge; 86998675Sdes 87098675Sdes debug3("%s: received challenge: %s", __func__, challenge); 87198675Sdes 87298675Sdes return (0); 87398675Sdes} 87498675Sdes 87598675Sdesint 87698675Sdesmm_bsdauth_respond(void *ctx, u_int numresponses, char **responses) 87798675Sdes{ 87898675Sdes Buffer m; 87998675Sdes int authok; 88098675Sdes 88198675Sdes debug3("%s: entering", __func__); 88298675Sdes if (numresponses != 1) 88398675Sdes return (-1); 88498675Sdes 88598675Sdes buffer_init(&m); 88698675Sdes buffer_put_cstring(&m, responses[0]); 88798675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHRESPOND, &m); 88898675Sdes 88998675Sdes mm_request_receive_expect(pmonitor->m_recvfd, 89098675Sdes MONITOR_ANS_BSDAUTHRESPOND, &m); 89198675Sdes 89298675Sdes authok = buffer_get_int(&m); 89398675Sdes buffer_free(&m); 89498675Sdes 89598675Sdes return ((authok == 0) ? -1 : 0); 89698675Sdes} 89798675Sdes 89899046Sdes#ifdef SKEY 89998675Sdesint 90098675Sdesmm_skey_query(void *ctx, char **name, char **infotxt, 90198675Sdes u_int *numprompts, char ***prompts, u_int **echo_on) 90298675Sdes{ 90398675Sdes Buffer m; 904113911Sdes int len; 905113911Sdes u_int success; 90698675Sdes char *p, *challenge; 90798675Sdes 90898675Sdes debug3("%s: entering", __func__); 90998675Sdes 91098675Sdes buffer_init(&m); 91198675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SKEYQUERY, &m); 91298675Sdes 91398675Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SKEYQUERY, 91498675Sdes &m); 915113911Sdes success = buffer_get_int(&m); 916113911Sdes if (success == 0) { 91798675Sdes debug3("%s: no challenge", __func__); 91898675Sdes buffer_free(&m); 91998675Sdes return (-1); 92098675Sdes } 92198675Sdes 92298675Sdes /* Get the challenge, and format the response */ 92398675Sdes challenge = buffer_get_string(&m, NULL); 92498675Sdes buffer_free(&m); 92598675Sdes 92698675Sdes debug3("%s: received challenge: %s", __func__, challenge); 92798675Sdes 92898675Sdes mm_chall_setup(name, infotxt, numprompts, prompts, echo_on); 92998675Sdes 93098675Sdes len = strlen(challenge) + strlen(SKEY_PROMPT) + 1; 93198675Sdes p = xmalloc(len); 93298675Sdes strlcpy(p, challenge, len); 93398675Sdes strlcat(p, SKEY_PROMPT, len); 93498675Sdes (*prompts)[0] = p; 93598675Sdes xfree(challenge); 93698675Sdes 93798675Sdes return (0); 93898675Sdes} 93998675Sdes 94098675Sdesint 94198675Sdesmm_skey_respond(void *ctx, u_int numresponses, char **responses) 94298675Sdes{ 94398675Sdes Buffer m; 94498675Sdes int authok; 94598675Sdes 94698675Sdes debug3("%s: entering", __func__); 94798675Sdes if (numresponses != 1) 94898675Sdes return (-1); 94998675Sdes 95098675Sdes buffer_init(&m); 95198675Sdes buffer_put_cstring(&m, responses[0]); 95298675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SKEYRESPOND, &m); 95398675Sdes 95498675Sdes mm_request_receive_expect(pmonitor->m_recvfd, 95598675Sdes MONITOR_ANS_SKEYRESPOND, &m); 95698675Sdes 95798675Sdes authok = buffer_get_int(&m); 95898675Sdes buffer_free(&m); 95998675Sdes 96098675Sdes return ((authok == 0) ? -1 : 0); 96198675Sdes} 96299046Sdes#endif 96398675Sdes 96498675Sdesvoid 96598675Sdesmm_ssh1_session_id(u_char session_id[16]) 96698675Sdes{ 96798675Sdes Buffer m; 96898675Sdes int i; 96998675Sdes 97098675Sdes debug3("%s entering", __func__); 97198675Sdes 97298675Sdes buffer_init(&m); 97398675Sdes for (i = 0; i < 16; i++) 97498675Sdes buffer_put_char(&m, session_id[i]); 97598675Sdes 97698675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SESSID, &m); 97798675Sdes buffer_free(&m); 97898675Sdes} 97998675Sdes 98098675Sdesint 98198675Sdesmm_auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey) 98298675Sdes{ 98398675Sdes Buffer m; 98498675Sdes Key *key; 98598675Sdes u_char *blob; 98698675Sdes u_int blen; 987113911Sdes int allowed = 0, have_forced = 0; 98898675Sdes 98998675Sdes debug3("%s entering", __func__); 99098675Sdes 99198675Sdes buffer_init(&m); 99298675Sdes buffer_put_bignum2(&m, client_n); 99398675Sdes 99498675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSAKEYALLOWED, &m); 99598675Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSAKEYALLOWED, &m); 99698675Sdes 99798675Sdes allowed = buffer_get_int(&m); 99898675Sdes 999113911Sdes /* fake forced command */ 1000113911Sdes auth_clear_options(); 1001113911Sdes have_forced = buffer_get_int(&m); 1002113911Sdes forced_command = have_forced ? xstrdup("true") : NULL; 1003113911Sdes 100498675Sdes if (allowed && rkey != NULL) { 100598675Sdes blob = buffer_get_string(&m, &blen); 100698675Sdes if ((key = key_from_blob(blob, blen)) == NULL) 100798675Sdes fatal("%s: key_from_blob failed", __func__); 100898675Sdes *rkey = key; 100998675Sdes xfree(blob); 101098675Sdes } 101198675Sdes mm_send_debug(&m); 101298675Sdes buffer_free(&m); 101398675Sdes 101498675Sdes return (allowed); 101598675Sdes} 101698675Sdes 101798675SdesBIGNUM * 101898675Sdesmm_auth_rsa_generate_challenge(Key *key) 101998675Sdes{ 102098675Sdes Buffer m; 102198675Sdes BIGNUM *challenge; 102298675Sdes u_char *blob; 102398675Sdes u_int blen; 102498675Sdes 102598675Sdes debug3("%s entering", __func__); 102698675Sdes 102798675Sdes if ((challenge = BN_new()) == NULL) 102898675Sdes fatal("%s: BN_new failed", __func__); 102998675Sdes 103098675Sdes key->type = KEY_RSA; /* XXX cheat for key_to_blob */ 103198675Sdes if (key_to_blob(key, &blob, &blen) == 0) 103298675Sdes fatal("%s: key_to_blob failed", __func__); 103398675Sdes key->type = KEY_RSA1; 103498675Sdes 103598675Sdes buffer_init(&m); 103698675Sdes buffer_put_string(&m, blob, blen); 103798675Sdes xfree(blob); 103898675Sdes 103998675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSACHALLENGE, &m); 104098675Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSACHALLENGE, &m); 104198675Sdes 104298675Sdes buffer_get_bignum2(&m, challenge); 104398675Sdes buffer_free(&m); 104498675Sdes 104598675Sdes return (challenge); 104698675Sdes} 104798675Sdes 104898675Sdesint 104998675Sdesmm_auth_rsa_verify_response(Key *key, BIGNUM *p, u_char response[16]) 105098675Sdes{ 105198675Sdes Buffer m; 105298675Sdes u_char *blob; 105398675Sdes u_int blen; 105498675Sdes int success = 0; 105598675Sdes 105698675Sdes debug3("%s entering", __func__); 105798675Sdes 105898675Sdes key->type = KEY_RSA; /* XXX cheat for key_to_blob */ 105998675Sdes if (key_to_blob(key, &blob, &blen) == 0) 106098675Sdes fatal("%s: key_to_blob failed", __func__); 106198675Sdes key->type = KEY_RSA1; 106298675Sdes 106398675Sdes buffer_init(&m); 106498675Sdes buffer_put_string(&m, blob, blen); 106598675Sdes buffer_put_string(&m, response, 16); 106698675Sdes xfree(blob); 106798675Sdes 106898675Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSARESPONSE, &m); 106998675Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSARESPONSE, &m); 107098675Sdes 107198675Sdes success = buffer_get_int(&m); 107298675Sdes buffer_free(&m); 107398675Sdes 107498675Sdes return (success); 107598675Sdes} 1076106130Sdes 1077124211Sdes#ifdef GSSAPI 1078124211SdesOM_uint32 1079124211Sdesmm_ssh_gssapi_server_ctx(Gssctxt **ctx, gss_OID oid) 1080106130Sdes{ 1081124211Sdes Buffer m; 1082124211Sdes OM_uint32 major; 1083106130Sdes 1084124211Sdes /* Client doesn't get to see the context */ 1085124211Sdes *ctx = NULL; 1086106130Sdes 1087106130Sdes buffer_init(&m); 1088124211Sdes buffer_put_string(&m, oid->elements, oid->length); 1089106130Sdes 1090124211Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSETUP, &m); 1091124211Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSETUP, &m); 1092106130Sdes 1093124211Sdes major = buffer_get_int(&m); 1094124211Sdes 1095106130Sdes buffer_free(&m); 1096124211Sdes return (major); 1097106130Sdes} 1098106130Sdes 1099124211SdesOM_uint32 1100124211Sdesmm_ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *in, 1101124211Sdes gss_buffer_desc *out, OM_uint32 *flags) 1102124211Sdes{ 1103124211Sdes Buffer m; 1104124211Sdes OM_uint32 major; 1105124211Sdes u_int len; 1106124211Sdes 1107124211Sdes buffer_init(&m); 1108124211Sdes buffer_put_string(&m, in->value, in->length); 1109124211Sdes 1110124211Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSTEP, &m); 1111124211Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSTEP, &m); 1112124211Sdes 1113124211Sdes major = buffer_get_int(&m); 1114124211Sdes out->value = buffer_get_string(&m, &len); 1115124211Sdes out->length = len; 1116124211Sdes if (flags) 1117124211Sdes *flags = buffer_get_int(&m); 1118124211Sdes 1119124211Sdes buffer_free(&m); 1120124211Sdes 1121124211Sdes return (major); 1122124211Sdes} 1123124211Sdes 1124106130Sdesint 1125124211Sdesmm_ssh_gssapi_userok(char *user) 1126106130Sdes{ 1127106130Sdes Buffer m; 1128124211Sdes int authenticated = 0; 1129106130Sdes 1130106130Sdes buffer_init(&m); 1131106130Sdes 1132124211Sdes mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, &m); 1133124211Sdes mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUSEROK, 1134124211Sdes &m); 1135106130Sdes 1136124211Sdes authenticated = buffer_get_int(&m); 1137106130Sdes 1138106130Sdes buffer_free(&m); 1139124211Sdes debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not "); 1140124211Sdes return (authenticated); 1141106130Sdes} 1142124211Sdes#endif /* GSSAPI */ 1143