common.c revision 178825
1193326Sed/* 2193326Sed * Copyright (c) 1997-2004 Kungliga Tekniska H�gskolan 3193326Sed * (Royal Institute of Technology, Stockholm, Sweden). 4193326Sed * All rights reserved. 5193326Sed * 6193326Sed * Redistribution and use in source and binary forms, with or without 7193326Sed * modification, are permitted provided that the following conditions 8193326Sed * are met: 9193326Sed * 10193326Sed * 1. Redistributions of source code must retain the above copyright 11193326Sed * notice, this list of conditions and the following disclaimer. 12193326Sed * 13193326Sed * 2. Redistributions in binary form must reproduce the above copyright 14193326Sed * notice, this list of conditions and the following disclaimer in the 15193326Sed * documentation and/or other materials provided with the distribution. 16193326Sed * 17193326Sed * 3. Neither the name of the Institute nor the names of its contributors 18193326Sed * may be used to endorse or promote products derived from this software 19193326Sed * without specific prior written permission. 20212904Sdim * 21193326Sed * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22193326Sed * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23212904Sdim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24212904Sdim * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25243830Sdim * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26212904Sdim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27218893Sdim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28218893Sdim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29212904Sdim * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30212904Sdim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31212904Sdim * SUCH DAMAGE. 32212904Sdim */ 33243830Sdim 34212904Sdim#include "rsh_locl.h" 35218893SdimRCSID("$Id: common.c 17450 2006-05-05 11:11:43Z lha $"); 36218893Sdim 37212904Sdim#if defined(KRB4) || defined(KRB5) 38212904Sdim 39208600Srdivacky#ifdef KRB5 40208600Srdivackyint key_usage = 1026; 41243830Sdim 42208600Srdivackyvoid *ivec_in[2]; 43218893Sdimvoid *ivec_out[2]; 44218893Sdim 45208600Srdivackyvoid 46208600Srdivackyinit_ivecs(int client, int have_errsock) 47193326Sed{ 48193326Sed size_t blocksize; 49243830Sdim 50198092Srdivacky krb5_crypto_getblocksize(context, crypto, &blocksize); 51218893Sdim 52218893Sdim ivec_in[0] = malloc(blocksize); 53193326Sed memset(ivec_in[0], client, blocksize); 54221345Sdim 55221345Sdim if(have_errsock) { 56221345Sdim ivec_in[1] = malloc(blocksize); 57243830Sdim memset(ivec_in[1], 2 | client, blocksize); 58221345Sdim } else 59221345Sdim ivec_in[1] = ivec_in[0]; 60221345Sdim 61221345Sdim ivec_out[0] = malloc(blocksize); 62198092Srdivacky memset(ivec_out[0], !client, blocksize); 63193326Sed 64193326Sed if(have_errsock) { 65243830Sdim ivec_out[1] = malloc(blocksize); 66193326Sed memset(ivec_out[1], 2 | !client, blocksize); 67218893Sdim } else 68218893Sdim ivec_out[1] = ivec_out[0]; 69198092Srdivacky} 70198092Srdivacky#endif 71193576Sed 72193576Sed 73243830Sdimssize_t 74198092Srdivackydo_read (int fd, void *buf, size_t sz, void *ivec) 75218893Sdim{ 76218893Sdim if (do_encrypt) { 77193576Sed#ifdef KRB4 78193576Sed if (auth_method == AUTH_KRB4) { 79234353Sdim return des_enc_read (fd, buf, sz, schedule, &iv); 80234353Sdim } else 81243830Sdim#endif /* KRB4 */ 82234353Sdim#ifdef KRB5 83234353Sdim if(auth_method == AUTH_KRB5) { 84234353Sdim krb5_error_code ret; 85234353Sdim uint32_t len, outer_len; 86234353Sdim int status; 87218893Sdim krb5_data data; 88218893Sdim void *edata; 89243830Sdim 90218893Sdim ret = krb5_net_read (context, &fd, &len, 4); 91218893Sdim if (ret <= 0) 92218893Sdim return ret; 93218893Sdim len = ntohl(len); 94218893Sdim if (len > sz) 95218893Sdim abort (); 96218893Sdim /* ivec will be non null for protocol version 2 */ 97243830Sdim if(ivec != NULL) 98218893Sdim outer_len = krb5_get_wrapped_length (context, crypto, len + 4); 99218893Sdim else 100218893Sdim outer_len = krb5_get_wrapped_length (context, crypto, len); 101218893Sdim edata = malloc (outer_len); 102249423Sdim if (edata == NULL) 103249423Sdim errx (1, "malloc: cannot allocate %u bytes", outer_len); 104249423Sdim ret = krb5_net_read (context, &fd, edata, outer_len); 105249423Sdim if (ret <= 0) 106249423Sdim return ret; 107249423Sdim 108249423Sdim status = krb5_decrypt_ivec(context, crypto, key_usage, 109249423Sdim edata, outer_len, &data, ivec); 110249423Sdim free (edata); 111249423Sdim 112249423Sdim if (status) 113249423Sdim krb5_err (context, 1, status, "decrypting data"); 114249423Sdim if(ivec != NULL) { 115249423Sdim unsigned long l; 116251662Sdim if(data.length < len + 4) 117251662Sdim errx (1, "data received is too short"); 118251662Sdim _krb5_get_int(data.data, &l, 4); 119263508Sdim if(l != len) 120263508Sdim errx (1, "inconsistency in received data"); 121251662Sdim memcpy (buf, (unsigned char *)data.data+4, len); 122251662Sdim } else 123263508Sdim memcpy (buf, data.data, len); 124263508Sdim krb5_data_free (&data); 125251662Sdim return len; 126251662Sdim } else 127263508Sdim#endif /* KRB5 */ 128263508Sdim abort (); 129263508Sdim } else 130263508Sdim return read (fd, buf, sz); 131263508Sdim} 132263508Sdim 133263508Sdimssize_t 134263508Sdimdo_write (int fd, void *buf, size_t sz, void *ivec) 135263508Sdim{ 136263508Sdim if (do_encrypt) { 137193326Sed#ifdef KRB4 138193326Sed if(auth_method == AUTH_KRB4) { 139193326Sed return des_enc_write (fd, buf, sz, schedule, &iv); 140 } else 141#endif /* KRB4 */ 142#ifdef KRB5 143 if(auth_method == AUTH_KRB5) { 144 krb5_error_code status; 145 krb5_data data; 146 unsigned char len[4]; 147 int ret; 148 149 _krb5_put_int(len, sz, 4); 150 if(ivec != NULL) { 151 unsigned char *tmp = malloc(sz + 4); 152 if(tmp == NULL) 153 err(1, "malloc"); 154 _krb5_put_int(tmp, sz, 4); 155 memcpy(tmp + 4, buf, sz); 156 status = krb5_encrypt_ivec(context, crypto, key_usage, 157 tmp, sz + 4, &data, ivec); 158 free(tmp); 159 } else 160 status = krb5_encrypt_ivec(context, crypto, key_usage, 161 buf, sz, &data, ivec); 162 163 if (status) 164 krb5_err(context, 1, status, "encrypting data"); 165 166 ret = krb5_net_write (context, &fd, len, 4); 167 if (ret != 4) 168 return ret; 169 ret = krb5_net_write (context, &fd, data.data, data.length); 170 if (ret != data.length) 171 return ret; 172 free (data.data); 173 return sz; 174 } else 175#endif /* KRB5 */ 176 abort(); 177 } else 178 return write (fd, buf, sz); 179} 180#endif /* KRB4 || KRB5 */ 181