1 /*++
2 /* NAME
3 /*	tls_proxy_client_print 3
4 /* SUMMARY
5 /*	write TLS_CLIENT_XXX structures to stream
6 /* SYNOPSIS
7 /*	#include <tls_proxy.h>
8 /*
9 /*	int	tls_proxy_client_param_print(print_fn, stream, flags, ptr)
10 /*	ATTR_PRINT_COMMON_FN print_fn;
11 /*	VSTREAM	*stream;
12 /*	int	flags;
13 /*	const void *ptr;
14 /*
15 /*	int	tls_proxy_client_init_print(print_fn, stream, flags, ptr)
16 /*	ATTR_PRINT_COMMON_FN print_fn;
17 /*	VSTREAM	*stream;
18 /*	int	flags;
19 /*	const void *ptr;
20 /*
21 /*	int	tls_proxy_client_start_print(print_fn, stream, flags, ptr)
22 /*	ATTR_PRINT_COMMON_FN print_fn;
23 /*	VSTREAM	*stream;
24 /*	int	flags;
25 /*	const void *ptr;
26 /* DESCRIPTION
27 /*	tls_proxy_client_param_print() writes a TLS_CLIENT_PARAMS structure to
28 /*	the named stream using the specified attribute print routine.
29 /*	tls_proxy_client_param_print() is meant to be passed as a call-back to
30 /*	attr_print(), thusly:
31 /*
32 /*	SEND_ATTR_FUNC(tls_proxy_client_param_print, (const void *) param), ...
33 /*
34 /*	tls_proxy_client_init_print() writes a full TLS_CLIENT_INIT_PROPS
35 /*	structure to the named stream using the specified attribute
36 /*	print routine. tls_proxy_client_init_print() is meant to
37 /*	be passed as a call-back to attr_print(), thusly:
38 /*
39 /*	SEND_ATTR_FUNC(tls_proxy_client_init_print, (const void *) init_props), ...
40 /*
41 /*	tls_proxy_client_start_print() writes a TLS_CLIENT_START_PROPS
42 /*	structure, without stream or file descriptor members, to
43 /*	the named stream using the specified attribute print routine.
44 /*	tls_proxy_client_start_print() is meant to be passed as a
45 /*	call-back to attr_print(), thusly:
46 /*
47 /*	SEND_ATTR_FUNC(tls_proxy_client_start_print, (const void *) start_props), ...
48 /* DIAGNOSTICS
49 /*	Fatal: out of memory.
50 /* LICENSE
51 /* .ad
52 /* .fi
53 /*	The Secure Mailer license must be distributed with this software.
54 /* AUTHOR(S)
55 /*	Wietse Venema
56 /*	Google, Inc.
57 /*	111 8th Avenue
58 /*	New York, NY 10011, USA
59 /*--*/
60 
61 #ifdef USE_TLS
62 
63 /* System library. */
64 
65 #include <sys_defs.h>
66 
67 /* Utility library */
68 
69 #include <argv_attr.h>
70 #include <attr.h>
71 #include <msg.h>
72 
73 /* Global library. */
74 
75 #include <mail_params.h>
76 
77 /* TLS library. */
78 
79 #include <tls.h>
80 #include <tls_proxy.h>
81 
82 
83 #define STR(x) vstring_str(x)
84 #define LEN(x) VSTRING_LEN(x)
85 
86 /* tls_proxy_client_param_print - send TLS_CLIENT_PARAMS over stream */
87 
tls_proxy_client_param_print(ATTR_PRINT_COMMON_FN print_fn,VSTREAM * fp,int flags,const void * ptr)88 int     tls_proxy_client_param_print(ATTR_PRINT_COMMON_FN print_fn, VSTREAM *fp,
89 				             int flags, const void *ptr)
90 {
91     const TLS_CLIENT_PARAMS *params = (const TLS_CLIENT_PARAMS *) ptr;
92     int     ret;
93 
94     if (msg_verbose)
95 	msg_info("begin tls_proxy_client_param_print");
96 
97     ret = print_fn(fp, flags | ATTR_FLAG_MORE,
98 		   SEND_ATTR_STR(VAR_TLS_HIGH_CLIST, params->tls_high_clist),
99 		   SEND_ATTR_STR(VAR_TLS_MEDIUM_CLIST,
100 				 params->tls_medium_clist),
101 		   SEND_ATTR_STR(VAR_TLS_LOW_CLIST, params->tls_low_clist),
102 		   SEND_ATTR_STR(VAR_TLS_EXPORT_CLIST,
103 				 params->tls_export_clist),
104 		   SEND_ATTR_STR(VAR_TLS_NULL_CLIST, params->tls_null_clist),
105 		   SEND_ATTR_STR(VAR_TLS_EECDH_AUTO, params->tls_eecdh_auto),
106 		   SEND_ATTR_STR(VAR_TLS_EECDH_STRONG,
107 				 params->tls_eecdh_strong),
108 		   SEND_ATTR_STR(VAR_TLS_EECDH_ULTRA,
109 				 params->tls_eecdh_ultra),
110 		   SEND_ATTR_STR(VAR_TLS_BUG_TWEAKS, params->tls_bug_tweaks),
111 		   SEND_ATTR_STR(VAR_TLS_SSL_OPTIONS,
112 				 params->tls_ssl_options),
113 		   SEND_ATTR_STR(VAR_TLS_DANE_DIGESTS,
114 				 params->tls_dane_digests),
115 		   SEND_ATTR_STR(VAR_TLS_MGR_SERVICE,
116 				 params->tls_mgr_service),
117 		   SEND_ATTR_STR(VAR_TLS_TKT_CIPHER, params->tls_tkt_cipher),
118 		   SEND_ATTR_INT(VAR_TLS_DAEMON_RAND_BYTES,
119 				 params->tls_daemon_rand_bytes),
120 		   SEND_ATTR_INT(VAR_TLS_APPEND_DEF_CA,
121 				 params->tls_append_def_CA),
122 		   SEND_ATTR_INT(VAR_TLS_BC_PKEY_FPRINT,
123 				 params->tls_bc_pkey_fprint),
124 		   SEND_ATTR_INT(VAR_TLS_PREEMPT_CLIST,
125 				 params->tls_preempt_clist),
126 		   SEND_ATTR_INT(VAR_TLS_MULTI_WILDCARD,
127 				 params->tls_multi_wildcard),
128 		   ATTR_TYPE_END);
129     /* Do not flush the stream. */
130     if (msg_verbose)
131 	msg_info("tls_proxy_client_param_print ret=%d", ret);
132     return (ret);
133 }
134 
135 /* tls_proxy_client_init_print - send TLS_CLIENT_INIT_PROPS over stream */
136 
tls_proxy_client_init_print(ATTR_PRINT_COMMON_FN print_fn,VSTREAM * fp,int flags,const void * ptr)137 int     tls_proxy_client_init_print(ATTR_PRINT_COMMON_FN print_fn, VSTREAM *fp,
138 				            int flags, const void *ptr)
139 {
140     const TLS_CLIENT_INIT_PROPS *props = (const TLS_CLIENT_INIT_PROPS *) ptr;
141     int     ret;
142 
143     if (msg_verbose)
144 	msg_info("begin tls_proxy_client_init_print");
145 
146 #define STRING_OR_EMPTY(s) ((s) ? (s) : "")
147 
148     ret = print_fn(fp, flags | ATTR_FLAG_MORE,
149 		   SEND_ATTR_STR(TLS_ATTR_LOG_PARAM,
150 				 STRING_OR_EMPTY(props->log_param)),
151 		   SEND_ATTR_STR(TLS_ATTR_LOG_LEVEL,
152 				 STRING_OR_EMPTY(props->log_level)),
153 		   SEND_ATTR_INT(TLS_ATTR_VERIFYDEPTH, props->verifydepth),
154 		   SEND_ATTR_STR(TLS_ATTR_CACHE_TYPE,
155 				 STRING_OR_EMPTY(props->cache_type)),
156 		   SEND_ATTR_STR(TLS_ATTR_CHAIN_FILES,
157 				 STRING_OR_EMPTY(props->chain_files)),
158 		   SEND_ATTR_STR(TLS_ATTR_CERT_FILE,
159 				 STRING_OR_EMPTY(props->cert_file)),
160 		   SEND_ATTR_STR(TLS_ATTR_KEY_FILE,
161 				 STRING_OR_EMPTY(props->key_file)),
162 		   SEND_ATTR_STR(TLS_ATTR_DCERT_FILE,
163 				 STRING_OR_EMPTY(props->dcert_file)),
164 		   SEND_ATTR_STR(TLS_ATTR_DKEY_FILE,
165 				 STRING_OR_EMPTY(props->dkey_file)),
166 		   SEND_ATTR_STR(TLS_ATTR_ECCERT_FILE,
167 				 STRING_OR_EMPTY(props->eccert_file)),
168 		   SEND_ATTR_STR(TLS_ATTR_ECKEY_FILE,
169 				 STRING_OR_EMPTY(props->eckey_file)),
170 		   SEND_ATTR_STR(TLS_ATTR_CAFILE,
171 				 STRING_OR_EMPTY(props->CAfile)),
172 		   SEND_ATTR_STR(TLS_ATTR_CAPATH,
173 				 STRING_OR_EMPTY(props->CApath)),
174 		   SEND_ATTR_STR(TLS_ATTR_MDALG,
175 				 STRING_OR_EMPTY(props->mdalg)),
176 		   ATTR_TYPE_END);
177     /* Do not flush the stream. */
178     if (msg_verbose)
179 	msg_info("tls_proxy_client_init_print ret=%d", ret);
180     return (ret);
181 }
182 
183 /* tls_proxy_client_tlsa_print - send TLS_TLSA over stream */
184 
tls_proxy_client_tlsa_print(ATTR_PRINT_COMMON_FN print_fn,VSTREAM * fp,int flags,const void * ptr)185 static int tls_proxy_client_tlsa_print(ATTR_PRINT_COMMON_FN print_fn,
186 			            VSTREAM *fp, int flags, const void *ptr)
187 {
188     const TLS_TLSA *head = (const TLS_TLSA *) ptr;
189     const TLS_TLSA *tp;
190     int     count;
191     int     ret;
192 
193     for (tp = head, count = 0; tp != 0; tp = tp->next)
194 	++count;
195     if (msg_verbose)
196 	msg_info("tls_proxy_client_tlsa_print count=%d", count);
197 
198     ret = print_fn(fp, flags | ATTR_FLAG_MORE,
199 		   SEND_ATTR_INT(TLS_ATTR_COUNT, count),
200 		   ATTR_TYPE_END);
201 
202     for (tp = head; ret == 0 && tp != 0; tp = tp->next)
203 	ret = print_fn(fp, flags | ATTR_FLAG_MORE,
204 		       SEND_ATTR_INT(TLS_ATTR_USAGE, tp->usage),
205 		       SEND_ATTR_INT(TLS_ATTR_SELECTOR, tp->selector),
206 		       SEND_ATTR_INT(TLS_ATTR_MTYPE, tp->mtype),
207 		       SEND_ATTR_DATA(TLS_ATTR_DATA, tp->length, tp->data),
208 		       ATTR_TYPE_END);
209 
210     /* Do not flush the stream. */
211     if (msg_verbose)
212 	msg_info("tls_proxy_client_tlsa_print ret=%d", count);
213     return (ret);
214 }
215 
216 /* tls_proxy_client_dane_print - send TLS_DANE over stream */
217 
tls_proxy_client_dane_print(ATTR_PRINT_COMMON_FN print_fn,VSTREAM * fp,int flags,const void * ptr)218 static int tls_proxy_client_dane_print(ATTR_PRINT_COMMON_FN print_fn,
219 			            VSTREAM *fp, int flags, const void *ptr)
220 {
221     const TLS_DANE *dane = (const TLS_DANE *) ptr;
222     int     ret;
223 
224     ret = print_fn(fp, flags | ATTR_FLAG_MORE,
225 		   SEND_ATTR_INT(TLS_ATTR_DANE, dane != 0),
226 		   ATTR_TYPE_END);
227     if (msg_verbose)
228 	msg_info("tls_proxy_client_dane_print dane=%d", dane != 0);
229 
230     if (ret == 0 && dane != 0) {
231 	/* Send the base_domain and RRs, we don't need the other fields */
232 	ret = print_fn(fp, flags | ATTR_FLAG_MORE,
233 		       SEND_ATTR_STR(TLS_ATTR_DOMAIN,
234 				     STRING_OR_EMPTY(dane->base_domain)),
235 		       SEND_ATTR_FUNC(tls_proxy_client_tlsa_print,
236 				      (const void *) dane->tlsa),
237 		       ATTR_TYPE_END);
238     }
239     /* Do not flush the stream. */
240     if (msg_verbose)
241 	msg_info("tls_proxy_client_dane_print ret=%d", ret);
242     return (ret);
243 }
244 
245 /* tls_proxy_client_start_print - send TLS_CLIENT_START_PROPS over stream */
246 
tls_proxy_client_start_print(ATTR_PRINT_COMMON_FN print_fn,VSTREAM * fp,int flags,const void * ptr)247 int     tls_proxy_client_start_print(ATTR_PRINT_COMMON_FN print_fn,
248 			            VSTREAM *fp, int flags, const void *ptr)
249 {
250     const TLS_CLIENT_START_PROPS *props = (const TLS_CLIENT_START_PROPS *) ptr;
251     int     ret;
252 
253     if (msg_verbose)
254 	msg_info("begin tls_proxy_client_start_print");
255 
256 #define STRING_OR_EMPTY(s) ((s) ? (s) : "")
257 
258     ret = print_fn(fp, flags | ATTR_FLAG_MORE,
259 		   SEND_ATTR_INT(TLS_ATTR_TIMEOUT, props->timeout),
260 		   SEND_ATTR_INT(TLS_ATTR_TLS_LEVEL, props->tls_level),
261 		   SEND_ATTR_STR(TLS_ATTR_NEXTHOP,
262 				 STRING_OR_EMPTY(props->nexthop)),
263 		   SEND_ATTR_STR(TLS_ATTR_HOST,
264 				 STRING_OR_EMPTY(props->host)),
265 		   SEND_ATTR_STR(TLS_ATTR_NAMADDR,
266 				 STRING_OR_EMPTY(props->namaddr)),
267 		   SEND_ATTR_STR(TLS_ATTR_SNI,
268 				 STRING_OR_EMPTY(props->sni)),
269 		   SEND_ATTR_STR(TLS_ATTR_SERVERID,
270 				 STRING_OR_EMPTY(props->serverid)),
271 		   SEND_ATTR_STR(TLS_ATTR_HELO,
272 				 STRING_OR_EMPTY(props->helo)),
273 		   SEND_ATTR_STR(TLS_ATTR_PROTOCOLS,
274 				 STRING_OR_EMPTY(props->protocols)),
275 		   SEND_ATTR_STR(TLS_ATTR_CIPHER_GRADE,
276 				 STRING_OR_EMPTY(props->cipher_grade)),
277 		   SEND_ATTR_STR(TLS_ATTR_CIPHER_EXCLUSIONS,
278 				 STRING_OR_EMPTY(props->cipher_exclusions)),
279 		   SEND_ATTR_FUNC(argv_attr_print,
280 				  (const void *) props->matchargv),
281 		   SEND_ATTR_STR(TLS_ATTR_MDALG,
282 				 STRING_OR_EMPTY(props->mdalg)),
283 		   SEND_ATTR_FUNC(tls_proxy_client_dane_print,
284 				  (const void *) props->dane),
285 		   ATTR_TYPE_END);
286     /* Do not flush the stream. */
287     if (msg_verbose)
288 	msg_info("tls_proxy_client_start_print ret=%d", ret);
289     return (ret);
290 }
291 
292 #endif
293