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
tlsp_state_create(const char * service,VSTREAM * plaintext_stream)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
tlsp_state_free(TLSP_STATE * state)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