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