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