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 105 TLSP_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 131 void 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