xref: /minix3/crypto/external/bsd/openssl/dist/demos/tunala/tunala.h (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
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