1*0a6a1f1dSLionel Sambuc /* 2*0a6a1f1dSLionel Sambuc * Tunala ("Tunneler with a New Zealand accent") Written by Geoff Thorpe, 3*0a6a1f1dSLionel Sambuc * but endorsed/supported by noone. Please use this is if it's useful or 4*0a6a1f1dSLionel Sambuc * informative to you, but it's only here as a scratchpad for ideas about how 5*0a6a1f1dSLionel Sambuc * you might (or might not) program with OpenSSL. If you deploy this is in a 6*0a6a1f1dSLionel Sambuc * mission-critical environment, and have not read, understood, audited, and 7*0a6a1f1dSLionel Sambuc * modified this code to your satisfaction, and the result is that all hell 8*0a6a1f1dSLionel Sambuc * breaks loose and you are looking for a new employer, then it proves 9*0a6a1f1dSLionel Sambuc * nothing except perhaps that Darwinism is alive and well. Let's just say, 10*0a6a1f1dSLionel Sambuc * *I* don't use this in a mission-critical environment, so it would be 11*0a6a1f1dSLionel Sambuc * stupid for anyone to assume that it is solid and/or tested enough when 12*0a6a1f1dSLionel Sambuc * even its author doesn't place that much trust in it. You have been warned. 13ebfedea0SLionel Sambuc * With thanks to Cryptographic Appliances, Inc. 14ebfedea0SLionel Sambuc */ 15ebfedea0SLionel Sambuc 16ebfedea0SLionel Sambuc #ifndef _TUNALA_H 17ebfedea0SLionel Sambuc # define _TUNALA_H 18ebfedea0SLionel Sambuc 19ebfedea0SLionel Sambuc /* pull in autoconf fluff */ 20ebfedea0SLionel Sambuc # ifndef NO_CONFIG_H 21ebfedea0SLionel Sambuc # include "config.h" 22ebfedea0SLionel Sambuc # else 23*0a6a1f1dSLionel Sambuc /* 24*0a6a1f1dSLionel Sambuc * We don't have autoconf, we have to set all of these unless a tweaked 25*0a6a1f1dSLionel Sambuc * Makefile tells us not to ... 26*0a6a1f1dSLionel Sambuc */ 27ebfedea0SLionel Sambuc /* headers */ 28ebfedea0SLionel Sambuc # ifndef NO_HAVE_SELECT 29ebfedea0SLionel Sambuc # define HAVE_SELECT 30ebfedea0SLionel Sambuc # endif 31ebfedea0SLionel Sambuc # ifndef NO_HAVE_SOCKET 32ebfedea0SLionel Sambuc # define HAVE_SOCKET 33ebfedea0SLionel Sambuc # endif 34ebfedea0SLionel Sambuc # ifndef NO_HAVE_UNISTD_H 35ebfedea0SLionel Sambuc # define HAVE_UNISTD_H 36ebfedea0SLionel Sambuc # endif 37ebfedea0SLionel Sambuc # ifndef NO_HAVE_FCNTL_H 38ebfedea0SLionel Sambuc # define HAVE_FCNTL_H 39ebfedea0SLionel Sambuc # endif 40ebfedea0SLionel Sambuc # ifndef NO_HAVE_LIMITS_H 41ebfedea0SLionel Sambuc # define HAVE_LIMITS_H 42ebfedea0SLionel Sambuc # endif 43ebfedea0SLionel Sambuc /* features */ 44ebfedea0SLionel Sambuc # ifndef NO_HAVE_STRSTR 45ebfedea0SLionel Sambuc # define HAVE_STRSTR 46ebfedea0SLionel Sambuc # endif 47ebfedea0SLionel Sambuc # ifndef NO_HAVE_STRTOUL 48ebfedea0SLionel Sambuc # define HAVE_STRTOUL 49ebfedea0SLionel Sambuc # endif 50ebfedea0SLionel Sambuc # endif 51ebfedea0SLionel Sambuc 52ebfedea0SLionel Sambuc # if !defined(HAVE_SELECT) || !defined(HAVE_SOCKET) 53ebfedea0SLionel Sambuc # error "can't build without some network basics like select() and socket()" 54ebfedea0SLionel Sambuc # endif 55ebfedea0SLionel Sambuc 56ebfedea0SLionel Sambuc # include <stdlib.h> 57ebfedea0SLionel Sambuc # ifndef NO_SYSTEM_H 58ebfedea0SLionel Sambuc # include <string.h> 59ebfedea0SLionel Sambuc # ifdef HAVE_UNISTD_H 60ebfedea0SLionel Sambuc # include <unistd.h> 61ebfedea0SLionel Sambuc # endif 62ebfedea0SLionel Sambuc # ifdef HAVE_FCNTL_H 63ebfedea0SLionel Sambuc # include <fcntl.h> 64ebfedea0SLionel Sambuc # endif 65ebfedea0SLionel Sambuc # ifdef HAVE_LIMITS_H 66ebfedea0SLionel Sambuc # include <limits.h> 67ebfedea0SLionel Sambuc # endif 68ebfedea0SLionel Sambuc # include <netdb.h> 69ebfedea0SLionel Sambuc # include <signal.h> 70ebfedea0SLionel Sambuc # include <sys/socket.h> 71ebfedea0SLionel Sambuc # include <sys/types.h> 72ebfedea0SLionel Sambuc # include <netinet/in.h> 73ebfedea0SLionel Sambuc # endif /* !defined(NO_SYSTEM_H) */ 74ebfedea0SLionel Sambuc 75ebfedea0SLionel Sambuc # ifndef NO_OPENSSL 76ebfedea0SLionel Sambuc # include <openssl/err.h> 77ebfedea0SLionel Sambuc # include <openssl/engine.h> 78ebfedea0SLionel Sambuc # include <openssl/ssl.h> 79ebfedea0SLionel Sambuc # endif /* !defined(NO_OPENSSL) */ 80ebfedea0SLionel Sambuc 81ebfedea0SLionel Sambuc # ifndef OPENSSL_NO_BUFFER 82*0a6a1f1dSLionel Sambuc /* 83*0a6a1f1dSLionel Sambuc * This is the generic "buffer" type that is used when feeding the 84ebfedea0SLionel Sambuc * state-machine. It's basically a FIFO with respect to the "adddata" & 85*0a6a1f1dSLionel Sambuc * "takedata" type functions that operate on it. 86*0a6a1f1dSLionel Sambuc */ 87ebfedea0SLionel Sambuc # define MAX_DATA_SIZE 16384 88ebfedea0SLionel Sambuc typedef struct _buffer_t { 89ebfedea0SLionel Sambuc unsigned char data[MAX_DATA_SIZE]; 90ebfedea0SLionel Sambuc unsigned int used; 91*0a6a1f1dSLionel Sambuc /* 92*0a6a1f1dSLionel Sambuc * Statistical values - counts the total number of bytes read in and read 93*0a6a1f1dSLionel Sambuc * out (respectively) since "buffer_init()" 94*0a6a1f1dSLionel Sambuc */ 95ebfedea0SLionel Sambuc unsigned long total_in, total_out; 96ebfedea0SLionel Sambuc } buffer_t; 97ebfedea0SLionel Sambuc 98ebfedea0SLionel Sambuc /* Initialise a buffer structure before use */ 99ebfedea0SLionel Sambuc void buffer_init(buffer_t * buf); 100*0a6a1f1dSLionel Sambuc /* 101*0a6a1f1dSLionel Sambuc * Cleanup a buffer structure - presently not needed, but if buffer_t is 102*0a6a1f1dSLionel Sambuc * converted to using dynamic allocation, this would be required - so should 103*0a6a1f1dSLionel Sambuc * be called to protect against an explosion of memory leaks later if the 104*0a6a1f1dSLionel Sambuc * change is made. 105*0a6a1f1dSLionel Sambuc */ 106ebfedea0SLionel Sambuc void buffer_close(buffer_t * buf); 107ebfedea0SLionel Sambuc 108ebfedea0SLionel Sambuc /* Basic functions to manipulate buffers */ 109ebfedea0SLionel Sambuc 110ebfedea0SLionel Sambuc unsigned int buffer_used(buffer_t * buf); /* How much data in the buffer */ 111ebfedea0SLionel Sambuc unsigned int buffer_unused(buffer_t * buf); /* How much space in the buffer */ 112ebfedea0SLionel Sambuc int buffer_full(buffer_t * buf); /* Boolean, is it full? */ 113ebfedea0SLionel Sambuc int buffer_notfull(buffer_t * buf); /* Boolean, is it not full? */ 114ebfedea0SLionel Sambuc int buffer_empty(buffer_t * buf); /* Boolean, is it empty? */ 115ebfedea0SLionel Sambuc int buffer_notempty(buffer_t * buf); /* Boolean, is it not empty? */ 116*0a6a1f1dSLionel Sambuc unsigned long buffer_total_in(buffer_t * buf); /* Total bytes written to 117*0a6a1f1dSLionel Sambuc * buffer */ 118*0a6a1f1dSLionel Sambuc unsigned long buffer_total_out(buffer_t * buf); /* Total bytes read from 119*0a6a1f1dSLionel Sambuc * buffer */ 120ebfedea0SLionel Sambuc 121*0a6a1f1dSLionel Sambuc # if 0 /* Currently used only within buffer.c - 122*0a6a1f1dSLionel Sambuc * better to expose only higher-level 123*0a6a1f1dSLionel Sambuc * functions anyway */ 124*0a6a1f1dSLionel Sambuc /* 125*0a6a1f1dSLionel Sambuc * Add data to the tail of the buffer, returns the amount that was actually 126*0a6a1f1dSLionel Sambuc * added (so, you need to check if return value is less than size) 127*0a6a1f1dSLionel Sambuc */ 128ebfedea0SLionel Sambuc unsigned int buffer_adddata(buffer_t * buf, const unsigned char *ptr, 129ebfedea0SLionel Sambuc unsigned int size); 130ebfedea0SLionel Sambuc 131*0a6a1f1dSLionel Sambuc /* 132*0a6a1f1dSLionel Sambuc * Take data from the front of the buffer (and scroll the rest forward). If 133ebfedea0SLionel Sambuc * "ptr" is NULL, this just removes data off the front of the buffer. Return 134*0a6a1f1dSLionel Sambuc * value is the amount actually removed (can be less than size if the buffer 135*0a6a1f1dSLionel Sambuc * has too little data). 136*0a6a1f1dSLionel Sambuc */ 137ebfedea0SLionel Sambuc unsigned int buffer_takedata(buffer_t * buf, unsigned char *ptr, 138ebfedea0SLionel Sambuc unsigned int size); 139ebfedea0SLionel Sambuc 140*0a6a1f1dSLionel Sambuc /* 141*0a6a1f1dSLionel Sambuc * Flushes as much data as possible out of the "from" buffer into the "to" 142*0a6a1f1dSLionel Sambuc * buffer. Return value is the amount moved. The amount moved can be 143*0a6a1f1dSLionel Sambuc * restricted to a maximum by specifying "cap" - setting it to -1 means no 144*0a6a1f1dSLionel Sambuc * limit. 145*0a6a1f1dSLionel Sambuc */ 146ebfedea0SLionel Sambuc unsigned int buffer_tobuffer(buffer_t * to, buffer_t * from, int cap); 147ebfedea0SLionel Sambuc # endif 148ebfedea0SLionel Sambuc 149ebfedea0SLionel Sambuc # ifndef NO_IP 150ebfedea0SLionel Sambuc /* Read or write between a file-descriptor and a buffer */ 151ebfedea0SLionel Sambuc int buffer_from_fd(buffer_t * buf, int fd); 152ebfedea0SLionel Sambuc int buffer_to_fd(buffer_t * buf, int fd); 153ebfedea0SLionel Sambuc # endif /* !defined(NO_IP) */ 154ebfedea0SLionel Sambuc 155ebfedea0SLionel Sambuc # ifndef NO_OPENSSL 156ebfedea0SLionel Sambuc /* Read or write between an SSL or BIO and a buffer */ 157ebfedea0SLionel Sambuc void buffer_from_SSL(buffer_t * buf, SSL *ssl); 158ebfedea0SLionel Sambuc void buffer_to_SSL(buffer_t * buf, SSL *ssl); 159ebfedea0SLionel Sambuc void buffer_from_BIO(buffer_t * buf, BIO *bio); 160ebfedea0SLionel Sambuc void buffer_to_BIO(buffer_t * buf, BIO *bio); 161ebfedea0SLionel Sambuc 162ebfedea0SLionel Sambuc /* Callbacks */ 163ebfedea0SLionel Sambuc void cb_ssl_info(const SSL *s, int where, int ret); 164*0a6a1f1dSLionel Sambuc /* Called if output should be sent too */ 165*0a6a1f1dSLionel Sambuc void cb_ssl_info_set_output(FILE *fp); 166ebfedea0SLionel Sambuc int cb_ssl_verify(int ok, X509_STORE_CTX *ctx); 167ebfedea0SLionel Sambuc void cb_ssl_verify_set_output(FILE *fp); 168ebfedea0SLionel Sambuc void cb_ssl_verify_set_depth(unsigned int verify_depth); 169ebfedea0SLionel Sambuc void cb_ssl_verify_set_level(unsigned int level); 170ebfedea0SLionel Sambuc RSA *cb_generate_tmp_rsa(SSL *s, int is_export, int keylength); 171ebfedea0SLionel Sambuc # endif /* !defined(NO_OPENSSL) */ 172ebfedea0SLionel Sambuc # endif /* !defined(OPENSSL_NO_BUFFER) */ 173ebfedea0SLionel Sambuc 174ebfedea0SLionel Sambuc # ifndef NO_TUNALA 175ebfedea0SLionel Sambuc # ifdef OPENSSL_NO_BUFFER 176ebfedea0SLionel Sambuc # error "TUNALA section of tunala.h requires BUFFER support" 177ebfedea0SLionel Sambuc # endif 178ebfedea0SLionel Sambuc typedef struct _state_machine_t { 179ebfedea0SLionel Sambuc SSL *ssl; 180ebfedea0SLionel Sambuc BIO *bio_intossl; 181ebfedea0SLionel Sambuc BIO *bio_fromssl; 182ebfedea0SLionel Sambuc buffer_t clean_in, clean_out; 183ebfedea0SLionel Sambuc buffer_t dirty_in, dirty_out; 184ebfedea0SLionel Sambuc } state_machine_t; 185ebfedea0SLionel Sambuc typedef enum { 186ebfedea0SLionel Sambuc SM_CLEAN_IN, SM_CLEAN_OUT, 187ebfedea0SLionel Sambuc SM_DIRTY_IN, SM_DIRTY_OUT 188ebfedea0SLionel Sambuc } sm_buffer_t; 189ebfedea0SLionel Sambuc void state_machine_init(state_machine_t * machine); 190ebfedea0SLionel Sambuc void state_machine_close(state_machine_t * machine); 191*0a6a1f1dSLionel Sambuc buffer_t *state_machine_get_buffer(state_machine_t * machine, 192*0a6a1f1dSLionel Sambuc sm_buffer_t type); 193ebfedea0SLionel Sambuc SSL *state_machine_get_SSL(state_machine_t * machine); 194ebfedea0SLionel Sambuc int state_machine_set_SSL(state_machine_t * machine, SSL *ssl, int is_server); 195ebfedea0SLionel Sambuc /* Performs the data-IO loop and returns zero if the machine should close */ 196ebfedea0SLionel Sambuc int state_machine_churn(state_machine_t * machine); 197*0a6a1f1dSLionel Sambuc /* 198*0a6a1f1dSLionel Sambuc * Is used to handle closing conditions - namely when one side of the tunnel 199*0a6a1f1dSLionel Sambuc * has closed but the other should finish flushing. 200*0a6a1f1dSLionel Sambuc */ 201ebfedea0SLionel Sambuc int state_machine_close_clean(state_machine_t * machine); 202ebfedea0SLionel Sambuc int state_machine_close_dirty(state_machine_t * machine); 203ebfedea0SLionel Sambuc # endif /* !defined(NO_TUNALA) */ 204ebfedea0SLionel Sambuc 205ebfedea0SLionel Sambuc # ifndef NO_IP 206*0a6a1f1dSLionel Sambuc /* 207*0a6a1f1dSLionel Sambuc * Initialise anything related to the networking. This includes blocking 208*0a6a1f1dSLionel Sambuc * pesky SIGPIPE signals. 209*0a6a1f1dSLionel Sambuc */ 210ebfedea0SLionel Sambuc int ip_initialise(void); 211*0a6a1f1dSLionel Sambuc /* 212*0a6a1f1dSLionel Sambuc * ip is the 4-byte ip address (eg. 127.0.0.1 is {0x7F,0x00,0x00,0x01}), port 213*0a6a1f1dSLionel Sambuc * is the port to listen on (host byte order), and the return value is the 214*0a6a1f1dSLionel Sambuc * file-descriptor or -1 on error. 215*0a6a1f1dSLionel Sambuc */ 216ebfedea0SLionel Sambuc int ip_create_listener_split(const char *ip, unsigned short port); 217ebfedea0SLionel Sambuc /* Same semantics as above. */ 218ebfedea0SLionel Sambuc int ip_create_connection_split(const char *ip, unsigned short port); 219ebfedea0SLionel Sambuc /* Converts a string into the ip/port before calling the above */ 220ebfedea0SLionel Sambuc int ip_create_listener(const char *address); 221ebfedea0SLionel Sambuc int ip_create_connection(const char *address); 222*0a6a1f1dSLionel Sambuc /* 223*0a6a1f1dSLionel Sambuc * Just does a string conversion on its own. NB: If accept_all_ip is 224*0a6a1f1dSLionel Sambuc * non-zero, then the address string could be just a port. Ie. it's suitable 225*0a6a1f1dSLionel Sambuc * for a listening address but not a connecting address. 226*0a6a1f1dSLionel Sambuc */ 227ebfedea0SLionel Sambuc int ip_parse_address(const char *address, const char **parsed_ip, 228ebfedea0SLionel Sambuc unsigned short *port, int accept_all_ip); 229*0a6a1f1dSLionel Sambuc /* 230*0a6a1f1dSLionel Sambuc * Accepts an incoming connection through the listener. Assumes selects and 231*0a6a1f1dSLionel Sambuc * what-not have deemed it an appropriate thing to do. 232*0a6a1f1dSLionel Sambuc */ 233ebfedea0SLionel Sambuc int ip_accept_connection(int listen_fd); 234ebfedea0SLionel Sambuc # endif /* !defined(NO_IP) */ 235ebfedea0SLionel Sambuc 236ebfedea0SLionel Sambuc /* These functions wrap up things that can be portability hassles. */ 237ebfedea0SLionel Sambuc int int_strtoul(const char *str, unsigned long *val); 238ebfedea0SLionel Sambuc # ifdef HAVE_STRSTR 239ebfedea0SLionel Sambuc # define int_strstr strstr 240ebfedea0SLionel Sambuc # else 241ebfedea0SLionel Sambuc char *int_strstr(const char *haystack, const char *needle); 242ebfedea0SLionel Sambuc # endif 243ebfedea0SLionel Sambuc 244ebfedea0SLionel Sambuc #endif /* !defined(_TUNALA_H) */ 245