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