1/* $NetBSD: tlsproxy_state.c,v 1.3 2020/03/18 19:05:21 christos Exp $ */ 2 3/*++ 4/* NAME 5/* tlsproxy_state 3 6/* SUMMARY 7/* Postfix SMTP server 8/* SYNOPSIS 9/* #include <tlsproxy.h> 10/* 11/* TLSP_STATE *tlsp_state_create(service, plaintext_stream) 12/* const char *service; 13/* VSTREAM *plaintext_stream; 14/* 15/* void tlsp_state_free(state) 16/* TLSP_STATE *state; 17/* DESCRIPTION 18/* This module provides TLSP_STATE constructor and destructor 19/* routines. 20/* 21/* tlsp_state_create() initializes session context. 22/* 23/* tlsp_state_free() destroys session context. If the handshake 24/* was in progress, it logs a 'handshake failed' message. 25/* 26/* Arguments: 27/* .IP service 28/* The service name for the TLS library. This argument is copied. 29/* The destructor will automatically destroy the string. 30/* .IP plaintext_stream 31/* The VSTREAM between postscreen(8) and tlsproxy(8). 32/* The destructor will automatically close the stream. 33/* .PP 34/* Other structure members are set by the application. The 35/* text below describes how the TLSP_STATE destructor 36/* disposes of them. 37/* .IP plaintext_buf 38/* NBBIO for plaintext I/O. 39/* The destructor will automatically turn off read/write/timeout 40/* events and destroy the NBBIO. 41/* .IP ciphertext_fd 42/* The file handle for the remote SMTP client socket. 43/* The destructor will automatically turn off read/write events 44/* and close the file handle. 45/* .IP ciphertext_timer 46/* The destructor will automatically turn off this time event. 47/* .IP timeout 48/* Time limit for plaintext and ciphertext I/O. 49/* .IP remote_endpt 50/* Printable remote endpoint name. 51/* The destructor will automatically destroy the string. 52/* .IP server_id 53/* TLS session cache identifier. 54/* The destructor will automatically destroy the string. 55/* DIAGNOSTICS 56/* All errors are fatal. 57/* LICENSE 58/* .ad 59/* .fi 60/* The Secure Mailer license must be distributed with this software. 61/* AUTHOR(S) 62/* Wietse Venema 63/* IBM T.J. Watson Research 64/* P.O. Box 704 65/* Yorktown Heights, NY 10598, USA 66/* 67/* Wietse Venema 68/* Google, Inc. 69/* 111 8th Avenue 70/* New York, NY 10011, USA 71/*--*/ 72 73 /* 74 * System library. 75 */ 76#include <sys_defs.h> 77 78 /* 79 * Utility library. 80 */ 81#include <msg.h> 82#include <mymalloc.h> 83#include <nbbio.h> 84 85 /* 86 * Master library. 87 */ 88#include <mail_server.h> 89 90 /* 91 * TLS library. 92 */ 93#ifdef USE_TLS 94#define TLS_INTERNAL /* XXX */ 95#include <tls.h> 96#include <tls_proxy.h> 97 98 /* 99 * Application-specific. 100 */ 101#include <tlsproxy.h> 102 103/* tlsp_state_create - create TLS proxy state object */ 104 105TLSP_STATE *tlsp_state_create(const char *service, 106 VSTREAM *plaintext_stream) 107{ 108 TLSP_STATE *state = (TLSP_STATE *) mymalloc(sizeof(*state)); 109 110 state->flags = TLSP_FLAG_DO_HANDSHAKE; 111 state->service = mystrdup(service); 112 state->plaintext_stream = plaintext_stream; 113 state->plaintext_buf = 0; 114 state->ciphertext_fd = -1; 115 state->ciphertext_timer = 0; 116 state->timeout = -1; 117 state->remote_endpt = 0; 118 state->server_id = 0; 119 state->tls_context = 0; 120 state->tls_params = 0; 121 state->server_init_props = 0; 122 state->server_start_props = 0; 123 state->client_init_props = 0; 124 state->client_start_props = 0; 125 126 return (state); 127} 128 129/* tlsp_state_free - destroy state objects, connection and events */ 130 131void tlsp_state_free(TLSP_STATE *state) 132{ 133 /* Don't log failure after plaintext EOF. */ 134 if (state->remote_endpt && state->server_id 135 && (state->flags & TLSP_FLAG_DO_HANDSHAKE)) 136 msg_info("TLS handshake failed for service=%s peer=%s", 137 state->server_id, state->remote_endpt); 138 myfree(state->service); 139 if (state->plaintext_buf) /* turns off plaintext events */ 140 nbbio_free(state->plaintext_buf); 141 else 142 event_disable_readwrite(vstream_fileno(state->plaintext_stream)); 143 event_server_disconnect(state->plaintext_stream); 144 if (state->ciphertext_fd >= 0) { 145 event_disable_readwrite(state->ciphertext_fd); 146 (void) close(state->ciphertext_fd); 147 } 148 if (state->ciphertext_timer) 149 event_cancel_timer(state->ciphertext_timer, (void *) state); 150 if (state->remote_endpt) { 151 msg_info("DISCONNECT %s", state->remote_endpt); 152 myfree(state->remote_endpt); 153 } 154 if (state->server_id) 155 myfree(state->server_id); 156 if (state->tls_context) 157 tls_free_context(state->tls_context); 158 if (state->tls_params) 159 tls_proxy_client_param_free(state->tls_params); 160 if (state->server_init_props) 161 tls_proxy_server_init_free(state->server_init_props); 162 if (state->server_start_props) 163 tls_proxy_server_start_free(state->server_start_props); 164 if (state->client_init_props) 165 tls_proxy_client_init_free(state->client_init_props); 166 if (state->client_start_props) 167 tls_proxy_client_start_free(state->client_start_props); 168 myfree((void *) state); 169} 170 171#endif 172