xref: /netbsd-src/external/ibm-public/postfix/dist/src/tls/tls_proxy_client_print.c (revision 82d56013d7b633d116a93943de88e08335357a7c)
1 /*	$NetBSD: tls_proxy_client_print.c,v 1.2 2020/03/18 19:05:21 christos Exp $	*/
2 
3 /*++
4 /* NAME
5 /*	tls_proxy_client_print 3
6 /* SUMMARY
7 /*	write TLS_CLIENT_XXX structures to stream
8 /* SYNOPSIS
9 /*	#include <tls_proxy.h>
10 /*
11 /*	int	tls_proxy_client_param_print(print_fn, stream, flags, ptr)
12 /*	ATTR_PRINT_MASTER_FN print_fn;
13 /*	VSTREAM	*stream;
14 /*	int	flags;
15 /*	void	*ptr;
16 /*
17 /*	int	tls_proxy_client_init_print(print_fn, stream, flags, ptr)
18 /*	ATTR_PRINT_MASTER_FN print_fn;
19 /*	VSTREAM	*stream;
20 /*	int	flags;
21 /*	void	*ptr;
22 /*
23 /*	int	tls_proxy_client_start_print(print_fn, stream, flags, ptr)
24 /*	ATTR_PRINT_MASTER_FN print_fn;
25 /*	VSTREAM	*stream;
26 /*	int	flags;
27 /*	void	*ptr;
28 /* DESCRIPTION
29 /*	tls_proxy_client_param_print() writes a TLS_CLIENT_PARAMS structure to
30 /*	the named stream using the specified attribute print routine.
31 /*	tls_proxy_client_param_print() is meant to be passed as a call-back to
32 /*	attr_print(), thusly:
33 /*
34 /*	SEND_ATTR_FUNC(tls_proxy_client_param_print, (void *) param), ...
35 /*
36 /*	tls_proxy_client_init_print() writes a full TLS_CLIENT_INIT_PROPS
37 /*	structure to the named stream using the specified attribute
38 /*	print routine. tls_proxy_client_init_print() is meant to
39 /*	be passed as a call-back to attr_print(), thusly:
40 /*
41 /*	SEND_ATTR_FUNC(tls_proxy_client_init_print, (void *) init_props), ...
42 /*
43 /*	tls_proxy_client_start_print() writes a TLS_CLIENT_START_PROPS
44 /*	structure, without stream or file descriptor members, to
45 /*	the named stream using the specified attribute print routine.
46 /*	tls_proxy_client_start_print() is meant to be passed as a
47 /*	call-back to attr_print(), thusly:
48 /*
49 /*	SEND_ATTR_FUNC(tls_proxy_client_start_print, (void *) start_props), ...
50 /* DIAGNOSTICS
51 /*	Fatal: out of memory.
52 /* LICENSE
53 /* .ad
54 /* .fi
55 /*	The Secure Mailer license must be distributed with this software.
56 /* AUTHOR(S)
57 /*	Wietse Venema
58 /*	Google, Inc.
59 /*	111 8th Avenue
60 /*	New York, NY 10011, USA
61 /*--*/
62 
63 #ifdef USE_TLS
64 
65 /* System library. */
66 
67 #include <sys_defs.h>
68 
69 /* Utility library */
70 
71 #include <argv_attr.h>
72 #include <attr.h>
73 #include <msg.h>
74 
75 /* Global library. */
76 
77 #include <mail_params.h>
78 
79 /* TLS library. */
80 
81 #include <tls.h>
82 #include <tls_proxy.h>
83 
84 
85 #define STR(x) vstring_str(x)
86 #define LEN(x) VSTRING_LEN(x)
87 
88 /* tls_proxy_client_param_print - send TLS_CLIENT_PARAMS over stream */
89 
90 int     tls_proxy_client_param_print(ATTR_PRINT_MASTER_FN print_fn, VSTREAM *fp,
91 				             int flags, void *ptr)
92 {
93     TLS_CLIENT_PARAMS *params = (TLS_CLIENT_PARAMS *) ptr;
94     int     ret;
95 
96     if (msg_verbose)
97 	msg_info("begin tls_proxy_client_param_print");
98 
99     ret = print_fn(fp, flags | ATTR_FLAG_MORE,
100 		   SEND_ATTR_STR(VAR_TLS_HIGH_CLIST, params->tls_high_clist),
101 		   SEND_ATTR_STR(VAR_TLS_MEDIUM_CLIST,
102 				 params->tls_medium_clist),
103 		   SEND_ATTR_STR(VAR_TLS_LOW_CLIST, params->tls_low_clist),
104 		   SEND_ATTR_STR(VAR_TLS_EXPORT_CLIST,
105 				 params->tls_export_clist),
106 		   SEND_ATTR_STR(VAR_TLS_NULL_CLIST, params->tls_null_clist),
107 		   SEND_ATTR_STR(VAR_TLS_EECDH_AUTO, params->tls_eecdh_auto),
108 		   SEND_ATTR_STR(VAR_TLS_EECDH_STRONG,
109 				 params->tls_eecdh_strong),
110 		   SEND_ATTR_STR(VAR_TLS_EECDH_ULTRA,
111 				 params->tls_eecdh_ultra),
112 		   SEND_ATTR_STR(VAR_TLS_BUG_TWEAKS, params->tls_bug_tweaks),
113 		   SEND_ATTR_STR(VAR_TLS_SSL_OPTIONS,
114 				 params->tls_ssl_options),
115 		   SEND_ATTR_STR(VAR_TLS_DANE_DIGESTS,
116 				 params->tls_dane_digests),
117 		   SEND_ATTR_STR(VAR_TLS_MGR_SERVICE,
118 				 params->tls_mgr_service),
119 		   SEND_ATTR_STR(VAR_TLS_TKT_CIPHER, params->tls_tkt_cipher),
120 		   SEND_ATTR_INT(VAR_TLS_DAEMON_RAND_BYTES,
121 				 params->tls_daemon_rand_bytes),
122 		   SEND_ATTR_INT(VAR_TLS_APPEND_DEF_CA,
123 				 params->tls_append_def_CA),
124 		   SEND_ATTR_INT(VAR_TLS_BC_PKEY_FPRINT,
125 				 params->tls_bc_pkey_fprint),
126 		   SEND_ATTR_INT(VAR_TLS_PREEMPT_CLIST,
127 				 params->tls_preempt_clist),
128 		   SEND_ATTR_INT(VAR_TLS_MULTI_WILDCARD,
129 				 params->tls_multi_wildcard),
130 		   ATTR_TYPE_END);
131     /* Do not flush the stream. */
132     if (msg_verbose)
133 	msg_info("tls_proxy_client_param_print ret=%d", ret);
134     return (ret);
135 }
136 
137 /* tls_proxy_client_init_print - send TLS_CLIENT_INIT_PROPS over stream */
138 
139 int     tls_proxy_client_init_print(ATTR_PRINT_MASTER_FN print_fn, VSTREAM *fp,
140 				            int flags, void *ptr)
141 {
142     TLS_CLIENT_INIT_PROPS *props = (TLS_CLIENT_INIT_PROPS *) ptr;
143     int     ret;
144 
145     if (msg_verbose)
146 	msg_info("begin tls_proxy_client_init_print");
147 
148 #define STRING_OR_EMPTY(s) ((s) ? (s) : "")
149 
150     ret = print_fn(fp, flags | ATTR_FLAG_MORE,
151 		   SEND_ATTR_STR(TLS_ATTR_LOG_PARAM,
152 				 STRING_OR_EMPTY(props->log_param)),
153 		   SEND_ATTR_STR(TLS_ATTR_LOG_LEVEL,
154 				 STRING_OR_EMPTY(props->log_level)),
155 		   SEND_ATTR_INT(TLS_ATTR_VERIFYDEPTH, props->verifydepth),
156 		   SEND_ATTR_STR(TLS_ATTR_CACHE_TYPE,
157 				 STRING_OR_EMPTY(props->cache_type)),
158 		   SEND_ATTR_STR(TLS_ATTR_CHAIN_FILES,
159 				 STRING_OR_EMPTY(props->chain_files)),
160 		   SEND_ATTR_STR(TLS_ATTR_CERT_FILE,
161 				 STRING_OR_EMPTY(props->cert_file)),
162 		   SEND_ATTR_STR(TLS_ATTR_KEY_FILE,
163 				 STRING_OR_EMPTY(props->key_file)),
164 		   SEND_ATTR_STR(TLS_ATTR_DCERT_FILE,
165 				 STRING_OR_EMPTY(props->dcert_file)),
166 		   SEND_ATTR_STR(TLS_ATTR_DKEY_FILE,
167 				 STRING_OR_EMPTY(props->dkey_file)),
168 		   SEND_ATTR_STR(TLS_ATTR_ECCERT_FILE,
169 				 STRING_OR_EMPTY(props->eccert_file)),
170 		   SEND_ATTR_STR(TLS_ATTR_ECKEY_FILE,
171 				 STRING_OR_EMPTY(props->eckey_file)),
172 		   SEND_ATTR_STR(TLS_ATTR_CAFILE,
173 				 STRING_OR_EMPTY(props->CAfile)),
174 		   SEND_ATTR_STR(TLS_ATTR_CAPATH,
175 				 STRING_OR_EMPTY(props->CApath)),
176 		   SEND_ATTR_STR(TLS_ATTR_MDALG,
177 				 STRING_OR_EMPTY(props->mdalg)),
178 		   ATTR_TYPE_END);
179     /* Do not flush the stream. */
180     if (msg_verbose)
181 	msg_info("tls_proxy_client_init_print ret=%d", ret);
182     return (ret);
183 }
184 
185 /* tls_proxy_client_certs_print - send x509 certificates over stream */
186 
187 static int tls_proxy_client_certs_print(ATTR_PRINT_MASTER_FN print_fn,
188 				          VSTREAM *fp, int flags, void *ptr)
189 {
190     TLS_CERTS *tls_certs = (TLS_CERTS *) ptr;
191     TLS_CERTS *tp;
192     int     count;
193     int     ret;
194 
195     for (tp = tls_certs, count = 0; tp != 0; tp = tp->next, count++)
196 	 /* void */ ;
197     if (msg_verbose)
198 	msg_info("tls_proxy_client_certs_print count=%d", count);
199 
200     ret = print_fn(fp, flags | ATTR_FLAG_MORE,
201 		   SEND_ATTR_INT(TLS_ATTR_COUNT, count),
202 		   ATTR_TYPE_END);
203 
204     if (ret == 0 && count > 0) {
205 	VSTRING *buf = vstring_alloc(100);
206 	int     n;
207 
208 	for (tp = tls_certs, n = 0; ret == 0 && n < count; tp = tp->next, n++) {
209 	    size_t  len = i2d_X509(tp->cert, (unsigned char **) 0);
210 	    unsigned char *bp;
211 
212 	    VSTRING_RESET(buf);
213 	    VSTRING_SPACE(buf, len);
214 	    bp = (unsigned char *) STR(buf);
215 	    i2d_X509(tp->cert, &bp);
216 	    if ((char *) bp - STR(buf) != len)
217 		msg_panic("i2d_X509 failed to encode certificate");
218 	    ret = print_fn(fp, flags | ATTR_FLAG_MORE,
219 			   SEND_ATTR_DATA(TLS_ATTR_CERT, LEN(buf), STR(buf)),
220 			   ATTR_TYPE_END);
221 	}
222 	vstring_free(buf);
223     }
224     /* Do not flush the stream. */
225     if (msg_verbose)
226 	msg_info("tls_proxy_client_certs_print ret=%d", count);
227     return (ret);
228 }
229 
230 /* tls_proxy_client_pkeys_print - send public keys over stream */
231 
232 static int tls_proxy_client_pkeys_print(ATTR_PRINT_MASTER_FN print_fn,
233 				          VSTREAM *fp, int flags, void *ptr)
234 {
235     TLS_PKEYS *tls_pkeys = (TLS_PKEYS *) ptr;
236     TLS_PKEYS *tp;
237     int     count;
238     int     ret;
239 
240     for (tp = tls_pkeys, count = 0; tp != 0; tp = tp->next, count++)
241 	 /* void */ ;
242     if (msg_verbose)
243 	msg_info("tls_proxy_client_pkeys_print count=%d", count);
244 
245     ret = print_fn(fp, flags | ATTR_FLAG_MORE,
246 		   SEND_ATTR_INT(TLS_ATTR_COUNT, count),
247 		   ATTR_TYPE_END);
248 
249     if (ret == 0 && count > 0) {
250 	VSTRING *buf = vstring_alloc(100);
251 	int     n;
252 
253 	for (tp = tls_pkeys, n = 0; ret == 0 && n < count; tp = tp->next, n++) {
254 	    size_t  len = i2d_PUBKEY(tp->pkey, (unsigned char **) 0);
255 	    unsigned char *bp;
256 
257 	    VSTRING_RESET(buf);
258 	    VSTRING_SPACE(buf, len);
259 	    bp = (unsigned char *) STR(buf);
260 	    i2d_PUBKEY(tp->pkey, &bp);
261 	    if ((char *) bp - STR(buf) != len)
262 		msg_panic("i2d_PUBKEY failed to encode public key");
263 	    ret = print_fn(fp, flags | ATTR_FLAG_MORE,
264 			   SEND_ATTR_DATA(TLS_ATTR_PKEY, LEN(buf), STR(buf)),
265 			   ATTR_TYPE_END);
266 	}
267 	vstring_free(buf);
268     }
269     /* Do not flush the stream. */
270     if (msg_verbose)
271 	msg_info("tls_proxy_client_pkeys_print ret=%d", count);
272     return (ret);
273 }
274 
275 /* tls_proxy_client_tlsa_print - send TLS_TLSA over stream */
276 
277 static int tls_proxy_client_tlsa_print(ATTR_PRINT_MASTER_FN print_fn,
278 				          VSTREAM *fp, int flags, void *ptr)
279 {
280     TLS_TLSA *tls_tlsa = (TLS_TLSA *) ptr;
281     TLS_TLSA *tp;
282     int     count;
283     int     ret;
284 
285     for (tp = tls_tlsa, count = 0; tp != 0; tp = tp->next, count++)
286 	 /* void */ ;
287     if (msg_verbose)
288 	msg_info("tls_proxy_client_tlsa_print count=%d", count);
289 
290     ret = print_fn(fp, flags | ATTR_FLAG_MORE,
291 		   SEND_ATTR_INT(TLS_ATTR_COUNT, count),
292 		   ATTR_TYPE_END);
293 
294     if (ret == 0 && count > 0) {
295 	int     n;
296 
297 	for (tp = tls_tlsa, n = 0; ret == 0 && n < count; tp = tp->next, n++) {
298 	    ret = print_fn(fp, flags | ATTR_FLAG_MORE,
299 			   SEND_ATTR_STR(TLS_ATTR_MDALG, tp->mdalg),
300 			   SEND_ATTR_FUNC(argv_attr_print,
301 					  (void *) tp->certs),
302 			   SEND_ATTR_FUNC(argv_attr_print,
303 					  (void *) tp->pkeys),
304 			   ATTR_TYPE_END);
305 	}
306     }
307     /* Do not flush the stream. */
308     if (msg_verbose)
309 	msg_info("tls_proxy_client_tlsa_print ret=%d", count);
310     return (ret);
311 }
312 
313 /* tls_proxy_client_dane_print - send TLS_DANE over stream */
314 
315 static int tls_proxy_client_dane_print(ATTR_PRINT_MASTER_FN print_fn,
316 				          VSTREAM *fp, int flags, void *ptr)
317 {
318     TLS_DANE *dane = (TLS_DANE *) ptr;
319     int     ret;
320 
321     ret = print_fn(fp, flags | ATTR_FLAG_MORE,
322 		   SEND_ATTR_INT(TLS_ATTR_DANE, dane != 0),
323 		   ATTR_TYPE_END);
324     if (msg_verbose)
325 	msg_info("tls_proxy_client_dane_print dane=%d", dane != 0);
326 
327     if (ret == 0 && dane != 0) {
328 	ret = print_fn(fp, flags | ATTR_FLAG_MORE,
329 		       SEND_ATTR_FUNC(tls_proxy_client_tlsa_print,
330 				      (void *) dane->ta),
331 		       SEND_ATTR_FUNC(tls_proxy_client_tlsa_print,
332 				      (void *) dane->ee),
333 		       SEND_ATTR_FUNC(tls_proxy_client_certs_print,
334 				      (void *) dane->certs),
335 		       SEND_ATTR_FUNC(tls_proxy_client_pkeys_print,
336 				      (void *) dane->pkeys),
337 		       SEND_ATTR_STR(TLS_ATTR_DOMAIN,
338 				     STRING_OR_EMPTY(dane->base_domain)),
339 		       SEND_ATTR_INT(TLS_ATTR_FLAGS, dane->flags),
340 		       SEND_ATTR_LONG(TLS_ATTR_EXP, dane->expires),
341 		       ATTR_TYPE_END);
342     }
343     /* Do not flush the stream. */
344     if (msg_verbose)
345 	msg_info("tls_proxy_client_dane_print ret=%d", ret);
346     return (ret);
347 }
348 
349 /* tls_proxy_client_start_print - send TLS_CLIENT_START_PROPS over stream */
350 
351 int     tls_proxy_client_start_print(ATTR_PRINT_MASTER_FN print_fn,
352 				          VSTREAM *fp, int flags, void *ptr)
353 {
354     TLS_CLIENT_START_PROPS *props = (TLS_CLIENT_START_PROPS *) ptr;
355     int     ret;
356 
357     if (msg_verbose)
358 	msg_info("begin tls_proxy_client_start_print");
359 
360 #define STRING_OR_EMPTY(s) ((s) ? (s) : "")
361 
362     ret = print_fn(fp, flags | ATTR_FLAG_MORE,
363 		   SEND_ATTR_INT(TLS_ATTR_TIMEOUT, props->timeout),
364 		   SEND_ATTR_INT(TLS_ATTR_TLS_LEVEL, props->tls_level),
365 		   SEND_ATTR_STR(TLS_ATTR_NEXTHOP,
366 				 STRING_OR_EMPTY(props->nexthop)),
367 		   SEND_ATTR_STR(TLS_ATTR_HOST,
368 				 STRING_OR_EMPTY(props->host)),
369 		   SEND_ATTR_STR(TLS_ATTR_NAMADDR,
370 				 STRING_OR_EMPTY(props->namaddr)),
371 		   SEND_ATTR_STR(TLS_ATTR_SNI,
372 				 STRING_OR_EMPTY(props->sni)),
373 		   SEND_ATTR_STR(TLS_ATTR_SERVERID,
374 				 STRING_OR_EMPTY(props->serverid)),
375 		   SEND_ATTR_STR(TLS_ATTR_HELO,
376 				 STRING_OR_EMPTY(props->helo)),
377 		   SEND_ATTR_STR(TLS_ATTR_PROTOCOLS,
378 				 STRING_OR_EMPTY(props->protocols)),
379 		   SEND_ATTR_STR(TLS_ATTR_CIPHER_GRADE,
380 				 STRING_OR_EMPTY(props->cipher_grade)),
381 		   SEND_ATTR_STR(TLS_ATTR_CIPHER_EXCLUSIONS,
382 				 STRING_OR_EMPTY(props->cipher_exclusions)),
383 		   SEND_ATTR_FUNC(argv_attr_print,
384 				  (void *) props->matchargv),
385 		   SEND_ATTR_STR(TLS_ATTR_MDALG,
386 				 STRING_OR_EMPTY(props->mdalg)),
387 		   SEND_ATTR_FUNC(tls_proxy_client_dane_print,
388 				  (void *) props->dane),
389 		   ATTR_TYPE_END);
390     /* Do not flush the stream. */
391     if (msg_verbose)
392 	msg_info("tls_proxy_client_start_print ret=%d", ret);
393     return (ret);
394 }
395 
396 #endif
397