diff -u --new-file tpop3d-1.3.5.orig/Makefile.am tpop3d-1.3.5/Makefile.am --- tpop3d-1.3.5.orig/Makefile.am Sat Oct 27 10:37:30 2001 +++ tpop3d-1.3.5/Makefile.am Wed Oct 31 01:11:24 2001 @@ -33,6 +33,7 @@ strtok_r.c \ substvars.c \ tokenise.c \ + tptls.c \ util.c \ vector.c @@ -55,6 +56,7 @@ signals.h \ stringmap.h \ tokenise.h \ + tptls.h \ vector.h \ util.h diff -u --new-file tpop3d-1.3.5.orig/cfgdirectives.c tpop3d-1.3.5/cfgdirectives.c --- tpop3d-1.3.5.orig/cfgdirectives.c Sat Oct 13 19:55:41 2001 +++ tpop3d-1.3.5/cfgdirectives.c Fri Nov 2 10:37:12 2001 @@ -76,6 +76,11 @@ #ifdef USE_TCP_WRAPPERS "tcp-wrappers-name", #endif + +#ifdef USE_OPENSSL_TLS + "tls-certificate-file", + "tls-privatekey-file", +#endif /* final entry must be NULL */ NULL}; diff -u --new-file tpop3d-1.3.5.orig/connection.c tpop3d-1.3.5/connection.c --- tpop3d-1.3.5.orig/connection.c Sat Oct 20 19:30:40 2001 +++ tpop3d-1.3.5/connection.c Fri Nov 2 10:37:12 2001 @@ -31,6 +31,7 @@ #include "connection.h" #include "util.h" +#include "tptls.h" extern int verbose; @@ -120,6 +121,10 @@ goto fail; } +#ifdef USE_OPENSSL_TLS + c->tls_enabled = 0; +#endif + return c; fail: @@ -138,6 +143,10 @@ close(c->s); } +#ifdef USE_OPENSSL_TLS + if (c->tls_enabled) tls_stop_servertls(c); +#endif + if (c->a) authcontext_delete(c->a); if (c->m) (c->m)->delete(c->m); @@ -163,7 +172,13 @@ return -1; } do { - n = read(c->s, c->p, c->buffer + c->bufferlen - c->p); +#ifdef USE_OPENSSL_TLS + if (c->tls_enabled) + n = SSL_read(c->tls_connection, c->p, + c->buffer + c->bufferlen - c->p); + else +#endif + n = read(c->s, c->p, c->buffer + c->bufferlen - c->p); } while (n == -1 && errno == EINTR); if (n > 0) c->p += n; return n; @@ -206,6 +221,10 @@ {"UIDL", UIDL}, {"USER", USER}, {"LAST", LAST}, + {"CAPA", CAPA}, +#ifdef USE_OPENSSL_TLS + {"STLS", STLS}, +#endif {NULL, UNKNOWN}}; /* last command MUST have s = NULL */ pop3command connection_parsecommand(connection c) { @@ -294,7 +313,14 @@ x = xmalloc(l = (4 + strlen(s) + 3 + 1)); if (!x) return 0; snprintf(x, l, "%s %s\r\n", success ? "+OK" : "-ERR", s); - m = xwrite(c->s, x, l = strlen(x)); + +#ifdef USE_OPENSSL_TLS + if (c->tls_enabled) + m = SSL_write(c->tls_connection, x, l = strlen(x)); + else +#endif + + m = xwrite(c->s, x, l = strlen(x)); xfree(x); if (verbose) print_log(LOG_DEBUG, _("connection_sendresponse: client %s: sent `%s %s'"), c->idstr, success? "+OK" : "-ERR", s); @@ -311,7 +337,14 @@ x = xmalloc(l = (3 + strlen(s))); if (!x) return 0; snprintf(x, l, "%s\r\n", s); - m = xwrite(c->s, x, l = strlen(x)); + +#ifdef USE_OPENSSL_TLS + if (c->tls_enabled) + m = SSL_write(c->tls_connection, x, l = strlen(x)); + else +#endif + + m = xwrite(c->s, x, l = strlen(x)); xfree(x); return (m == l); } diff -u --new-file tpop3d-1.3.5.orig/connection.h tpop3d-1.3.5/connection.h --- tpop3d-1.3.5.orig/connection.h Thu Jun 7 14:13:17 2001 +++ tpop3d-1.3.5/connection.h Fri Nov 2 10:37:12 2001 @@ -11,6 +11,13 @@ #ifndef __CONNECTION_H_ /* include guard */ #define __CONNECTION_H_ +#ifdef USE_OPENSSL_TLS +#include +#define MD5Init MD5_Init +#define MD5Update MD5_Update +#define MD5Final MD5_Final +#endif + #include #include #include @@ -44,6 +51,11 @@ time_t idlesince; /* used to implement timeouts */ +#ifdef USE_OPENSSL_TLS + int tls_enabled; /* TLS enabled on this connection? */ + SSL *tls_connection; /* the OpenSSL TLS connection */ +#endif + int n_auth_tries, n_errors; char *user, *pass; /* state accumulated */ authcontext a; @@ -56,7 +68,11 @@ NOOP, PASS, QUIT, RETR, RSET, STAT, TOP, UIDL, USER, - LAST}; + LAST, CAPA, +#ifdef USE_OPENSSL_TLS + STLS, +#endif + }; typedef struct _pop3command { enum pop3_command_code cmd; diff -u --new-file tpop3d-1.3.5.orig/mailbox.h tpop3d-1.3.5/mailbox.h --- tpop3d-1.3.5.orig/mailbox.h Sun Jul 8 10:57:09 2001 +++ tpop3d-1.3.5/mailbox.h Fri Nov 2 10:38:53 2001 @@ -43,6 +43,10 @@ #include +#ifdef USE_OPENSSL_TLS +#include +#endif + /* struct indexpoint: * Individual messages which appear as files on FS for maildir or sections of * a file in a BSD mailspool. @@ -73,6 +77,10 @@ void (*delete)(mailbox m); int (*send_message)(mailbox m, int sck, const int i, int n); int (*apply_changes)(mailbox m); + +#ifdef USE_OPENSSL_TLS + int (*tls_send_message)(mailbox m, SSL *tls, const int i, int n); +#endif }; /* Return code from a mailbox constructor used to indicate non-presence of the @@ -107,6 +115,10 @@ int mailspool_build_index(mailbox m, char *filemem); int mailspool_send_message(mailbox m, int sck, const int i, int n); int mailspool_apply_changes(mailbox m); + +#ifdef USE_OPENSSL_TLS +int mailspool_tls_send_message(mailbox M, SSL *tls, const int i, int n); +#endif /* How long we wait between trying to lock the mailspool */ #define MAILSPOOL_LOCK_WAIT 2 diff -u --new-file tpop3d-1.3.5.orig/mailspool.c tpop3d-1.3.5/mailspool.c --- tpop3d-1.3.5.orig/mailspool.c Sat Oct 13 19:55:42 2001 +++ tpop3d-1.3.5/mailspool.c Fri Nov 2 10:40:18 2001 @@ -1,3 +1,4 @@ +B /* * mailspool.c: * Berkeley mailspool handling. @@ -49,6 +50,7 @@ #include "mailbox.h" #include "md5.h" #include "stringmap.h" +#include "tptls.h" #include "util.h" #ifdef MBOX_BSD_SAVE_INDICES @@ -149,6 +151,10 @@ M->apply_changes = mailspool_apply_changes; M->send_message = mailspool_send_message; +#ifdef USE_OPENSSL_TLS + M->tls_send_message = mailspool_tls_send_message; +#endif + /* Allocate space for the index. */ M->index = (struct indexpoint*)xcalloc(32, sizeof(struct indexpoint)); M->size = 32; @@ -366,8 +372,22 @@ if (!M) return 0; if (i < 0 || i >= M->num) return 0; x = M->index + i; + return write_file(M->fd, sck, x->offset, x->length + 1, x->msglength, n); } + +#ifdef USE_OPENSSL_TLS +int mailspool_tls_send_message(const mailbox M, SSL *tls, const int i, int n) { + struct indexpoint *x; + + if (!M) return 0; + if (i < 0 || i >= M->num) return 0; + x = M->index + i; + + return tls_write_file(M->fd, tls, x->offset, x->length + 1, x->msglength, n); +} +#endif + /* mailspool_apply_changes: * Apply deletions to a mailspool by mapping it and copying it in blocks. diff -u --new-file tpop3d-1.3.5.orig/main.c tpop3d-1.3.5/main.c --- tpop3d-1.3.5.orig/main.c Fri Oct 26 16:32:11 2001 +++ tpop3d-1.3.5/main.c Fri Nov 2 10:37:12 2001 @@ -47,6 +47,8 @@ #include "vector.h" #include "util.h" +#include "tptls.h" + /* The socket send buffer is set to this, so that we don't end up in a * position that we send so much data that the client will not have received * all of it before we time them out. @@ -79,6 +81,10 @@ connection *connections; /* Active connections. */ size_t max_connections; /* Number of connection slots allocated. */ +#ifdef USE_OPENSSL_TLS +int tls_engine_started = 0; /* Is the SSL/TLS engine is running? */ +#endif + /* Theory of operation: * The main loop is in net_loop, below; it calls listeners_ and * connections_pre_select, then calls select, then calls listeners_ and @@ -692,6 +698,13 @@ print_log(LOG_ERR, _("%s: no listen addresses obtained; exiting"), configfile); EXIT_REMOVING_PIDFILE(1); } + +#ifdef USE_OPENSSL_TLS + if (!(tls_engine_started = tls_init_engine())) { + print_log(LOG_ERR, _("can't initialize TLS engine")); + tls_stop_engine(); + } +#endif /* Find out the maximum number of children we may spawn at once. */ switch(config_get_int("max-children", &max_running_children)) { diff -u --new-file tpop3d-1.3.5.orig/md5.h tpop3d-1.3.5/md5.h --- tpop3d-1.3.5.orig/md5.h Thu Jun 7 14:13:17 2001 +++ tpop3d-1.3.5/md5.h Fri Nov 2 10:37:12 2001 @@ -23,6 +23,8 @@ documentation and/or software. */ +#ifndef USE_OPENSSL_TLS + #include "global.h" /* MD5 context. */ @@ -36,3 +38,5 @@ void MD5Update PROTO_LIST ((MD5_CTX *, unsigned char *, unsigned int)); void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *)); + +#endif diff -u --new-file tpop3d-1.3.5.orig/md5c.c tpop3d-1.3.5/md5c.c --- tpop3d-1.3.5.orig/md5c.c Sat Oct 13 19:55:42 2001 +++ tpop3d-1.3.5/md5c.c Fri Nov 2 10:37:12 2001 @@ -23,6 +23,8 @@ documentation and/or software. */ +#ifndef USE_OPENSSL_TLS + #include "md5.h" #include @@ -338,3 +340,5 @@ */ memset(output,value,len); } + +#endif diff -u --new-file tpop3d-1.3.5.orig/pop3.c tpop3d-1.3.5/pop3.c --- tpop3d-1.3.5.orig/pop3.c Sat Oct 13 19:55:43 2001 +++ tpop3d-1.3.5/pop3.c Fri Nov 2 10:37:12 2001 @@ -26,9 +26,14 @@ #include "authswitch.h" #include "connection.h" #include "util.h" +#include "tptls.h" extern int verbose; +#ifdef USE_OPENSSL_TLS +extern int tls_engine_started; +#endif + /* connection_do: * Makes a command do something on a connection, returning a code indicating * what the caller should do. @@ -39,9 +44,44 @@ /* This breaks the RFC, but is sensible. */ if (p->cmd != NOOP && p->cmd != UNKNOWN) c->idlesince = time(NULL); + if (p->cmd == CAPA) { + connection_sendresponse(c, 1, _("I can handle the following")); + connection_sendline(c, "TOP"); + connection_sendline(c, "USER"); + connection_sendline(c, "UIDL"); + +#ifdef USE_OPENSSL_TLS + if (tls_engine_started && !c->tls_enabled) + connection_sendline(c, "STLS"); +#endif + + connection_sendline(c, "."); + c->idlesince = time(NULL); + + return do_nothing; + } + if (c->state == authorisation) { /* Authorisation state: gather username and password. */ switch (p->cmd) { +#ifdef USE_OPENSSL_TLS + case STLS: + if (c->tls_enabled) { + connection_sendresponse(c, 0, _("SSL/TLS already running!")); + return do_nothing; + } + + if (tls_start_servertls(c)) { + connection_sendresponse(c, 1, _("Let's encrypt your conncetion with TLS")); + c->tls_enabled = tls_handshake(c); + } + else + connection_sendresponse(c, 0, _("Can't start SSL/TLS on this connection")); + + return do_nothing; + break; +#endif + case USER: if (p->toks->num != 2) { connection_sendresponse(c, 0, _("No, that's not right.")); @@ -390,10 +430,21 @@ print_log(LOG_DEBUG, _("connection_do: client %s: sending message %d (%d bytes)"), c->idstr, msg_num + 1, (int)curmsg->msglength); connection_sendresponse(c, 1, _("Message follows:")); - if (!(curmbox)->send_message(curmbox, c->s, msg_num, -1)) { - connection_sendresponse(c, 0, _("Oops")); - return close_connection; + +#ifdef USE_OPENSSL_TLS + if (c->tls_enabled) { + if (!(curmbox)->tls_send_message(curmbox, c->tls_connection, msg_num, -1)) { + connection_sendresponse(c, 0, _("Oops")); + return close_connection; + } } + else +#endif + if (!(curmbox)->send_message(curmbox, c->s, msg_num, -1)) { + connection_sendresponse(c, 0, _("Oops")); + return close_connection; + } + /* That might have taken a long time. */ c->idlesince = time(NULL); if (verbose) diff -u --new-file tpop3d-1.3.5.orig/tptls.c tpop3d-1.3.5/tptls.c --- tpop3d-1.3.5.orig/tptls.c Wed Dec 31 17:00:00 1969 +++ tpop3d-1.3.5/tptls.c Fri Nov 2 11:33:59 2001 @@ -0,0 +1,371 @@ +/* + * tptls.c: + * Enables SSL/TLS connections for tpop3d. + * + * Copyright (c) 2001 Ben Schumacher. All rights reserved. + * + */ + +#ifdef USE_OPENSSL_TLS + +#ifdef HAVE_CONFIG_H +#include "configuration.h" +#endif /* HAVE_CONFIG_H */ + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "stringmap.h" +#include "tptls.h" +#include "util.h" + +extern stringmap config; + +int tls_verbose = 0; +SSL_CTX *tls_ctx = NULL; +char *cert_file = NULL, *key_file = NULL; + +/* tls_print_errors: + * um... prints our errors related to SSL/TLS + */ +void tls_print_errors(void) { + unsigned long l; + const char *file; + const char *data; + int line; + int flags; + unsigned long es; + + es = CRYPTO_thread_id(); + while ((l = ERR_get_error_line_data(&file, &line, &data, &flags)) != 0) { + if (flags & ERR_TXT_STRING) + print_log(LOG_ERR, + "%s: %lu:%.256s:%.256s:%d:%.256s", __FILE__, + es, ERR_error_string(l, NULL), file, line, + data); + else + print_log(LOG_ERR, "%s: %lu:%.256s:%.256s:%d", __FILE__, + es, ERR_error_string(l, NULL), file, line); + } +} + +/* tls_rand_seed: + * seeds the random number generator with some *HOPEFULLY* semi-random + * information. + * + * the idea is this, on busy systems, timestamps aren't going to change + * that often, but *hopefully* rusage will. on non-busy systems the + * timestamps *should* move more. *shrug* we could implement a random + * file read thingy, i just wasn't convinced it was necessary. on systems + * with /dev/urandom, i'm not sure this code has any use. + */ +void tls_rand_seed(void) { + struct { + struct timeval tv; + pid_t pid; + pid_t ppid; + struct rusage ru; + } randseed; + +#ifdef GETTIMEOFDAY_TZ + gettimeofday(&randseed.tv, NULL); +#else + gettimeofday(&randseed.tv); +#endif + randseed.pid = getpid(); + randseed.ppid = getppid(); + getrusage(RUSAGE_SELF, &randseed.ru); + + if (tls_verbose) + print_log(LOG_INFO, "%s: Adding %d bytes of pseudo random data", + __FILE__, sizeof(randseed)); + + RAND_add(&randseed, sizeof(randseed), 0.5); +} + +/* tls_info_callback: + * Dump information related to the SSL/TLS connection when OpenSSL + * call this function. + */ +void tls_info_callback(SSL *s, int where, int ret) { + char *str; + int w = (where & (~SSL_ST_MASK)); + + if (w & SSL_ST_CONNECT) + str = "SSL_connect"; + else if (w & SSL_ST_ACCEPT) + str = "SSL_accept"; + else + str = "undefined"; + if (where & SSL_CB_LOOP) { + if (tls_verbose) + print_log(LOG_ERR, "%s: %.20s: %.512s", __FILE__, str, + SSL_state_string_long(s)); + } else if (where & SSL_CB_ALERT) { + str = ((where & SSL_CB_READ) ? "read" : "write"); + if ((tls_verbose) || ((ret & 0xff) != + SSL3_AD_CLOSE_NOTIFY)) + print_log(LOG_ERR, "%s: SSL3 alert: %.20s: %.512s %.512s", + __FILE__, str, SSL_alert_type_string_long(ret), + SSL_alert_desc_string_long(ret)); + } else if (where & SSL_CB_EXIT) { + if (ret == 0) + print_log(LOG_ERR, "%s: %.20s: failed in %.512s", + __FILE__, str, SSL_state_string_long(s)); + else if (ret < 0) + print_log(LOG_ERR, "%s: %.20s: error in %.512s", + __FILE__, str, SSL_state_string_long(s)); + } +} + +/* tls_set_cert_file: + * sets the certificate and key file to what is specified in the + * config file. + */ +int tls_set_cert_file() { + item *I; + + I = stringmap_find(config, "tls-certificate-file"); + if (I == NULL) { + print_log(LOG_ERR, "%s: certificate file not set", __FILE__); + tls_print_errors(); + return 0; + } + + cert_file = (char *) xmalloc(sizeof(char) * I->l); + strncpy(cert_file, I->v, I->l); + + I = stringmap_find(config, "tls-privatekey-file"); + if (I == NULL) { + print_log(LOG_INFO, "%s: private key file not set, assuming " + "private key is in certificate file", __FILE__); + key_file = cert_file; + } + else { + key_file = (char *) xmalloc(sizeof(char) * I->l); + strncpy(key_file, I->v, I->l); + } + + return 1; +} + +/* tls_stop_engine: + * Stops the TLS engine. + */ +void tls_stop_engine(void) { + if (tls_ctx != NULL) + SSL_CTX_free(tls_ctx); + tls_ctx = NULL; + + if (cert_file != key_file) xfree(key_file); + xfree(cert_file); +} + +/* tls_init_engine: + * Initialize the engine. This should only be run once instance + * of tpop3d. + */ +int tls_init_engine(void) { + SSL_load_error_strings(); + SSL_library_init(); + if ((tls_ctx = SSL_CTX_new(SSLv23_server_method())) == NULL) { + print_log(LOG_ERR, "%s: SSL_CTX_new failed", __FILE__); + tls_print_errors(); + return 0; + } + SSL_CTX_set_options(tls_ctx, SSL_OP_ALL); + SSL_CTX_set_info_callback(tls_ctx, tls_info_callback); + SSL_CTX_sess_set_cache_size(tls_ctx, 1); + + if (!tls_set_cert_file()) { + return 0; + } + + return 1; +} + +/* tls_stop_servertls: + * Close the SSL/TLS connection and free up some resources. + */ +void tls_stop_servertls(connection c) { + if (c->tls_connection != NULL) + SSL_free(c->tls_connection); + c->tls_connection = NULL; +} + +/* tls_start_servertls: + * Start the server's SSL/TLS connection. + */ +int tls_start_servertls(connection c) { + + tls_rand_seed(); + if (RAND_status() != 1) { + print_log(LOG_ERR, "%s: insufficient random seeding", __FILE__); + tls_print_errors(); + return 0; + } + + if (SSL_CTX_use_certificate_file(tls_ctx, cert_file, + SSL_FILETYPE_PEM) < 0) { + print_log(LOG_ERR, "%s: can't load certificate file: %s", + __FILE__, cert_file); + tls_print_errors(); + return 0; + } + + if (SSL_CTX_use_PrivateKey_file(tls_ctx, key_file, + SSL_FILETYPE_PEM) < 0) { + print_log(LOG_ERR, "%s: can't load certificate file: %s", + __FILE__, cert_file); + tls_print_errors(); + return 0; + } + + if (!SSL_CTX_check_private_key(tls_ctx)) { + print_log(LOG_ERR, "%s: can't verify private key", __FILE__); + tls_print_errors(); + return 0; + } + + c->tls_connection = SSL_new(tls_ctx); + if (c->tls_connection == NULL) { + print_log(LOG_ERR, "%s: can't create TLS connection", __FILE__); + tls_print_errors(); + return 0; + } + + if (SSL_set_fd(c->tls_connection, c->s) == 0) { + print_log(LOG_ERR, "%s: can't set socket for TLS conncetion", + __FILE__); + tls_print_errors(); + return 0; + } + + + return 1; +} + +/* tls_handshake: + * Do the SSL/TLS handshake with the client. + */ +int tls_handshake(connection c) { + int ret; + + if ((ret = SSL_accept(c->tls_connection)) <= 0) { + print_log(LOG_ERR, "%s: failed to accept TLS connection: %d", + __FILE__, ret); + tls_print_errors(); + tls_stop_servertls(c); + return 0; + } + + if (tls_verbose) { + SSL_CIPHER *cipher; + + cipher = SSL_get_current_cipher(c->tls_connection); + if (cipher != NULL) { + const char *cipher_name = SSL_CIPHER_get_name(cipher); + int cipher_bits; + + print_log(LOG_INFO, "%s: TLS established with %s (%dbits)", + __FILE__, cipher_name, + SSL_CIPHER_get_bits(cipher, &cipher_bits)); + } + } + + return 1; +} + +/* tls_write_file: + * same code that is in write_file in util.c, except instead + * of a socket, it expects a pointer to the SSL connection. + */ +int tls_write_file(int fd, SSL *s, size_t msgoffset, size_t skip, size_t msglength, int n) { + char *filemem; + char *p, *q, *r; + size_t length, offset; + + offset = msgoffset - (msgoffset % PAGESIZE); + length = (msgoffset + msglength + PAGESIZE) ; + length -= length % PAGESIZE; + + filemem = mmap(0, length, PROT_READ, MAP_PRIVATE, fd, offset); + if (filemem == MAP_FAILED) { + print_log(LOG_ERR, "write_file: mmap: %m"); + return 0; + } + + /* Find the beginning of the message headers */ + p = filemem + (msgoffset % PAGESIZE); + r = p + msglength; + p += skip; + + /* Send the message headers */ + do { + q = memchr(p, '\n', r - p); + if (!q) q = r; + errno = 0; + /* Escape a leading ., if present. */ + if (*p == '.' && !tls_try_write(s, ".", 1)) goto write_failure; + /* Send line itself. */ + if (!tls_try_write(s, p, q - p) || !tls_try_write(s, "\r\n", 2)) + goto write_failure; + p = q + 1; + } while (p < r && *p != '\n'); + + ++p; + + errno = 0; + if (!tls_try_write(s, "\r\n", 2)) { + print_log(LOG_ERR, "write_file: write: %m"); + munmap(filemem, length); + return 0; + } + + /* Now send the message itself */ + while (p < r && n) { + if (n > 0) --n; + + q = memchr(p, '\n', r - p); + if (!q) q = r; + errno = 0; + + /* Escape a leading ., if present. */ + if (*p == '.' && !tls_try_write(s, ".", 1)) goto write_failure; + /* Send line itself. */ + if (!tls_try_write(s, p, q - p) || !tls_try_write(s, "\r\n", 2)) + goto write_failure; + + p = q + 1; + } + if (munmap(filemem, length) == -1) + print_log(LOG_ERR, "write_file: munmap: %m"); + + errno = 0; + if (!tls_try_write(s, ".\r\n", 3)) { + print_log(LOG_ERR, "write_file: write: %m"); + return 0; + } else return 1; + +write_failure: + print_log(LOG_ERR, "write_file: write: %m"); + munmap(filemem, length); + return 0; +} + +#endif diff -u --new-file tpop3d-1.3.5.orig/tptls.h tpop3d-1.3.5/tptls.h --- tpop3d-1.3.5.orig/tptls.h Wed Dec 31 17:00:00 1969 +++ tpop3d-1.3.5/tptls.h Fri Nov 2 10:37:12 2001 @@ -0,0 +1,21 @@ +#ifdef USE_OPENSSL_TLS + +#ifndef __TPTLS_H_ /* include guard */ +#define __TPTLS_H_ + +#include "connection.h" + +#define tls_try_write(a, b, c) (SSL_write((a), (b), (c)) == (c)) + +int tls_init_engine(void); +int tls_start_servertls(connection c); +int tls_handshake(connection c); + +int tls_write_file(int fd, SSL *s, size_t msgoffset, size_t skip, size_t msglength, int n); + +void tls_stop_servertls(connection c); +void tls_stop_engine(void); + +#endif /* __TPTLS_H_ */ + +#endif /* USE_OPENSSL_TLS */