Permalink
Browse files

Cygnus's libkstream, from cryptosrc-us.

  • Loading branch information...
1 parent b25df74 commit 0d448ea16c26b6eec6520b1e8abd01d124ae0901 thorpej committed Jun 17, 2000
Showing with 828 additions and 0 deletions.
  1. +12 −0 lib/libkstream/Makefile
  2. +339 −0 lib/libkstream/kstream-des.c
  3. +377 −0 lib/libkstream/kstream.c
  4. +100 −0 lib/libkstream/kstream.h
View
12 lib/libkstream/Makefile
@@ -0,0 +1,12 @@
+# $NetBSD: Makefile,v 1.1.1.1 2000/06/17 06:24:28 thorpej Exp $
+
+LIB= kstream
+
+SRCS= kstream.c kstream-des.c
+
+COPTS+= -g
+
+SHLIB_MAJOR?= 1
+SHLIB_MINOR?= 0
+
+.include <bsd.lib.mk>
View
339 lib/libkstream/kstream-des.c
@@ -0,0 +1,339 @@
+/* $NetBSD: kstream-des.c,v 1.1.1.1 2000/06/17 06:24:28 thorpej Exp $ */
+
+/* DES-encrypted-stream implementation for MIT Kerberos.
+ Written by Ken Raeburn (Raeburn@Cygnus.COM), based on algorithms
+ in the original MIT Kerberos code.
+ Copyright (C) 1991, 1992 by Cygnus Support.
+
+ This file is distributed under the same terms as Kerberos.
+ For copying and distribution information, please see the file
+ <kerberosIV/mit-copyright.h>.
+
+ from: kstream-des.c,v 1.9 1996/06/02 07:37:27 ghudson Exp $
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <des.h>
+#include <kerberosIV/kstream.h>
+
+typedef struct {
+ union {
+ long align_me;
+ double align_me_harder;
+ Key_schedule sched;
+ } u;
+ des_cblock ivec;
+} kstream_des_init_block;
+
+typedef struct {
+ kstream_des_init_block x;
+ int no_right_justify;
+ int protect_rlogin_oob;
+ char *buf1, *buf2;
+ size_t len1, len2;
+} priv;
+
+typedef struct kstream_data_block ksdb;
+
+/* The data stream consists of four bytes representing a net-order
+ integer, followed by enough data to produce that many
+ cleartext bytes. This means the size of that data must be rounded
+ up to a multiple of 8, even though the cleartext may only be one
+ byte. For blocks of less than eight bytes, most software (well,
+ exactly half of the two already-existing programs, and all of the
+ ones we write using this library :-) pads on the *left* with
+ random values.
+
+ Some existing software that we have to be compatible with may send
+ blocks of data that decrypt to more than 8 bytes, but not an exact
+ multiple. In that case, the padding is on the right, as would be
+ considered "normal". This software currently will not generate such
+ a sequence, but a future version could. Don't break compatibility
+ with that mode. */
+
+#ifdef sun
+static kstream_ptr losing_realloc (old_ptr, new_size)
+ kstream_ptr old_ptr;
+ size_t new_size;
+{
+ return old_ptr ? realloc (old_ptr, new_size) : malloc (new_size);
+}
+#define realloc losing_realloc
+#endif
+
+/* Do the actual encryption work. This routine will handle chunks of
+ any size up to 16 bytes, or any multiple of 8 over that. It makes
+ the padding a little easier to write it this way. Handling sizes
+ between 8 and 16 is an annoyance, but rlogin actually relies on being
+ able to send 12 bytes in one chunk. Bleah! */
+static void
+do_encrypt (out, inp, p)
+ ksdb *out;
+ ksdb *inp;
+ priv *p;
+{
+ union {
+ char buf[16];
+ int junk[16 / sizeof (int)];
+ } u;
+ ksdb in;
+ char *ptr;
+ static int seeded;
+
+ if (!seeded) {
+ srandom ((int) time ((time_t *) 0));
+ seeded = 1;
+ }
+
+ in = *inp;
+ if (in.length < 8)
+ {
+ if (! p->no_right_justify)
+ {
+ u.junk[0] = random ();
+ memcpy (u.buf + 8 - in.length, in.ptr, in.length);
+ }
+ else
+ {
+ u.junk[(sizeof (u.junk[0]) + 7) / sizeof (u.junk[0]) - 1] = random ();
+ memcpy (u.buf, in.ptr, in.length);
+ }
+ in.ptr = u.buf;
+ in.length = 8;
+ }
+ else if (in.length == 8)
+ {
+ memcpy (u.buf, in.ptr, 8);
+ in.ptr = u.buf;
+ }
+ else if (in.length < sizeof (u.buf))
+ {
+ if (in.length % 8 == 0)
+ abort ();
+ u.junk[(sizeof (u.junk) / sizeof (u.junk[0])) - 1] = random ();
+ memcpy (u.buf, in.ptr, in.length);
+ in.ptr = u.buf;
+ }
+ else if (in.length % 8 != 0)
+ abort ();
+ {
+ unsigned long x;
+ x = inp->length; /* not in.length! */
+ ptr = (char *) out->ptr;
+ ptr[3] = x & 0xff; x >>= 8;
+ ptr[2] = x & 0xff; x >>= 8;
+ ptr[1] = x & 0xff; x >>= 8;
+ ptr[0] = x & 0xff; x >>= 8;
+ ptr += 4;
+ if (x)
+ abort ();
+ }
+ des_pcbc_encrypt ((des_cblock *)in.ptr, (des_cblock *)ptr, in.length,
+ p->x.u.sched, (des_cblock *)p->x.ivec, ENCRYPT);
+ out->ptr = ptr + ((in.length + 7) & ~7);
+}
+
+static int
+encrypt (outp, inp, k)
+ ksdb *outp;
+ ksdb *inp;
+ kstream k;
+{
+ const int small_block_size = 16;
+ priv *p = (priv *) k->data;
+
+ if (inp->length > small_block_size && inp->length % 8 != 0)
+ {
+ /* do two */
+ ksdb in, out;
+ size_t sz;
+
+ in.ptr = inp->ptr;
+ in.length = inp->length & ~7;
+ sz = in.length + 4; /* first block */
+ sz += 8 + 4; /* second block */
+ outp->length = sz;
+ out.ptr = outp->ptr = p->buf1 = realloc (p->buf1, sz);
+ out.length = sz;
+ assert (out.ptr != 0 || out.length == 0);
+ do_encrypt (&out, &in, p);
+ in.ptr = (char *) in.ptr + in.length;
+ in.length = inp->length - in.length;
+ do_encrypt (&out, &in, p);
+ return inp->length;
+ }
+ else
+ {
+ size_t sz = (inp->length + 7) & ~7;
+ sz += 4;
+ outp->length = sz;
+ outp->ptr = p->buf1 = realloc (p->buf1, sz);
+ assert (outp->ptr != 0 || outp->length == 0);
+ do_encrypt (outp, inp, p);
+ outp->ptr = p->buf1;
+ return inp->length;
+ }
+}
+
+int _kstream_des_debug_OOB = 0;
+
+static int
+decrypt (outp, inp, k)
+ ksdb *outp;
+ ksdb *inp;
+ kstream k;
+{
+ char *ptr = inp->ptr;
+ unsigned long x = 0;
+ int error_count = 0;
+ size_t sz;
+ priv *p = (priv *) k->data;
+
+ if(inp->length < 1) return -12; /* make sure we have at least one byte */
+ if (p->protect_rlogin_oob) {
+ /* here's where we handle an attack. The first byte ends up being the
+ highest. If it's not zero, skip it. If it is zero, we can't detect it,
+ and we still lose... */
+ x = *ptr & 0xff; /* get the first char */
+ while (x) {
+ if(_kstream_des_debug_OOB) fprintf(stderr,"BAD BYTE %02x\n\r", x);
+ error_count++; /* count the bad byte */
+ ptr++; /* and skip it */
+ if(inp->length == error_count) {
+ return -12; /* we've used up all of the input */
+ }
+ x = *ptr & 0xff; /* get the next potentially first char */
+ }
+ ptr++;
+ } else {
+ x <<= 8; x += *ptr++ & 0xff;
+ }
+
+
+ /* If we've got four bytes, we can at least determine the correct
+ amount that still needs to be read. If not, we can assume a
+ minimum of 12 good bytes (4-byte length plus one 8-byte block)
+ and we know how many of the ones we've got are bad. */
+ if (inp->length < 4 + error_count)
+ return inp->length - error_count - 12;
+
+/* x <<= 8; x += *ptr++ & 0xff; */ /* x already has first byte loaded */
+ x <<= 8; x += *ptr++ & 0xff;
+ x <<= 8; x += *ptr++ & 0xff;
+ x <<= 8; x += *ptr++ & 0xff;
+ sz = (x + 7) & ~7;
+ if (inp->length < sz + 4 + error_count)
+ return - (sz + 4 + error_count - inp->length);
+ assert (sz <= sizeof (k->in_crypt.data));
+
+ if (p->buf1)
+ p->buf1 = realloc (p->buf1, sz);
+ else
+ p->buf1 = malloc (sz);
+ assert (p->buf1 != 0 || sz == 0);
+ outp->ptr = p->buf1;
+ outp->length = x;
+ pcbc_encrypt ((des_cblock *)ptr, (des_cblock *)outp->ptr, sz, p->x.u.sched,
+ (des_cblock *)p->x.ivec, DECRYPT);
+ if (p->no_right_justify == 0
+ && x < 8)
+ outp->ptr = p->buf1 + 8 - x;
+ return sz + 4 + error_count;
+}
+
+static int
+init (k, data)
+ kstream k;
+ void *data;
+{
+ priv *p;
+
+ p = (priv *) malloc (sizeof (priv));
+ k->data = (kstream_ptr) p;
+ if (!p)
+ return errno;
+ p->buf1 = p->buf2 = 0;
+ p->len1 = p->len2 = 0;
+ p->no_right_justify = 0;
+ p->protect_rlogin_oob = 0;
+ p->x = * (kstream_des_init_block *) data;
+ return 0;
+}
+
+static int
+rcp_init (k, data)
+ kstream k;
+ void *data;
+{
+ int x = init (k, data);
+ ((priv *)(k->data))->no_right_justify = 1;
+ return x;
+}
+
+static int
+rlogin_init (k, data)
+ kstream k;
+ void *data;
+{
+ int x = init (k, data);
+ ((priv *)(k->data))->protect_rlogin_oob = 1;
+ return x;
+}
+
+static void
+destroy (k)
+ kstream k;
+{
+ priv *p = (priv *) k->data;
+ if (p->buf1)
+ free (p->buf1);
+ memset (p, '\\', sizeof (*p)); /* scribble to make sure it's gone */
+ free (p);
+ k->data = 0;
+}
+
+static const struct kstream_crypt_ctl_block kstream_des_ccb = {
+ encrypt, decrypt, rlogin_init, destroy
+};
+
+static const struct kstream_crypt_ctl_block kstream_des_rcp_ccb = {
+ encrypt, decrypt, rcp_init, destroy
+};
+
+kstream
+kstream_create_rlogin_from_fd (fd, P_sched, ivec)
+ int fd;
+ kstream_ptr P_sched;
+ des_cblock (*ivec);
+{
+ Key_schedule *sched = (Key_schedule *) P_sched;
+ kstream_des_init_block x;
+ kstream k;
+ memcpy (&x.u.sched, sched, sizeof (Key_schedule));
+ memcpy (&x.ivec, ivec, sizeof (des_cblock));
+ k = kstream_create_from_fd (fd, &kstream_des_ccb, &x);
+ memset (&x, '\\', sizeof (x));
+ return k;
+}
+
+kstream
+kstream_create_rcp_from_fd (fd, P_sched, ivec)
+ int fd;
+ kstream_ptr P_sched;
+ des_cblock (*ivec);
+{
+ Key_schedule *sched = (Key_schedule *) P_sched;
+ kstream_des_init_block x;
+ kstream k;
+ memcpy (&x.u.sched, sched, sizeof (Key_schedule));
+ memcpy (&x.ivec, ivec, sizeof (des_cblock));
+ k = kstream_create_from_fd (fd, &kstream_des_rcp_ccb, &x);
+ memset (&x, '\\', sizeof (x));
+ return k;
+}
View
377 lib/libkstream/kstream.c
@@ -0,0 +1,377 @@
+/* $NetBSD: kstream.c,v 1.1.1.1 2000/06/17 06:24:28 thorpej Exp $ */
+
+/* Encrypted-stream implementation for MIT Kerberos.
+ Written by Ken Raeburn (Raeburn@Cygnus.COM).
+ Copyright (C) 1991, 1992 by Cygnus Support.
+
+ This file is distributed under the same terms as Kerberos.
+ For copying and distribution information, please see the file
+ <kerberosIV/mit-copyright.h>.
+
+ from: kstream.c,v 1.7 1996/06/02 07:37:27 ghudson Exp $
+ */
+
+/* Current assumptions:
+ * the encryption/decryption routine may change the size of the data
+ significantly, in either direction, and need not be consistent
+ about it. (e.g., a pipe to "compress" could be used.)
+ * encryption/decryption may not consume all characters passed, but
+ will consume some, or will return a negative number indicating how
+ many more characters should be read before it will be able to do
+ anything with the data. (A return value of -1 is always safe; so
+ is calling the crypt routine again without enough data.)
+ * the file descriptor used is not set to non-blocking.
+ * no other routines will do i/o on that file descriptor while this
+ library is using it. (out-of-band messages are probably okay.)
+
+ Bugs:
+ * if the encryption package cannot handle arbitrarily small data,
+ flushing the outgoing stream may not work.
+
+ ToDo: Lots.
+ * completion of the code...
+ * begin testing
+ * buffering (efficiency)
+ * reduce data copying for large buffers that get sent immediately
+ * error handling
+ * consistency in error reporting conventions
+ */
+
+#include <assert.h>
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* Only use alloca if we've got gcc 2 or better */
+#ifdef __GNUC__
+#if __GNUC__ >= 2
+#define alloca __builtin_alloca
+#define HAS_ALLOCA
+#endif
+#endif
+
+#include <kerberosIV/kstream.h>
+#ifdef __STDC__
+int krb_net_write (int, char *, int);
+int krb_net_read (int, char *, int);
+#else
+int krb_net_write ();
+int krb_net_read ();
+void abort ();
+char *memmove ();
+void *memcpy ();
+char *malloc ();
+char *realloc ();
+void free ();
+#endif
+extern int errno;
+
+#ifdef sun
+#ifndef solaris20
+/* SunOS has no memmove, but bcopy overlaps correctly */
+#define memmove(dest,src,size) bcopy(src,dest,size)
+#endif
+#endif
+
+static void fifo__init (this)
+ fifo *this;
+{
+ this->next_write = this->next_read = 0;
+ memset (this->data, 0, sizeof (this->data));
+}
+static char *fifo__data_start (this)
+ fifo *this;
+{
+ return this->data + this->next_read;
+}
+static size_t fifo__bytes_available (this)
+ fifo *this;
+{
+ return this->next_write - this->next_read;
+}
+static size_t fifo__space_available (this)
+ fifo *this;
+{
+ return sizeof (this->data) - fifo__bytes_available (this);
+}
+static int fifo__append (this, ptr, len)
+ fifo *this;
+ const char *ptr;
+ size_t len;
+{
+ if (len > fifo__space_available (this))
+ len = fifo__space_available (this);
+ if (sizeof (this->data) - this->next_write < len)
+ {
+ memmove (this->data, this->data + this->next_read,
+ this->next_write - this->next_read);
+ this->next_write -= this->next_read;
+ this->next_read = 0;
+ }
+ memcpy (this->data + this->next_write, ptr, len);
+ this->next_write += len;
+ return len;
+}
+static int fifo__extract (this, ptr, len)
+ fifo *this;
+ char *ptr;
+ size_t len;
+{
+ size_t n = fifo__bytes_available (this);
+ if (len > n)
+ len = n;
+ if (ptr)
+ memcpy (ptr, this->data + this->next_read, len);
+ this->next_read += len;
+ if (this->next_read == this->next_write)
+ this->next_read = this->next_write = 0;
+ return len;
+}
+
+static void kstream_rec__init (this)
+ kstream_rec *this;
+{
+ fifo__init (&this->in_crypt);
+ fifo__init (&this->in_clear);
+ fifo__init (&this->out_clear);
+}
+
+kstream
+kstream_create_from_fd (fd, ctl, data)
+ int fd;
+ const struct kstream_crypt_ctl_block *ctl;
+ void *data;
+{
+ kstream k;
+ k = (kstream) malloc (sizeof (kstream_rec));
+ if (!k)
+ return 0;
+ kstream_rec__init (k);
+ k->ctl = ctl;
+ k->data = 0;
+ k->fd = fd;
+ k->buffering = 1; /* why not? */
+ if (ctl && ctl->init && (ctl->init) (k, data) != 0)
+ {
+ free (k);
+ return 0;
+ }
+ return k;
+}
+
+int
+kstream_destroy (k)
+ kstream k;
+{
+ int x = kstream_flush (k);
+ if (k->ctl && k->ctl->destroy)
+ (k->ctl->destroy) (k);
+ free (k);
+ return x;
+}
+
+void
+kstream_set_buffer_mode (k, mode)
+ kstream k;
+ int mode;
+{
+ k->buffering = mode;
+}
+
+int
+kstream_write (k, p_data, p_len)
+ kstream k;
+ kstream_ptr p_data;
+ size_t p_len;
+{
+ size_t len = p_len;
+ char *data = p_data;
+ int x = 0;
+ fifo *out = &k->out_clear;
+
+ assert (k != 0);
+
+ while (len)
+ {
+ x = fifo__append (out, data, len);
+ assert (x >= 0);
+ data += x;
+ len -= x;
+ if (len == 0 && k->buffering != 0)
+ return p_len;
+ x = kstream_flush (k);
+ if (x < 0)
+ return x;
+ }
+ return p_len;
+}
+
+int
+kstream_flush (k)
+ kstream k;
+{
+ int x, n;
+ fifo *out = &k->out_clear;
+ struct kstream_data_block kd_out, kd_in;
+
+ assert (k != 0);
+
+ if (k->ctl == 0)
+ {
+ int n = fifo__bytes_available (out);
+ x = krb_net_write (k->fd, fifo__data_start (out), n);
+ if (x < 0)
+ return x;
+ else if (x != n)
+ abort ();
+ fifo__extract (out, 0, n);
+ return 0;
+ }
+
+ n = fifo__bytes_available (out);
+ kd_in.length = n;
+ kd_in.ptr = fifo__data_start (out);
+ kd_out.ptr = 0;
+ kd_out.length = 0;
+ while (fifo__bytes_available (out))
+ {
+ x = (k->ctl->encrypt) (&kd_out, &kd_in, k);
+ if (x < 0)
+ return x;
+ else if (x == 0)
+ return -1;
+ /* x is number of input characters processed */
+ fifo__extract (out, 0, x);
+ x = krb_net_write (k->fd, kd_out.ptr, kd_out.length);
+ if (x < 0)
+ return x;
+ else if (x != kd_out.length)
+ abort ();
+ }
+ return 0;
+}
+
+int
+kstream_read (k, p_data, p_len)
+ kstream k;
+ kstream_ptr p_data;
+ size_t p_len;
+{
+ char *data = p_data;
+ size_t len = p_len;
+ int n;
+ fifo *in = &k->in_clear, *crypt;
+ struct kstream_data_block kd_out, kd_in;
+
+ assert (k != 0);
+
+ read_clear:
+ if (k->ctl == 0)
+ return read (k->fd, data, len);
+
+ if (fifo__bytes_available (in) > 0)
+ return fifo__extract (in, data, len);
+
+ crypt = &k->in_crypt;
+ try_2:
+ kd_out.ptr = 0;
+ kd_out.length = 0;
+ kd_in.length = fifo__bytes_available (crypt);
+ kd_in.ptr = fifo__data_start (crypt);
+ if (kd_in.length == 0)
+ {
+ n = -1;
+ goto read_source;
+ }
+ n = (k->ctl->decrypt) (&kd_out, &kd_in, k);
+ if (n > 0)
+ {
+ /* Succeeded in decrypting some data. */
+ fifo__extract (crypt, 0, n);
+ {
+ int n2;
+ n = kd_out.length;
+ n2 = fifo__append (in, kd_out.ptr, kd_out.length);
+ assert (n == n2);
+ }
+ goto read_clear;
+ }
+ else if (n == 0)
+ assert (n != 0); /* not handling errors yet */
+
+ read_source:
+ {
+ size_t sz;
+ static char *buf;
+ sz = -n;
+ if (sz > fifo__space_available (crypt))
+ {
+#ifdef DEBUG
+ fprintf (stderr, "insufficient space avail (%d, want %d)\n",
+ fifo__space_available (crypt), sz);
+#endif
+ errno = ENOMEM;
+ return -1;
+ }
+#ifdef HAS_ALLOCA
+ buf = alloca (sz);
+#else
+ if (buf)
+ buf = realloc (buf, sz);
+ else
+ buf = malloc (sz);
+ assert(buf);
+#endif
+ while (sz > 0)
+ {
+ int n2;
+ n2 = krb_net_read (k->fd, buf, sz);
+ if (n2 < 0)
+ {
+#ifdef DEBUG
+ perror ("kstream_read: krb_net_read");
+#endif
+ return n2;
+ }
+ else if (n2 == 0)
+ return 0;
+ fifo__append (crypt, buf, n2);
+ sz -= n2;
+ }
+ goto try_2;
+ }
+}
+
+#if 0
+extern "C" {
+
+/* simple rotate */
+
+typedef struct kstream_data_block DB;
+
+static int
+move (DB *out, DB *in, kstream k, int direction)
+{
+ int i, x;
+ static char *ptr;
+ char *inp = in->ptr;
+ if (in->length == 0) return -1;
+ /* Sun's realloc loses on null pointers. */
+ ptr = ptr ? realloc (ptr, in->length) : malloc (in->length);
+ out->ptr = ptr;
+ if (!ptr) return 0;
+ out->length = in->length;
+ x = direction ? +1 : -1;
+ for (i = in->length; i-- > 0; )
+ ptr[i] = inp[i] + x;
+ return in->length;
+}
+
+static int emove (DB *out, DB *in, kstream k) { return move (out, in, k, 0); }
+static int dmove (DB *out, DB *in, kstream k) { return move (out, in, k, 1); }
+extern const struct kstream_crypt_ctl_block rot1_ccb = {
+ emove, dmove, 0, 0
+};
+}
+#endif
View
100 lib/libkstream/kstream.h
@@ -0,0 +1,100 @@
+/* Header file for encrypted-stream library.
+ Written by Ken Raeburn (Raeburn@Cygnus.COM).
+ Copyright (C) 1991, 1992 by Cygnus Support.
+
+ This file is distributed under the same terms as Kerberos.
+ For copying and distribution information, please see the file
+ <mit-copyright.h>.
+
+ $NetBSD: kstream.h,v 1.1.1.1 2000/06/17 06:24:28 thorpej Exp $
+ */
+
+#include <sys/types.h> /* for size_t */
+
+/* Each stream is set up for two-way communication; if buffering is
+ requested, output will be flushed before input is read, or when
+ kstream_flush is called. */
+
+#if defined (__STDC__) || defined (__cplusplus)
+typedef void *kstream_ptr;
+#else
+typedef char *kstream_ptr;
+#endif
+typedef struct kstream_rec *kstream;
+struct kstream_data_block {
+ kstream_ptr ptr;
+ size_t length;
+};
+struct kstream_crypt_ctl_block {
+ /* Don't rely on anything in this structure.
+ It is almost guaranteed to change.
+ Right now, it's just a hack so we can bang out the interface
+ in some form that lets us run both rcp and rlogin. This is also
+ the only reason the contents of this structure are public. */
+#if defined (__STDC__) || defined (__cplusplus)
+ int (*encrypt) (struct kstream_data_block *, /* output -- written */
+ struct kstream_data_block*, /* input */
+ kstream str
+ ); /* ret val = # input bytes used */
+ int (*decrypt) (struct kstream_data_block *, /* output -- written */
+ struct kstream_data_block*, /* input */
+ kstream str
+ ); /* ret val = # input bytes used */
+ int (*init) (kstream str, kstream_ptr data);
+ void (*destroy) (kstream str);
+#else
+ int (*encrypt) (), (*decrypt) (), (*init) ();
+ void (*destroy) ();
+#endif
+};
+
+/* ctl==0 means no encryption. data is specific to crypt functions */
+#if defined (__STDC__) || defined (__cplusplus)
+kstream kstream_create_from_fd (int fd,
+ const struct kstream_crypt_ctl_block *ctl,
+ kstream_ptr data);
+/* There should be a "standard" DES mode used here somewhere.
+ These differ, and I haven't chosen one over the other (yet). */
+kstream kstream_create_rlogin_from_fd (int fd, void* sched,
+ unsigned char (*ivec)[8]);
+kstream kstream_create_rcp_from_fd (int fd, void* sched,
+ unsigned char (*ivec)[8]);
+int kstream_write (kstream, void*, size_t);
+int kstream_read (kstream, void*, size_t);
+int kstream_flush (kstream);
+int kstream_destroy (kstream);
+void kstream_set_buffer_mode (kstream, int);
+#else
+kstream kstream_create_from_fd (),
+ kstream_create_rlogin_from_fd (),
+ kstream_create_rcp_from_fd ();
+void kstream_set_buffer_mode ();
+#endif
+
+#if 0 /* Perhaps someday... */
+kstream kstream_create (principal, host, port, ...);
+#endif
+
+#if !defined (__STDC__) && !defined (__cplusplus) && !defined (const)
+#define const /* empty */
+#endif
+
+typedef struct fifo {
+ char data[10*1024];
+ size_t next_write, next_read;
+} fifo;
+
+typedef struct kstream_rec {
+ const struct kstream_crypt_ctl_block *ctl;
+ int fd;
+ int buffering : 2;
+ kstream_ptr data;
+ /* These should be made pointers as soon as code has been
+ written to reallocate them. Also, it would be more efficient
+ to use pointers into the buffers, rather than continually shifting
+ them down so unprocessed data starts at index 0. */
+ /* incoming */
+ fifo in_crypt, in_clear;
+ /* outgoing */
+ fifo out_clear;
+} kstream_rec;

0 comments on commit 0d448ea

Please sign in to comment.