1 /*	$NetBSD: tls_proxy_client_print.c,v 1.3 2022/10/08 16:12:50 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_COMMON_FN print_fn;
13 /*	VSTREAM	*stream;
14 /*	int	flags;
15 /*	const void *ptr;
16 /*
17 /*	int	tls_proxy_client_init_print(print_fn, stream, flags, ptr)
18 /*	ATTR_PRINT_COMMON_FN print_fn;
19 /*	VSTREAM	*stream;
20 /*	int	flags;
21 /*	const void *ptr;
22 /*
23 /*	int	tls_proxy_client_start_print(print_fn, stream, flags, ptr)
24 /*	ATTR_PRINT_COMMON_FN print_fn;
25 /*	VSTREAM	*stream;
26 /*	int	flags;
27 /*	const 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, (const 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, (const 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, (const 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 
tls_proxy_client_param_print(ATTR_PRINT_COMMON_FN print_fn,VSTREAM * fp,int flags,const void * ptr)90 int     tls_proxy_client_param_print(ATTR_PRINT_COMMON_FN print_fn, VSTREAM *fp,
91 				             int flags, const void *ptr)
92 {
93     const TLS_CLIENT_PARAMS *params = (const 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 
tls_proxy_client_init_print(ATTR_PRINT_COMMON_FN print_fn,VSTREAM * fp,int flags,const void * ptr)139 int     tls_proxy_client_init_print(ATTR_PRINT_COMMON_FN print_fn, VSTREAM *fp,
140 				            int flags, const void *ptr)
141 {
142     const TLS_CLIENT_INIT_PROPS *props = (const 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_tlsa_print - send TLS_TLSA over stream */
186 
tls_proxy_client_tlsa_print(ATTR_PRINT_COMMON_FN print_fn,VSTREAM * fp,int flags,const void * ptr)187 static int tls_proxy_client_tlsa_print(ATTR_PRINT_COMMON_FN print_fn,
188 			            VSTREAM *fp, int flags, const void *ptr)
189 {
190     const TLS_TLSA *head = (const TLS_TLSA *) ptr;
191     const TLS_TLSA *tp;
192     int     count;
193     int     ret;
194 
195     for (tp = head, count = 0; tp != 0; tp = tp->next)
196 	++count;
197     if (msg_verbose)
198 	msg_info("tls_proxy_client_tlsa_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     for (tp = head; ret == 0 && tp != 0; tp = tp->next)
205 	ret = print_fn(fp, flags | ATTR_FLAG_MORE,
206 		       SEND_ATTR_INT(TLS_ATTR_USAGE, tp->usage),
207 		       SEND_ATTR_INT(TLS_ATTR_SELECTOR, tp->selector),
208 		       SEND_ATTR_INT(TLS_ATTR_MTYPE, tp->mtype),
209 		       SEND_ATTR_DATA(TLS_ATTR_DATA, tp->length, tp->data),
210 		       ATTR_TYPE_END);
211 
212     /* Do not flush the stream. */
213     if (msg_verbose)
214 	msg_info("tls_proxy_client_tlsa_print ret=%d", count);
215     return (ret);
216 }
217 
218 /* tls_proxy_client_dane_print - send TLS_DANE over stream */
219 
tls_proxy_client_dane_print(ATTR_PRINT_COMMON_FN print_fn,VSTREAM * fp,int flags,const void * ptr)220 static int tls_proxy_client_dane_print(ATTR_PRINT_COMMON_FN print_fn,
221 			            VSTREAM *fp, int flags, const void *ptr)
222 {
223     const TLS_DANE *dane = (const TLS_DANE *) ptr;
224     int     ret;
225 
226     ret = print_fn(fp, flags | ATTR_FLAG_MORE,
227 		   SEND_ATTR_INT(TLS_ATTR_DANE, dane != 0),
228 		   ATTR_TYPE_END);
229     if (msg_verbose)
230 	msg_info("tls_proxy_client_dane_print dane=%d", dane != 0);
231 
232     if (ret == 0 && dane != 0) {
233 	/* Send the base_domain and RRs, we don't need the other fields */
234 	ret = print_fn(fp, flags | ATTR_FLAG_MORE,
235 		       SEND_ATTR_STR(TLS_ATTR_DOMAIN,
236 				     STRING_OR_EMPTY(dane->base_domain)),
237 		       SEND_ATTR_FUNC(tls_proxy_client_tlsa_print,
238 				      (const void *) dane->tlsa),
239 		       ATTR_TYPE_END);
240     }
241     /* Do not flush the stream. */
242     if (msg_verbose)
243 	msg_info("tls_proxy_client_dane_print ret=%d", ret);
244     return (ret);
245 }
246 
247 /* tls_proxy_client_start_print - send TLS_CLIENT_START_PROPS over stream */
248 
tls_proxy_client_start_print(ATTR_PRINT_COMMON_FN print_fn,VSTREAM * fp,int flags,const void * ptr)249 int     tls_proxy_client_start_print(ATTR_PRINT_COMMON_FN print_fn,
250 			            VSTREAM *fp, int flags, const void *ptr)
251 {
252     const TLS_CLIENT_START_PROPS *props = (const TLS_CLIENT_START_PROPS *) ptr;
253     int     ret;
254 
255     if (msg_verbose)
256 	msg_info("begin tls_proxy_client_start_print");
257 
258 #define STRING_OR_EMPTY(s) ((s) ? (s) : "")
259 
260     ret = print_fn(fp, flags | ATTR_FLAG_MORE,
261 		   SEND_ATTR_INT(TLS_ATTR_TIMEOUT, props->timeout),
262 		   SEND_ATTR_INT(TLS_ATTR_TLS_LEVEL, props->tls_level),
263 		   SEND_ATTR_STR(TLS_ATTR_NEXTHOP,
264 				 STRING_OR_EMPTY(props->nexthop)),
265 		   SEND_ATTR_STR(TLS_ATTR_HOST,
266 				 STRING_OR_EMPTY(props->host)),
267 		   SEND_ATTR_STR(TLS_ATTR_NAMADDR,
268 				 STRING_OR_EMPTY(props->namaddr)),
269 		   SEND_ATTR_STR(TLS_ATTR_SNI,
270 				 STRING_OR_EMPTY(props->sni)),
271 		   SEND_ATTR_STR(TLS_ATTR_SERVERID,
272 				 STRING_OR_EMPTY(props->serverid)),
273 		   SEND_ATTR_STR(TLS_ATTR_HELO,
274 				 STRING_OR_EMPTY(props->helo)),
275 		   SEND_ATTR_STR(TLS_ATTR_PROTOCOLS,
276 				 STRING_OR_EMPTY(props->protocols)),
277 		   SEND_ATTR_STR(TLS_ATTR_CIPHER_GRADE,
278 				 STRING_OR_EMPTY(props->cipher_grade)),
279 		   SEND_ATTR_STR(TLS_ATTR_CIPHER_EXCLUSIONS,
280 				 STRING_OR_EMPTY(props->cipher_exclusions)),
281 		   SEND_ATTR_FUNC(argv_attr_print,
282 				  (const void *) props->matchargv),
283 		   SEND_ATTR_STR(TLS_ATTR_MDALG,
284 				 STRING_OR_EMPTY(props->mdalg)),
285 		   SEND_ATTR_FUNC(tls_proxy_client_dane_print,
286 				  (const void *) props->dane),
287 		   ATTR_TYPE_END);
288     /* Do not flush the stream. */
289     if (msg_verbose)
290 	msg_info("tls_proxy_client_start_print ret=%d", ret);
291     return (ret);
292 }
293 
294 #endif
295