Commit 33e3cd24 authored by Niels Möller's avatar Niels Möller

A framework for processing of the packets of the transport leayer.

Rev: src/debug.c:1.1
Rev: src/debug.h:1.1
Rev: src/encrypt.c:1.1
Rev: src/encrypt.h:1.1
Rev: src/pad.c:1.1
Rev: src/pad.h:1.1
Rev: src/transport.c:1.1
Rev: src/transport.h:1.1
Rev: src/zlib.c:1.1
Rev: src/zlib.h:1.1
parents
[attr]binary -text -crlf -diff -ident
* text ident
RCS
SCCS
CVS
CVS.adm
RCSLOG
cvslog.*
tags
TAGS
.make.state
.nse_depinfo
*~
#*
.#*
,*
_$*
*$
*.old
*.bak
*.BAK
*.orig
*.rej
.del-*
*.a
*.olb
*.o
*.obj
*.so
*.exe
*.Z
*.elc
*.ln
core
/* debug.c
*
*/
static int do_debug(struct debug_processor *closure,
struct simple_packet *packet)
{
UINT32 i;
fprintf(closure->output, "DEBUG: (packet size %d = 0x%x)\n",
packet->length);
for(i=0; i<packet->length; i++)
{
if (! i%16)
fprintf(closure->output, "\n%08x: ", i);
fprintf(closure->output, "%02x ", packet->data[i]);
}
fprintf(closure->output, "\n");
return apply_processor(closure->c->next, packet);
}
struct packet_processor *make_debug_processor(FILE *output,
packet_processor *continuation)
{
struct debug_processor *closure = xalloc(sizeof(struct debug_processor));
closure->c->p->f = (raw_processor_function) do_debug;
closure->c->next = continuation;
closure->output = output;
return (packet_processor) closure;
}
/* debug.h
*
* Packet processor dumping packets to a file.
*/
#ifndef LSH_DEBUG_H_INCLUDED
#define LSH_DEBUG_H_INCLUDED
#include <stdio.h>
struct debug_processor
{
struct chained_processor c;
FILE *output;
}
struct packet_processor *make_debug_processor(FILE *output,
packet_processor *continuation);
#endif */ LSH_DEBUG_H_INCLUDED */
/* encrypt.c
*
*/
#include "encrypt.h"
static int do_crypt(struct encrypt_processor *closure,
struct simple_packet *packet)
{
struct simple_packet *new
= simple_packet_alloc(packet->length + closure->mac_size);
closure->encrypt_function(closure->encrypt_state,
packet->data, new->data, packet->length);
closure->mac_function(closure->mac_state,
packet->data, new->data + packet->length);
simple_packet_free(packet);
return apply_processor(closure->c->next, new);
}
struct packet_processor *
make_encrypt_processor(struct packet_processor *containing,
unsigned mac_size,
transform_function mac_function,
void *mac_state,
transform_function encrypt_function,
void *encrypt_state)
{
struct pad_processor *closure = xalloc(sizeof(struct pad_processor));
closure->c->p->f = (raw_processor_function) do_pad;
closure->c->next = continuation;
closure->mac_size = mac_size;
closure->mac_function = mac_function;
closure->mac_state = mac_state;
closure->encrypt_function = encrypt_function;
closure->encrypt_state = encrypt_state;
return (packet_processor) closure;
}
/* encrypt.h
*
* Processor to pad, encrypt and authenticate
*/
#ifndef LSH_ENCRYPT_H_INCLUDED
#define LSH_ENCRYPT_H_INCLUDED
/* FIXME: Perhaps cryptographic algoritms should be encapsulated into
* objects, to avoid passing a lot of extra state parameters? */
typedef (*transform_function)(void *state,
UINT32 size, UINT8 *src, UINT8 *dst);
struct encrypt_processor
{
struct chained_processor c;
unsigned mac_size;
transform_function mac_function;
void *mac_state;
transform_function encrypt_function;
void *encrypt_state;
};
struct packet_processor *
make_encrypt_processor(struct packet_processor *containing,
unsigned mac_size,
transform_function mac_function,
void *mac_state,
transform_function encrypt_function,
void *encrypt_state);
#endif /* LSH_ENCRYPT_H_INCLUDED */
/* pad.c
*
*/
#include "pad.h"
static int do_pad(struct pad_processor *closure,
struct simple_packet *packet)
{
UINT32 new_size;
UINT8 padding;
struct simple_packet *new;
struct ssh_packet *ssh;
new_size = 1 + closure->block_size
* ( (8 + packet->length) / closure->block_size);
padding = new_size - packet->length - 5;
assert(ssh->padding_length >= 4);
new = simple_packet_alloc(new_size);
ssh = (struct ssh_packet *) new->data;
ssh->length = htonl(new_size);
ssh->padding_length = padding;
memcpy(ssh->data, packet->data, packet->length);
closure->random(closure->state, padding, ssh->data + packet->length);
simple_packet_free(packet);
return apply_processor(closure->c->next, new);
}
struct packet_processor *make_pad_processor(packet_processor *continuation,
unsigned block_size,
random_function random,
void *state)
{
struct pad_processor *closure = xalloc(sizeof(struct pad_processor));
closure->c->p->f = (raw_processor_function) do_pad;
closure->c->next = continuation;
closure->block_size = block_size;
closure->random = random;
closure->state = state;
return (packet_processor) closure;
}
/* pad.h
*
* Processor for padding and formatting ssh-packets
*/
#ifndef LSH_PAD_H_INCLUDED
#define LSH_PAD_H_INCLUDED
typedef (*random_function)(void *state, UINT32 length, UINT8 *dst);
/* Input to the processor is a packet with the payload. Output is a
* packet containing a formatted ssh packet (with correct byte order,
* etc). */
struct pad_processor
{
struct chained_processor c;
unsigned block_size; /* At least 8, even for stream ciphers */
random_function random;
void *state;
};
struct packet_processor *make_pad_processor(packet_processor *continuation,
unsigned block_size,
random_function random,
void *state);
#if 0
/* Input to the processor is a packet with the payload. Output is a
* packet containing a formatted ssh packet (with correct byte order,
* etc). No padding is done. */
struct format_processor
{
struct chained_processor c;
};
struct packet_processor *make_pad_processor(packet_processor *continuation);
#endif
#endif /* LSH_PAD_H_INCLUDED */
/* transport.c
*/
struct simple_packet *simple_packet_alloc(UINT32 length)
{
struct simple_packet *packet = xalloc(sizeof(struct simple_packet) - 1 + size);
packet->length = size;
return packet;
}
void simple_packet_free(struct simple_packet *packet);
{
free(packet);
}
void simple_buffer_init(struct simple_buffer *buffer,
UINT32 capacity, UINT8 *data)
{
buffer->capacity = capacity;
buffer->pos = 0;
buffer->data = data;
}
UINT32 simple_buffer_write(struct simple_buffer *buffer,
UINT32 length, UINT32 *data)
{
UINT32 left = buffer->capacity - buffer->pos;
UINT32 copy = MIN(left, length);
memcpy(buffer->data + buffer->pos, data, copy);
return copy;
}
UINT32 simple_buffer_avail(struct simple_buffer *buffer)
{
return buffer->capacity - buffer->pos;
}
int apply_processor(struct packet_processor *closure,
struct simple_packet *packet)
{
return closure->f(closure, packet);
}
/* transport.h
*
* ssh transport protocol, and supporting types
*/
#ifndef LSH_TRANSPORT_H_INCLUDED
#define LSH_TRANSPORT_H_INCLUDED
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
/* Generic packet */
struct simple_packet
{
UINT32 length;
UINT8 data[1];
}
struct ssh_packet
{
UINT32 packet_length; /* In network byteorder */
UINT8 padding_length;
UINT8 data[1]; /* Includes payload and padding */
};
/* Allocation */
/* The memory allocation model is as follows:
*
* Packets are allocated when the are needed. They may be passed
* through a chain of processing functions, until it is finally
* discarded or transmitted, at which time it is deallocated.
* Processing functions may deallocate their input packets and
* allocate fresh packets to pass on; therefore, any data from a
* packet that is needed later must be copied into some other storage.
*
* At any time, each packet is own by a a particular processing
* function. Pointers into a packet are valid only while you own it.
* */
/* Size is the maximum amount of payload + padding that will be stored
* in the packet. */
struct simple_packet *simple_packet_alloc(UINT32 size);
void simple_packet_free(struct simple_packet *packet);
/* Simple buffer */
struct simple_buffer
{
UNIT32 capacity;
UINT32 pos;
UINT8 *data;
};
void simple_buffer_init(struct simple_buffer *buffer,
UINT32 capacity, UINT8 *data);
/* Returns the number of octets that were actually written into the buffer */
UINT32 simple_buffer_write(struct simple_buffer *buffer,
UINT32 length, UINT32 *data);
UINT32 simple_buffer_avail(struct simple_buffer *buffer);
/* A packet processing function.
*
* Typically, real processors will extend this struct, with fields
* such as the process parameters, next processor, output socket, etc.
* */
typedef int (*raw_processor_function)(struct packet_processor *context,
struct simple_packet *packet);
struct packet_processor
{
/* Returns some (so far unspecified) return code */
raw_processor_function f;
};
int apply_processor(struct packet_processor *closure,
struct simple_packet *packet);
/* A processor that passes its result on to another processor */
struct chained_processor
{
struct packet_processor p;
struct *packet_processor *next;
};
#endif /* LSH_TRANSPORT_H_INCLUDED */
/* zlib.c
*
*/
#include "zlib.h"
#define
static int do_deflate(struct zlib_processor *closure,
struct simple_packet *packet)
{
struct simple_packet *new;
/* call deflate, copy into new packet */
new = simple_packet_alloc(...);
simple_packet_free(packet);
return apply_processor(closure->c->next, new);
}
struct packet_processor *make_zlib_processor(packet_processor *continuation,
int level)
{
struct debug_processor *closure = xalloc(sizeof(struct zlib_processor));
closure->c->p->f = (raw_processor_function) do_deflate;
closure->c->next = continuation;
/* inititialize closure->zstream */
return (packet_processor) closure;
}
/* zlib.h
*
* Processor to compress packets using zlib
*/
#ifndef LSH_ZLIB_H_INCLUDED
#define LSH_ZLIB_H_INCLUDED
/* The input to the compressor should be a packet with payload only. */
struct zlib_processor
{
struct chained_processor c;
z_stream state;
}
struct packet_processor *make_zlib_processor(packet_processor *continuation,
level);
#endif /* LSH_ZLIB_H_INCLUDED */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment