1 /* $OpenBSD: print.c,v 1.3 2021/10/26 17:31:22 tobhe 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 35 const char * 36 print_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 49 void 50 print_user(struct iked_user *usr) 51 { 52 print_verbose("user \"%s\" \"%s\"\n", usr->usr_name, usr->usr_pass); 53 } 54 55 void 56 print_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", 116 print_host((struct sockaddr *)&flow->flow_src.addr, NULL, 117 0)); 118 if (flow->flow_src.addr_af != AF_UNSPEC && 119 flow->flow_src.addr_net) 120 print_verbose("/%d", flow->flow_src.addr_mask); 121 if (flow->flow_src.addr_port) 122 print_verbose(" port %d", 123 ntohs(flow->flow_src.addr_port)); 124 125 print_verbose(" to %s", 126 print_host((struct sockaddr *)&flow->flow_dst.addr, NULL, 127 0)); 128 if (flow->flow_dst.addr_af != AF_UNSPEC && 129 flow->flow_dst.addr_net) 130 print_verbose("/%d", flow->flow_dst.addr_mask); 131 if (flow->flow_dst.addr_port) 132 print_verbose(" port %d", 133 ntohs(flow->flow_dst.addr_port)); 134 } 135 136 if ((pol->pol_flags & IKED_POLICY_DEFAULT) == 0) { 137 print_verbose(" local %s", 138 print_host((struct sockaddr *)&pol->pol_local.addr, NULL, 139 0)); 140 if (pol->pol_local.addr.ss_family != AF_UNSPEC && 141 pol->pol_local.addr_net) 142 print_verbose("/%d", pol->pol_local.addr_mask); 143 144 print_verbose(" peer %s", 145 print_host((struct sockaddr *)&pol->pol_peer.addr, NULL, 146 0)); 147 if (pol->pol_peer.addr.ss_family != AF_UNSPEC && 148 pol->pol_peer.addr_net) 149 print_verbose("/%d", pol->pol_peer.addr_mask); 150 } 151 152 TAILQ_FOREACH(pp, &pol->pol_proposals, prop_entry) { 153 if (!pp->prop_nxforms) 154 continue; 155 if (pp->prop_protoid == IKEV2_SAPROTO_IKE) 156 print_verbose(" ikesa"); 157 else 158 print_verbose(" childsa"); 159 160 for (j = 0; ikev2_xformtype_map[j].cm_type != 0; j++) { 161 xfs = NULL; 162 163 for (i = 0; i < pp->prop_nxforms; i++) { 164 xform = pp->prop_xforms + i; 165 166 if (xform->xform_type != 167 ikev2_xformtype_map[j].cm_type) 168 continue; 169 170 switch (xform->xform_type) { 171 case IKEV2_XFORMTYPE_INTEGR: 172 print_verbose(" auth "); 173 xfs = authxfs; 174 break; 175 case IKEV2_XFORMTYPE_ENCR: 176 print_verbose(" enc "); 177 if (pp->prop_protoid == 178 IKEV2_SAPROTO_IKE) 179 xfs = ikeencxfs; 180 else 181 xfs = ipsecencxfs; 182 break; 183 case IKEV2_XFORMTYPE_PRF: 184 print_verbose(" prf "); 185 xfs = prfxfs; 186 break; 187 case IKEV2_XFORMTYPE_DH: 188 print_verbose(" group "); 189 xfs = groupxfs; 190 break; 191 case IKEV2_XFORMTYPE_ESN: 192 print_verbose(" "); 193 xfs = esnxfs; 194 break; 195 default: 196 continue; 197 } 198 199 print_verbose("%s", print_xf(xform->xform_id, 200 xform->xform_length / 8, xfs)); 201 } 202 } 203 } 204 205 if (pol->pol_localid.id_length != 0) 206 print_verbose(" srcid %s", pol->pol_localid.id_data); 207 if (pol->pol_peerid.id_length != 0) 208 print_verbose(" dstid %s", pol->pol_peerid.id_data); 209 210 if (pol->pol_rekey) 211 print_verbose(" ikelifetime %u", pol->pol_rekey); 212 213 print_verbose(" lifetime %llu bytes %llu", 214 pol->pol_lifetime.lt_seconds, pol->pol_lifetime.lt_bytes); 215 216 switch (pol->pol_auth.auth_method) { 217 case IKEV2_AUTH_NONE: 218 print_verbose (" none"); 219 break; 220 case IKEV2_AUTH_SHARED_KEY_MIC: 221 print_verbose(" psk 0x"); 222 for (i = 0; i < pol->pol_auth.auth_length; i++) 223 print_verbose("%02x", pol->pol_auth.auth_data[i]); 224 break; 225 default: 226 if (pol->pol_auth.auth_eap) 227 print_verbose(" eap \"%s\"", 228 print_map(pol->pol_auth.auth_eap, eap_type_map)); 229 else 230 print_verbose(" %s", 231 print_xf(pol->pol_auth.auth_method, 0, methodxfs)); 232 } 233 234 for (i = 0; i < pol->pol_ncfg; i++) { 235 cfg = &pol->pol_cfg[i]; 236 print_verbose(" config %s %s", print_xf(cfg->cfg_type, 237 cfg->cfg.address.addr_af, cpxfs), 238 print_host((struct sockaddr *)&cfg->cfg.address.addr, NULL, 239 0)); 240 } 241 242 if (pol->pol_iface != 0 && if_indextoname(pol->pol_iface, iface) != NULL) 243 print_verbose(" iface %s", iface); 244 245 if (pol->pol_tag[0] != '\0') 246 print_verbose(" tag \"%s\"", pol->pol_tag); 247 248 if (pol->pol_tap != 0) 249 print_verbose(" tap \"enc%u\"", pol->pol_tap); 250 251 print_verbose("\n"); 252 } 253