📄 tunala.h
字号:
/* Tunala ("Tunneler with a New Zealand accent") * * Written by Geoff Thorpe, but endorsed/supported by noone. Please use this is * if it's useful or informative to you, but it's only here as a scratchpad for * ideas about how you might (or might not) program with OpenSSL. If you deploy * this is in a mission-critical environment, and have not read, understood, * audited, and modified this code to your satisfaction, and the result is that * all hell breaks loose and you are looking for a new employer, then it proves * nothing except perhaps that Darwinism is alive and well. Let's just say, *I* * don't use this in a mission-critical environment, so it would be stupid for * anyone to assume that it is solid and/or tested enough when even its author * doesn't place that much trust in it. You have been warned. * * With thanks to Cryptographic Appliances, Inc. */#ifndef _TUNALA_H#define _TUNALA_H/* pull in autoconf fluff */#ifndef NO_CONFIG_H#include "config.h"#else/* We don't have autoconf, we have to set all of these unless a tweaked Makefile * tells us not to ... *//* headers */#ifndef NO_HAVE_SELECT#define HAVE_SELECT#endif#ifndef NO_HAVE_SOCKET#define HAVE_SOCKET#endif#ifndef NO_HAVE_UNISTD_H#define HAVE_UNISTD_H#endif#ifndef NO_HAVE_FCNTL_H#define HAVE_FCNTL_H#endif#ifndef NO_HAVE_LIMITS_H#define HAVE_LIMITS_H#endif/* features */#ifndef NO_HAVE_STRSTR#define HAVE_STRSTR#endif#ifndef NO_HAVE_STRTOUL#define HAVE_STRTOUL#endif#endif#if !defined(HAVE_SELECT) || !defined(HAVE_SOCKET)#error "can't build without some network basics like select() and socket()"#endif#include <stdlib.h>#ifndef NO_SYSTEM_H#include <string.h>#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#ifdef HAVE_FCNTL_H#include <fcntl.h>#endif#ifdef HAVE_LIMITS_H#include <limits.h>#endif#include <netdb.h>#include <signal.h>#include <sys/socket.h>#include <sys/types.h>#include <netinet/in.h>#endif /* !defined(NO_SYSTEM_H) */#ifndef NO_OPENSSL#include <openssl/err.h>#include <openssl/engine.h>#include <openssl/ssl.h>#endif /* !defined(NO_OPENSSL) */#ifndef OPENSSL_NO_BUFFER/* This is the generic "buffer" type that is used when feeding the * state-machine. It's basically a FIFO with respect to the "adddata" & * "takedata" type functions that operate on it. */#define MAX_DATA_SIZE 16384typedef struct _buffer_t { unsigned char data[MAX_DATA_SIZE]; unsigned int used; /* Statistical values - counts the total number of bytes read in and * read out (respectively) since "buffer_init()" */ unsigned long total_in, total_out;} buffer_t;/* Initialise a buffer structure before use */void buffer_init(buffer_t *buf);/* Cleanup a buffer structure - presently not needed, but if buffer_t is * converted to using dynamic allocation, this would be required - so should be * called to protect against an explosion of memory leaks later if the change is * made. */void buffer_close(buffer_t *buf);/* Basic functions to manipulate buffers */unsigned int buffer_used(buffer_t *buf); /* How much data in the buffer */unsigned int buffer_unused(buffer_t *buf); /* How much space in the buffer */int buffer_full(buffer_t *buf); /* Boolean, is it full? */int buffer_notfull(buffer_t *buf); /* Boolean, is it not full? */int buffer_empty(buffer_t *buf); /* Boolean, is it empty? */int buffer_notempty(buffer_t *buf); /* Boolean, is it not empty? */unsigned long buffer_total_in(buffer_t *buf); /* Total bytes written to buffer */unsigned long buffer_total_out(buffer_t *buf); /* Total bytes read from buffer */#if 0 /* Currently used only within buffer.c - better to expose only * higher-level functions anyway *//* Add data to the tail of the buffer, returns the amount that was actually * added (so, you need to check if return value is less than size) */unsigned int buffer_adddata(buffer_t *buf, const unsigned char *ptr, unsigned int size);/* Take data from the front of the buffer (and scroll the rest forward). If * "ptr" is NULL, this just removes data off the front of the buffer. Return * value is the amount actually removed (can be less than size if the buffer has * too little data). */unsigned int buffer_takedata(buffer_t *buf, unsigned char *ptr, unsigned int size);/* Flushes as much data as possible out of the "from" buffer into the "to" * buffer. Return value is the amount moved. The amount moved can be restricted * to a maximum by specifying "cap" - setting it to -1 means no limit. */unsigned int buffer_tobuffer(buffer_t *to, buffer_t *from, int cap);#endif#ifndef NO_IP/* Read or write between a file-descriptor and a buffer */int buffer_from_fd(buffer_t *buf, int fd);int buffer_to_fd(buffer_t *buf, int fd);#endif /* !defined(NO_IP) */#ifndef NO_OPENSSL/* Read or write between an SSL or BIO and a buffer */void buffer_from_SSL(buffer_t *buf, SSL *ssl);void buffer_to_SSL(buffer_t *buf, SSL *ssl);void buffer_from_BIO(buffer_t *buf, BIO *bio);void buffer_to_BIO(buffer_t *buf, BIO *bio);/* Callbacks */void cb_ssl_info(const SSL *s, int where, int ret);void cb_ssl_info_set_output(FILE *fp); /* Called if output should be sent too */int cb_ssl_verify(int ok, X509_STORE_CTX *ctx);void cb_ssl_verify_set_output(FILE *fp);void cb_ssl_verify_set_depth(unsigned int verify_depth);void cb_ssl_verify_set_level(unsigned int level);RSA *cb_generate_tmp_rsa(SSL *s, int is_export, int keylength);#endif /* !defined(NO_OPENSSL) */#endif /* !defined(OPENSSL_NO_BUFFER) */#ifndef NO_TUNALA#ifdef OPENSSL_NO_BUFFER#error "TUNALA section of tunala.h requires BUFFER support"#endiftypedef struct _state_machine_t { SSL *ssl; BIO *bio_intossl; BIO *bio_fromssl; buffer_t clean_in, clean_out; buffer_t dirty_in, dirty_out;} state_machine_t;typedef enum { SM_CLEAN_IN, SM_CLEAN_OUT, SM_DIRTY_IN, SM_DIRTY_OUT} sm_buffer_t;void state_machine_init(state_machine_t *machine);void state_machine_close(state_machine_t *machine);buffer_t *state_machine_get_buffer(state_machine_t *machine, sm_buffer_t type);SSL *state_machine_get_SSL(state_machine_t *machine);int state_machine_set_SSL(state_machine_t *machine, SSL *ssl, int is_server);/* Performs the data-IO loop and returns zero if the machine should close */int state_machine_churn(state_machine_t *machine);/* Is used to handle closing conditions - namely when one side of the tunnel has * closed but the other should finish flushing. */int state_machine_close_clean(state_machine_t *machine);int state_machine_close_dirty(state_machine_t *machine);#endif /* !defined(NO_TUNALA) */#ifndef NO_IP/* Initialise anything related to the networking. This includes blocking pesky * SIGPIPE signals. */int ip_initialise(void);/* ip is the 4-byte ip address (eg. 127.0.0.1 is {0x7F,0x00,0x00,0x01}), port is * the port to listen on (host byte order), and the return value is the * file-descriptor or -1 on error. */int ip_create_listener_split(const char *ip, unsigned short port);/* Same semantics as above. */int ip_create_connection_split(const char *ip, unsigned short port);/* Converts a string into the ip/port before calling the above */int ip_create_listener(const char *address);int ip_create_connection(const char *address);/* Just does a string conversion on its own. NB: If accept_all_ip is non-zero, * then the address string could be just a port. Ie. it's suitable for a * listening address but not a connecting address. */int ip_parse_address(const char *address, const char **parsed_ip, unsigned short *port, int accept_all_ip);/* Accepts an incoming connection through the listener. Assumes selects and * what-not have deemed it an appropriate thing to do. */int ip_accept_connection(int listen_fd);#endif /* !defined(NO_IP) *//* These functions wrap up things that can be portability hassles. */int int_strtoul(const char *str, unsigned long *val);#ifdef HAVE_STRSTR#define int_strstr strstr#elsechar *int_strstr(const char *haystack, const char *needle);#endif#endif /* !defined(_TUNALA_H) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -