155682Smarkm/* 2233294Sstas * Copyright (c) 1997-2004 Kungliga Tekniska H��gskolan 3233294Sstas * (Royal Institute of Technology, Stockholm, Sweden). 4233294Sstas * All rights reserved. 555682Smarkm * 6233294Sstas * Redistribution and use in source and binary forms, with or without 7233294Sstas * modification, are permitted provided that the following conditions 8233294Sstas * are met: 955682Smarkm * 10233294Sstas * 1. Redistributions of source code must retain the above copyright 11233294Sstas * notice, this list of conditions and the following disclaimer. 1255682Smarkm * 13233294Sstas * 2. Redistributions in binary form must reproduce the above copyright 14233294Sstas * notice, this list of conditions and the following disclaimer in the 15233294Sstas * documentation and/or other materials provided with the distribution. 1655682Smarkm * 17233294Sstas * 3. Neither the name of the Institute nor the names of its contributors 18233294Sstas * may be used to endorse or promote products derived from this software 19233294Sstas * without specific prior written permission. 2055682Smarkm * 21233294Sstas * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22233294Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23233294Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24233294Sstas * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25233294Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26233294Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27233294Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28233294Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29233294Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30233294Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31233294Sstas * SUCH DAMAGE. 3255682Smarkm */ 3355682Smarkm 3455682Smarkm#include "rsh_locl.h" 35233294SstasRCSID("$Id$"); 3655682Smarkm 37233294Sstas#if defined(KRB5) 38102644Snectar 39103423Snectar#ifdef KRB5 40103423Snectarint key_usage = 1026; 41103423Snectar 42103423Snectarvoid *ivec_in[2]; 43103423Snectarvoid *ivec_out[2]; 44103423Snectar 45103423Snectarvoid 46178825Sdfrinit_ivecs(int client, int have_errsock) 47103423Snectar{ 48103423Snectar size_t blocksize; 49103423Snectar 50103423Snectar krb5_crypto_getblocksize(context, crypto, &blocksize); 51103423Snectar 52103423Snectar ivec_in[0] = malloc(blocksize); 53103423Snectar memset(ivec_in[0], client, blocksize); 54103423Snectar 55178825Sdfr if(have_errsock) { 56178825Sdfr ivec_in[1] = malloc(blocksize); 57178825Sdfr memset(ivec_in[1], 2 | client, blocksize); 58178825Sdfr } else 59178825Sdfr ivec_in[1] = ivec_in[0]; 60103423Snectar 61103423Snectar ivec_out[0] = malloc(blocksize); 62103423Snectar memset(ivec_out[0], !client, blocksize); 63103423Snectar 64178825Sdfr if(have_errsock) { 65178825Sdfr ivec_out[1] = malloc(blocksize); 66178825Sdfr memset(ivec_out[1], 2 | !client, blocksize); 67178825Sdfr } else 68178825Sdfr ivec_out[1] = ivec_out[0]; 69103423Snectar} 70103423Snectar#endif 71103423Snectar 72103423Snectar 7355682Smarkmssize_t 74103423Snectardo_read (int fd, void *buf, size_t sz, void *ivec) 7555682Smarkm{ 7655682Smarkm if (do_encrypt) { 77102644Snectar#ifdef KRB5 7855682Smarkm if(auth_method == AUTH_KRB5) { 79102644Snectar krb5_error_code ret; 80178825Sdfr uint32_t len, outer_len; 8155682Smarkm int status; 8255682Smarkm krb5_data data; 8355682Smarkm void *edata; 8455682Smarkm 8555682Smarkm ret = krb5_net_read (context, &fd, &len, 4); 8655682Smarkm if (ret <= 0) 8755682Smarkm return ret; 8855682Smarkm len = ntohl(len); 8955682Smarkm if (len > sz) 9055682Smarkm abort (); 91103423Snectar /* ivec will be non null for protocol version 2 */ 92103423Snectar if(ivec != NULL) 93103423Snectar outer_len = krb5_get_wrapped_length (context, crypto, len + 4); 94103423Snectar else 95103423Snectar outer_len = krb5_get_wrapped_length (context, crypto, len); 9655682Smarkm edata = malloc (outer_len); 9755682Smarkm if (edata == NULL) 9855682Smarkm errx (1, "malloc: cannot allocate %u bytes", outer_len); 9955682Smarkm ret = krb5_net_read (context, &fd, edata, outer_len); 100233294Sstas if (ret <= 0) { 101233294Sstas free(edata); 10255682Smarkm return ret; 103233294Sstas } 10455682Smarkm 105233294Sstas status = krb5_decrypt_ivec(context, crypto, key_usage, 106103423Snectar edata, outer_len, &data, ivec); 10755682Smarkm free (edata); 108233294Sstas 10955682Smarkm if (status) 110103423Snectar krb5_err (context, 1, status, "decrypting data"); 111103423Snectar if(ivec != NULL) { 112103423Snectar unsigned long l; 113103423Snectar if(data.length < len + 4) 114103423Snectar errx (1, "data received is too short"); 115103423Snectar _krb5_get_int(data.data, &l, 4); 116103423Snectar if(l != len) 117103423Snectar errx (1, "inconsistency in received data"); 118103423Snectar memcpy (buf, (unsigned char *)data.data+4, len); 119103423Snectar } else 120103423Snectar memcpy (buf, data.data, len); 12155682Smarkm krb5_data_free (&data); 12255682Smarkm return len; 123102644Snectar } else 124102644Snectar#endif /* KRB5 */ 12555682Smarkm abort (); 12655682Smarkm } else 12755682Smarkm return read (fd, buf, sz); 12855682Smarkm} 12955682Smarkm 13055682Smarkmssize_t 131103423Snectardo_write (int fd, void *buf, size_t sz, void *ivec) 13255682Smarkm{ 13355682Smarkm if (do_encrypt) { 134102644Snectar#ifdef KRB5 13555682Smarkm if(auth_method == AUTH_KRB5) { 13655682Smarkm krb5_error_code status; 13755682Smarkm krb5_data data; 138103423Snectar unsigned char len[4]; 13955682Smarkm int ret; 14055682Smarkm 141103423Snectar _krb5_put_int(len, sz, 4); 142103423Snectar if(ivec != NULL) { 143103423Snectar unsigned char *tmp = malloc(sz + 4); 144103423Snectar if(tmp == NULL) 145103423Snectar err(1, "malloc"); 146103423Snectar _krb5_put_int(tmp, sz, 4); 147103423Snectar memcpy(tmp + 4, buf, sz); 148103423Snectar status = krb5_encrypt_ivec(context, crypto, key_usage, 149103423Snectar tmp, sz + 4, &data, ivec); 150103423Snectar free(tmp); 151103423Snectar } else 152103423Snectar status = krb5_encrypt_ivec(context, crypto, key_usage, 153103423Snectar buf, sz, &data, ivec); 154103423Snectar 15555682Smarkm if (status) 156103423Snectar krb5_err(context, 1, status, "encrypting data"); 15755682Smarkm 158103423Snectar ret = krb5_net_write (context, &fd, len, 4); 15955682Smarkm if (ret != 4) 16055682Smarkm return ret; 16155682Smarkm ret = krb5_net_write (context, &fd, data.data, data.length); 16255682Smarkm if (ret != data.length) 16355682Smarkm return ret; 16455682Smarkm free (data.data); 16555682Smarkm return sz; 166102644Snectar } else 167102644Snectar#endif /* KRB5 */ 16855682Smarkm abort(); 16955682Smarkm } else 17055682Smarkm return write (fd, buf, sz); 17155682Smarkm} 172233294Sstas#endif /* KRB5 */ 173