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