1/*	$OpenBSD: print.c,v 1.4 2023/06/13 12:34:12 tb Exp $	*/
2
3/*
4 * Copyright (c) 2019-2021 Tobias Heider <tobias.heider@stusta.de>
5 * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#include <sys/types.h>
21#include <sys/socket.h>
22#include <sys/uio.h>
23#include <net/if.h>
24
25#include <inttypes.h>
26#include <stdio.h>
27#include <stdlib.h>
28#include <unistd.h>
29#include <event.h>
30
31#include "iked.h"
32#include "ikev2.h"
33#include "eap.h"
34
35const char *
36print_xf(unsigned int id, unsigned int length, const struct ipsec_xf xfs[])
37{
38	int		i;
39
40	for (i = 0; xfs[i].name != NULL; i++) {
41		if (xfs[i].id == id) {
42			if (length == 0 || length == xfs[i].length)
43				return (xfs[i].name);
44		}
45	}
46	return ("unknown");
47}
48
49void
50print_user(struct iked_user *usr)
51{
52	print_verbose("user \"%s\" \"%s\"\n", usr->usr_name, usr->usr_pass);
53}
54
55void
56print_policy(struct iked_policy *pol)
57{
58	struct iked_proposal	*pp;
59	struct iked_transform	*xform;
60	struct iked_flow	*flow;
61	struct iked_cfg		*cfg;
62	unsigned int		 i, j;
63	const struct ipsec_xf	*xfs = NULL;
64	char			 iface[IF_NAMESIZE];
65
66	print_verbose("ikev2");
67
68	if (pol->pol_name[0] != '\0')
69		print_verbose(" \"%s\"", pol->pol_name);
70
71	if (pol->pol_flags & IKED_POLICY_DEFAULT)
72		print_verbose(" default");
73	else if (pol->pol_flags & IKED_POLICY_QUICK)
74		print_verbose(" quick");
75	else if (pol->pol_flags & IKED_POLICY_SKIP)
76		print_verbose(" skip");
77
78	if (pol->pol_flags & IKED_POLICY_ACTIVE)
79		print_verbose(" active");
80	else
81		print_verbose(" passive");
82
83	if (pol->pol_flags & IKED_POLICY_IPCOMP)
84		print_verbose(" ipcomp");
85
86	if (pol->pol_flags & IKED_POLICY_TRANSPORT)
87		print_verbose(" transport");
88	else
89		print_verbose(" tunnel");
90
91	print_verbose(" %s", print_xf(pol->pol_saproto, 0, saxfs));
92
93	if (pol->pol_nipproto > 0) {
94		print_verbose(" proto {");
95		for (i = 0; i < pol->pol_nipproto; i++) {
96			if (i == 0)
97				print_verbose(" %s", print_proto(pol->pol_ipproto[i]));
98			else
99				print_verbose(", %s", print_proto(pol->pol_ipproto[i]));
100		}
101		print_verbose(" }");
102	}
103
104	if (pol->pol_af) {
105		if (pol->pol_af == AF_INET)
106			print_verbose(" inet");
107		else
108			print_verbose(" inet6");
109	}
110
111	if (pol->pol_rdomain >= 0)
112		print_verbose(" rdomain %d", pol->pol_rdomain);
113
114	RB_FOREACH(flow, iked_flows, &pol->pol_flows) {
115		print_verbose(" from %s", print_addr(&flow->flow_src.addr));
116		if (flow->flow_src.addr_af != AF_UNSPEC &&
117		    flow->flow_src.addr_net)
118			print_verbose("/%d", flow->flow_src.addr_mask);
119		if (flow->flow_src.addr_port)
120			print_verbose(" port %d",
121			    ntohs(flow->flow_src.addr_port));
122
123		print_verbose(" to %s", print_addr(&flow->flow_dst.addr));
124		if (flow->flow_dst.addr_af != AF_UNSPEC &&
125		    flow->flow_dst.addr_net)
126			print_verbose("/%d", flow->flow_dst.addr_mask);
127		if (flow->flow_dst.addr_port)
128			print_verbose(" port %d",
129			    ntohs(flow->flow_dst.addr_port));
130	}
131
132	if ((pol->pol_flags & IKED_POLICY_DEFAULT) == 0) {
133		print_verbose(" local %s", print_addr(&pol->pol_local.addr));
134		if (pol->pol_local.addr.ss_family != AF_UNSPEC &&
135		    pol->pol_local.addr_net)
136			print_verbose("/%d", pol->pol_local.addr_mask);
137
138		print_verbose(" peer %s", print_addr(&pol->pol_peer.addr));
139		if (pol->pol_peer.addr.ss_family != AF_UNSPEC &&
140		    pol->pol_peer.addr_net)
141			print_verbose("/%d", pol->pol_peer.addr_mask);
142	}
143
144	TAILQ_FOREACH(pp, &pol->pol_proposals, prop_entry) {
145		if (!pp->prop_nxforms)
146			continue;
147		if (pp->prop_protoid == IKEV2_SAPROTO_IKE)
148			print_verbose(" ikesa");
149		else
150			print_verbose(" childsa");
151
152		for (j = 0; ikev2_xformtype_map[j].cm_type != 0; j++) {
153			xfs = NULL;
154
155			for (i = 0; i < pp->prop_nxforms; i++) {
156				xform = pp->prop_xforms + i;
157
158				if (xform->xform_type !=
159				    ikev2_xformtype_map[j].cm_type)
160					continue;
161
162				switch (xform->xform_type) {
163				case IKEV2_XFORMTYPE_INTEGR:
164					print_verbose(" auth ");
165					xfs = authxfs;
166					break;
167				case IKEV2_XFORMTYPE_ENCR:
168					print_verbose(" enc ");
169					if (pp->prop_protoid ==
170					    IKEV2_SAPROTO_IKE)
171						xfs = ikeencxfs;
172					else
173						xfs = ipsecencxfs;
174					break;
175				case IKEV2_XFORMTYPE_PRF:
176					print_verbose(" prf ");
177					xfs = prfxfs;
178					break;
179				case IKEV2_XFORMTYPE_DH:
180					print_verbose(" group ");
181					xfs = groupxfs;
182					break;
183				case IKEV2_XFORMTYPE_ESN:
184					print_verbose(" ");
185					xfs = esnxfs;
186					break;
187				default:
188					continue;
189				}
190
191				print_verbose("%s", print_xf(xform->xform_id,
192				    xform->xform_length / 8, xfs));
193			}
194		}
195	}
196
197	if (pol->pol_localid.id_length != 0)
198		print_verbose(" srcid %s", pol->pol_localid.id_data);
199	if (pol->pol_peerid.id_length != 0)
200		print_verbose(" dstid %s", pol->pol_peerid.id_data);
201
202	if (pol->pol_rekey)
203		print_verbose(" ikelifetime %u", pol->pol_rekey);
204
205	print_verbose(" lifetime %llu bytes %llu",
206	    pol->pol_lifetime.lt_seconds, pol->pol_lifetime.lt_bytes);
207
208	switch (pol->pol_auth.auth_method) {
209	case IKEV2_AUTH_NONE:
210		print_verbose (" none");
211		break;
212	case IKEV2_AUTH_SHARED_KEY_MIC:
213		print_verbose(" psk 0x");
214		for (i = 0; i < pol->pol_auth.auth_length; i++)
215			print_verbose("%02x", pol->pol_auth.auth_data[i]);
216		break;
217	default:
218		if (pol->pol_auth.auth_eap)
219			print_verbose(" eap \"%s\"",
220			    print_map(pol->pol_auth.auth_eap, eap_type_map));
221		else
222			print_verbose(" %s",
223			    print_xf(pol->pol_auth.auth_method, 0, methodxfs));
224	}
225
226	for (i = 0; i < pol->pol_ncfg; i++) {
227		cfg = &pol->pol_cfg[i];
228		print_verbose(" config %s %s", print_xf(cfg->cfg_type,
229		    cfg->cfg.address.addr_af, cpxfs),
230		    print_addr(&cfg->cfg.address.addr));
231	}
232
233	if (pol->pol_iface != 0 && if_indextoname(pol->pol_iface, iface) != NULL)
234		print_verbose(" iface %s", iface);
235
236	if (pol->pol_tag[0] != '\0')
237		print_verbose(" tag \"%s\"", pol->pol_tag);
238
239	if (pol->pol_tap != 0)
240		print_verbose(" tap \"enc%u\"", pol->pol_tap);
241
242	print_verbose("\n");
243}
244