diff options
Diffstat (limited to 'openssl/demos/tunala/tunala.h')
-rw-r--r-- | openssl/demos/tunala/tunala.h | 215 |
1 files changed, 215 insertions, 0 deletions
diff --git a/openssl/demos/tunala/tunala.h b/openssl/demos/tunala/tunala.h new file mode 100644 index 000000000..3a752f259 --- /dev/null +++ b/openssl/demos/tunala/tunala.h @@ -0,0 +1,215 @@ +/* Tunala ("Tunneler with a New Zealand accent") + * + * Written by Geoff Thorpe, but endorsed/supported by noone. Please use this is + * if it's useful or informative to you, but it's only here as a scratchpad for + * ideas about how you might (or might not) program with OpenSSL. If you deploy + * this is in a mission-critical environment, and have not read, understood, + * audited, and modified this code to your satisfaction, and the result is that + * all hell breaks loose and you are looking for a new employer, then it proves + * nothing except perhaps that Darwinism is alive and well. Let's just say, *I* + * don't use this in a mission-critical environment, so it would be stupid for + * anyone to assume that it is solid and/or tested enough when even its author + * doesn't place that much trust in it. You have been warned. + * + * With thanks to Cryptographic Appliances, Inc. + */ + +#ifndef _TUNALA_H +#define _TUNALA_H + +/* pull in autoconf fluff */ +#ifndef NO_CONFIG_H +#include "config.h" +#else +/* We don't have autoconf, we have to set all of these unless a tweaked Makefile + * tells us not to ... */ +/* headers */ +#ifndef NO_HAVE_SELECT +#define HAVE_SELECT +#endif +#ifndef NO_HAVE_SOCKET +#define HAVE_SOCKET +#endif +#ifndef NO_HAVE_UNISTD_H +#define HAVE_UNISTD_H +#endif +#ifndef NO_HAVE_FCNTL_H +#define HAVE_FCNTL_H +#endif +#ifndef NO_HAVE_LIMITS_H +#define HAVE_LIMITS_H +#endif +/* features */ +#ifndef NO_HAVE_STRSTR +#define HAVE_STRSTR +#endif +#ifndef NO_HAVE_STRTOUL +#define HAVE_STRTOUL +#endif +#endif + +#if !defined(HAVE_SELECT) || !defined(HAVE_SOCKET) +#error "can't build without some network basics like select() and socket()" +#endif + +#include <stdlib.h> +#ifndef NO_SYSTEM_H +#include <string.h> +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#ifdef HAVE_FCNTL_H +#include <fcntl.h> +#endif +#ifdef HAVE_LIMITS_H +#include <limits.h> +#endif +#include <netdb.h> +#include <signal.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <netinet/in.h> +#endif /* !defined(NO_SYSTEM_H) */ + +#ifndef NO_OPENSSL +#include <openssl/err.h> +#include <openssl/engine.h> +#include <openssl/ssl.h> +#endif /* !defined(NO_OPENSSL) */ + +#ifndef OPENSSL_NO_BUFFER +/* This is the generic "buffer" type that is used when feeding the + * state-machine. It's basically a FIFO with respect to the "adddata" & + * "takedata" type functions that operate on it. */ +#define MAX_DATA_SIZE 16384 +typedef struct _buffer_t { + unsigned char data[MAX_DATA_SIZE]; + unsigned int used; + /* Statistical values - counts the total number of bytes read in and + * read out (respectively) since "buffer_init()" */ + unsigned long total_in, total_out; +} buffer_t; + +/* Initialise a buffer structure before use */ +void buffer_init(buffer_t *buf); +/* Cleanup a buffer structure - presently not needed, but if buffer_t is + * converted to using dynamic allocation, this would be required - so should be + * called to protect against an explosion of memory leaks later if the change is + * made. */ +void buffer_close(buffer_t *buf); + +/* Basic functions to manipulate buffers */ + +unsigned int buffer_used(buffer_t *buf); /* How much data in the buffer */ +unsigned int buffer_unused(buffer_t *buf); /* How much space in the buffer */ +int buffer_full(buffer_t *buf); /* Boolean, is it full? */ +int buffer_notfull(buffer_t *buf); /* Boolean, is it not full? */ +int buffer_empty(buffer_t *buf); /* Boolean, is it empty? */ +int buffer_notempty(buffer_t *buf); /* Boolean, is it not empty? */ +unsigned long buffer_total_in(buffer_t *buf); /* Total bytes written to buffer */ +unsigned long buffer_total_out(buffer_t *buf); /* Total bytes read from buffer */ + +#if 0 /* Currently used only within buffer.c - better to expose only + * higher-level functions anyway */ +/* Add data to the tail of the buffer, returns the amount that was actually + * added (so, you need to check if return value is less than size) */ +unsigned int buffer_adddata(buffer_t *buf, const unsigned char *ptr, + unsigned int size); + +/* Take data from the front of the buffer (and scroll the rest forward). If + * "ptr" is NULL, this just removes data off the front of the buffer. Return + * value is the amount actually removed (can be less than size if the buffer has + * too little data). */ +unsigned int buffer_takedata(buffer_t *buf, unsigned char *ptr, + unsigned int size); + +/* Flushes as much data as possible out of the "from" buffer into the "to" + * buffer. Return value is the amount moved. The amount moved can be restricted + * to a maximum by specifying "cap" - setting it to -1 means no limit. */ +unsigned int buffer_tobuffer(buffer_t *to, buffer_t *from, int cap); +#endif + +#ifndef NO_IP +/* Read or write between a file-descriptor and a buffer */ +int buffer_from_fd(buffer_t *buf, int fd); +int buffer_to_fd(buffer_t *buf, int fd); +#endif /* !defined(NO_IP) */ + +#ifndef NO_OPENSSL +/* Read or write between an SSL or BIO and a buffer */ +void buffer_from_SSL(buffer_t *buf, SSL *ssl); +void buffer_to_SSL(buffer_t *buf, SSL *ssl); +void buffer_from_BIO(buffer_t *buf, BIO *bio); +void buffer_to_BIO(buffer_t *buf, BIO *bio); + +/* Callbacks */ +void cb_ssl_info(const SSL *s, int where, int ret); +void cb_ssl_info_set_output(FILE *fp); /* Called if output should be sent too */ +int cb_ssl_verify(int ok, X509_STORE_CTX *ctx); +void cb_ssl_verify_set_output(FILE *fp); +void cb_ssl_verify_set_depth(unsigned int verify_depth); +void cb_ssl_verify_set_level(unsigned int level); +RSA *cb_generate_tmp_rsa(SSL *s, int is_export, int keylength); +#endif /* !defined(NO_OPENSSL) */ +#endif /* !defined(OPENSSL_NO_BUFFER) */ + +#ifndef NO_TUNALA +#ifdef OPENSSL_NO_BUFFER +#error "TUNALA section of tunala.h requires BUFFER support" +#endif +typedef struct _state_machine_t { + SSL *ssl; + BIO *bio_intossl; + BIO *bio_fromssl; + buffer_t clean_in, clean_out; + buffer_t dirty_in, dirty_out; +} state_machine_t; +typedef enum { + SM_CLEAN_IN, SM_CLEAN_OUT, + SM_DIRTY_IN, SM_DIRTY_OUT +} sm_buffer_t; +void state_machine_init(state_machine_t *machine); +void state_machine_close(state_machine_t *machine); +buffer_t *state_machine_get_buffer(state_machine_t *machine, sm_buffer_t type); +SSL *state_machine_get_SSL(state_machine_t *machine); +int state_machine_set_SSL(state_machine_t *machine, SSL *ssl, int is_server); +/* Performs the data-IO loop and returns zero if the machine should close */ +int state_machine_churn(state_machine_t *machine); +/* Is used to handle closing conditions - namely when one side of the tunnel has + * closed but the other should finish flushing. */ +int state_machine_close_clean(state_machine_t *machine); +int state_machine_close_dirty(state_machine_t *machine); +#endif /* !defined(NO_TUNALA) */ + +#ifndef NO_IP +/* Initialise anything related to the networking. This includes blocking pesky + * SIGPIPE signals. */ +int ip_initialise(void); +/* ip is the 4-byte ip address (eg. 127.0.0.1 is {0x7F,0x00,0x00,0x01}), port is + * the port to listen on (host byte order), and the return value is the + * file-descriptor or -1 on error. */ +int ip_create_listener_split(const char *ip, unsigned short port); +/* Same semantics as above. */ +int ip_create_connection_split(const char *ip, unsigned short port); +/* Converts a string into the ip/port before calling the above */ +int ip_create_listener(const char *address); +int ip_create_connection(const char *address); +/* Just does a string conversion on its own. NB: If accept_all_ip is non-zero, + * then the address string could be just a port. Ie. it's suitable for a + * listening address but not a connecting address. */ +int ip_parse_address(const char *address, const char **parsed_ip, + unsigned short *port, int accept_all_ip); +/* Accepts an incoming connection through the listener. Assumes selects and + * what-not have deemed it an appropriate thing to do. */ +int ip_accept_connection(int listen_fd); +#endif /* !defined(NO_IP) */ + +/* These functions wrap up things that can be portability hassles. */ +int int_strtoul(const char *str, unsigned long *val); +#ifdef HAVE_STRSTR +#define int_strstr strstr +#else +char *int_strstr(const char *haystack, const char *needle); +#endif + +#endif /* !defined(_TUNALA_H) */ |