Bug Summary

File:programs/pluto/ikev2_child.c
Warning:line 73, column 21
Value stored to 'c' during its initialization is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name ikev2_child.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -mrelocation-model pic -pic-level 2 -pic-is-pie -mthread-model posix -mdisable-fp-elim -relaxed-aliasing -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -resource-dir /usr/lib64/clang/8.0.0 -D TimeZoneOffset=timezone -D linux -D PIE -D NSS_IPSEC_PROFILE -D XFRM_SUPPORT -D USE_XFRM_INTERFACE -D USE_DNSSEC -D DEFAULT_DNSSEC_ROOTKEY_FILE="/var/lib/unbound/root.key" -D HAVE_LABELED_IPSEC -D HAVE_SECCOMP -D LIBCURL -D USE_LINUX_AUDIT -D USE_SYSTEMD_WATCHDOG -D HAVE_NM -D XAUTH_HAVE_PAM -D USE_3DES -D USE_AES -D USE_CAMELLIA -D USE_CHACHA -D USE_DH31 -D USE_MD5 -D USE_SHA1 -D USE_SHA2 -D USE_PRF_AES_XCBC -D DEFAULT_RUNDIR="/run/pluto" -D IPSEC_CONF="/etc/ipsec.conf" -D IPSEC_CONFDDIR="/etc/ipsec.d" -D IPSEC_NSSDIR="/etc/ipsec.d" -D IPSEC_CONFDIR="/etc" -D IPSEC_EXECDIR="/usr/local/libexec/ipsec" -D IPSEC_SBINDIR="/usr/local/sbin" -D IPSEC_VARDIR="/var" -D POLICYGROUPSDIR="/etc/ipsec.d/policies" -D IPSEC_SECRETS_FILE="/etc/ipsec.secrets" -D FORCE_PR_ASSERT -D USE_FORK=1 -D USE_VFORK=0 -D USE_DAEMON=0 -D USE_PTHREAD_SETSCHEDPRIO=1 -D GCC_LINT -D HAVE_LIBCAP_NG -I . -I ../../OBJ.linux.x86_64/programs/pluto -I ../../include -I /usr/include/nss3 -I /usr/include/nspr4 -I /home/build/libreswan/programs/pluto/linux-copy -D HERE_BASENAME="ikev2_child.c" -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/8.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-missing-field-initializers -std=gnu99 -fdebug-compilation-dir /home/build/libreswan/programs/pluto -ferror-limit 19 -fmessage-length 0 -stack-protector 3 -fobjc-runtime=gcc -fdiagnostics-show-option -analyzer-output=html -o /tmp/scan-build-2020-09-09-193337-25440-1 -x c /home/build/libreswan/programs/pluto/ikev2_child.c -faddrsig
1/*
2 * Copyright (C) 2007-2008 Michael Richardson <mcr@xelerance.com>
3 * Copyright (C) 2009-2010 Paul Wouters <paul@xelerance.com>
4 * Copyright (C) 2010 Tuomo Soini <tis@foobar.fi>
5 * Copyright (C) 2011-2012 Avesh Agarwal <avagarwa@redhat.com>
6 * Copyright (C) 2012-2018 Paul Wouters <pwouters@redhat.com>
7 * Copyright (C) 2012,2016-2017 Antony Antony <appu@phenome.org>
8 * Copyright (C) 2013-2019 D. Hugh Redelmeier <hugh@mimosa.com>
9 * Copyright (C) 2014-2019 Andrew Cagney <cagney@gnu.org>
10 * Copyright (C) 2017 Antony Antony <antony@phenome.org>
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version. See <https://www.gnu.org/licenses/gpl2.txt>.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * for more details.
21 *
22 */
23
24#include <unistd.h>
25#include <sys/types.h>
26#include <sys/socket.h>
27#include <netinet/in.h>
28#include <arpa/inet.h>
29
30
31#include "sysdep.h"
32#include "constants.h"
33
34#include "defs.h"
35#include "id.h"
36#include "x509.h"
37#include "pluto_x509.h"
38#include "certs.h"
39#include "connections.h" /* needs id.h */
40#include "state.h"
41#include "packet.h"
42#include "crypto.h"
43#include "ike_alg.h"
44#include "log.h"
45#include "demux.h" /* needs packet.h */
46#include "pluto_crypt.h" /* for pluto_crypto_req & pluto_crypto_req_cont */
47#include "ikev2.h"
48#include "ipsec_doi.h" /* needs demux.h and state.h */
49#include "timer.h"
50#include "whack.h" /* requires connections.h */
51#include "server.h"
52#include "vendor.h"
53#include "kernel.h"
54#include "virtual.h" /* needs connections.h */
55#include "hostpair.h"
56#include "addresspool.h"
57#include "rnd.h"
58#include "ip_address.h"
59#include "ikev2_send.h"
60#include "ikev2_message.h"
61#include "ikev2_ts.h"
62#include "ip_info.h"
63#ifdef USE_XFRM_INTERFACE1
64# include "kernel_xfrm_interface.h"
65#endif
66
67stf_status ikev2_child_sa_respond(struct ike_sa *ike,
68 struct child_sa *child,
69 struct msg_digest *md,
70 pb_stream *outpbs,
71 enum isakmp_xchg_types isa_xchg)
72{
73 struct connection *c = md->st->st_connection;
Value stored to 'c' during its initialization is never read
74 struct state *cst = &child->sa; /* child state */
75
76 /* switch to child */
77 pexpect(md->st == &child->sa)({ _Bool assertion__ = md->st == &child->sa; if (!assertion__
) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_child.c"
, .line = 77}, "%s", "md->st == &child->sa"); } assertion__
; })
;
78 c = cst->st_connection;
79
80 if (c->spd.that.has_lease &&
81 md->chain[ISAKMP_NEXT_v2CP] != NULL((void*)0) &&
82 child->sa.st_state->kind != STATE_V2_REKEY_IKE_R0) {
83 /*
84 * XXX: should this be passed the CHILD SA's
85 * .st_connection? Here things are negotiating a new
86 * CHILD?
87 */
88 if (!emit_v2_child_configuration_payload(ike->sa.st_connection,
89 child, outpbs)) {
90 return STF_INTERNAL_ERROR;
91 }
92 } else if (md->chain[ISAKMP_NEXT_v2CP] != NULL((void*)0)) {
93 dbg("#%lu %s ignoring unexpected v2CP payload",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("#%lu %s ignoring unexpected v2CP payload", cst
->st_serialno, cst->st_state->name); } }
94 cst->st_serialno, cst->st_state->name){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("#%lu %s ignoring unexpected v2CP payload", cst
->st_serialno, cst->st_state->name); } }
;
95 }
96
97 /* start of SA out */
98 {
99 /* ??? this code won't support AH + ESP */
100 struct ipsec_proto_info *proto_info
101 = ikev2_child_sa_proto_info(pexpect_child_sa(cst), c->policy);
102
103 if (isa_xchg != ISAKMP_v2_CREATE_CHILD_SA) {
104 stf_status res = ikev2_process_child_sa_pl(ike, child, md, FALSE0);
105 if (res != STF_OK)
106 return res;
107 }
108 proto_info->our_spi = ikev2_child_sa_spi(&c->spd, c->policy);
109 chunk_t local_spi = THING_AS_CHUNK(proto_info->our_spi)chunk2(&(proto_info->our_spi), sizeof(proto_info->our_spi
))
;
110 if (!ikev2_emit_sa_proposal(outpbs,
111 child->sa.st_accepted_esp_or_ah_proposal,
112 &local_spi)) {
113 dbg("problem emitting accepted proposal"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("problem emitting accepted proposal"); } }
;
114 return STF_INTERNAL_ERROR;
115 }
116 }
117
118 if (isa_xchg == ISAKMP_v2_CREATE_CHILD_SA) {
119 /* send NONCE */
120 struct ikev2_generic in = {
121 .isag_critical = build_ikev2_critical(false0),
122 };
123 pb_stream pb_nr;
124 if (!out_struct(&in, &ikev2_nonce_desc, outpbs, &pb_nr) ||
125 !pbs_out_hunk(cst->st_nr, &pb_nr, "IKEv2 nonce")({ typeof(cst->st_nr) hunk_ = cst->st_nr; struct packet_byte_stream
*outs_ = &pb_nr; diag_t d_ = pbs_out_raw(outs_, hunk_.ptr
, hunk_.len, ("IKEv2 nonce")); if (d_ != ((void*)0)) { log_diag
(RC_LOG_SERIOUS, outs_->out_logger, &d_, "%s", ""); } d_
== ((void*)0); })
)
126 return STF_INTERNAL_ERROR;
127
128 close_output_pbs(&pb_nr);
129
130 /*
131 * XXX: shouldn't this be conditional on the local end
132 * having computed KE and not what the remote sent?
133 */
134 if (md->chain[ISAKMP_NEXT_v2KE] != NULL((void*)0)) {
135 if (!emit_v2KE(&cst->st_gr, cst->st_oakley.ta_dh, outpbs))
136 return STF_INTERNAL_ERROR;
137 }
138 }
139
140 /*
141 * Paul: This is the second time we are processing NOTIFY's I
142 * suspect we are only interested in those related to the
143 * Child SA and mark those on the child state. But this code
144 * is used in IKE_AUTH as well as CREATE_CHILD_SA, so we end
145 * up double logging bad payloads on the responder.
146 */
147 /* Process all NOTIFY payloads */
148 for (struct payload_digest *ntfy = md->chain[ISAKMP_NEXT_v2N];
149 ntfy != NULL((void*)0); ntfy = ntfy->next) {
150 switch (ntfy->payload.v2n.isan_type) {
151 case v2N_NAT_DETECTION_SOURCE_IP:
152 case v2N_NAT_DETECTION_DESTINATION_IP:
153 case v2N_IKEV2_FRAGMENTATION_SUPPORTED:
154 case v2N_COOKIE:
155 case v2N_USE_PPK:
156 dbg("received %s which is not valid for current exchange",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("received %s which is not valid for current exchange"
, enum_name(&ikev2_notify_names, ntfy->payload.v2n.isan_type
)); } }
157 enum_name(&ikev2_notify_names, ntfy->payload.v2n.isan_type)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("received %s which is not valid for current exchange"
, enum_name(&ikev2_notify_names, ntfy->payload.v2n.isan_type
)); } }
;
158 break;
159 case v2N_USE_TRANSPORT_MODE:
160 dbg("received USE_TRANSPORT_MODE"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("received USE_TRANSPORT_MODE"); } }
;
161 cst->st_seen_use_transport = TRUE1;
162 break;
163 case v2N_IPCOMP_SUPPORTED:
164 {
165 pb_stream pbs = ntfy->pbs;
166 size_t len = pbs_left(&pbs)((size_t)((&pbs)->roof - (&pbs)->cur));
167 struct ikev2_notify_ipcomp_data n_ipcomp;
168
169 dbg("received v2N_IPCOMP_SUPPORTED of length %zd", len){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("received v2N_IPCOMP_SUPPORTED of length %zd",
len); } }
;
170
171 if (!in_struct(&n_ipcomp, &ikev2notify_ipcomp_data_desc, &pbs, NULL((void*)0))) {
172 return STF_FATAL;
173 }
174
175 if (n_ipcomp.ikev2_notify_ipcomp_trans != IPCOMP_DEFLATE) {
176 loglog(RC_LOG_SERIOUS, "Unsupported IPCOMP compression method %d",
177 n_ipcomp.ikev2_notify_ipcomp_trans); /* enum_name this later */
178 return STF_FATAL;
179 }
180 if (n_ipcomp.ikev2_cpi < IPCOMP_FIRST_NEGOTIATED256) {
181 loglog(RC_LOG_SERIOUS, "Illegal IPCOMP CPI %d", n_ipcomp.ikev2_cpi);
182 return STF_FATAL;
183 }
184 if ((c->policy & POLICY_COMPRESS((lset_t)1 << (POLICY_COMPRESS_IX))) == LEMPTY((lset_t)0)) {
185 dbg("Ignored IPCOMP request as connection has compress=no"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("Ignored IPCOMP request as connection has compress=no"
); } }
;
186 cst->st_ipcomp.present = FALSE0;
187 break;
188 }
189 dbg("Received compression CPI=%d", htonl(n_ipcomp.ikev2_cpi)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("Received compression CPI=%d", htonl(n_ipcomp.
ikev2_cpi)); } }
;
190
191 //cst->st_ipcomp.attrs.spi = uniquify_peer_cpi((ipsec_spi_t)htonl(n_ipcomp.ikev2_cpi), cst, 0);
192 cst->st_ipcomp.attrs.spi = htonl((ipsec_spi_t)n_ipcomp.ikev2_cpi);
193 cst->st_ipcomp.attrs.transattrs.ta_comp = n_ipcomp.ikev2_notify_ipcomp_trans;
194 cst->st_ipcomp.attrs.mode = ENCAPSULATION_MODE_TUNNEL1; /* always? */
195 cst->st_ipcomp.present = TRUE1;
196 cst->st_seen_use_ipcomp = TRUE1;
197 break;
198 }
199 case v2N_ESP_TFC_PADDING_NOT_SUPPORTED:
200 dbg("received ESP_TFC_PADDING_NOT_SUPPORTED"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("received ESP_TFC_PADDING_NOT_SUPPORTED"); } }
;
201 cst->st_seen_no_tfc = TRUE1;
202 break;
203 case v2N_MOBIKE_SUPPORTED:
204 dbg("received v2N_MOBIKE_SUPPORTED"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("received v2N_MOBIKE_SUPPORTED"); } }
;
205 cst->st_seen_mobike = ike->sa.st_seen_mobike = TRUE1;
206 break;
207 case v2N_INITIAL_CONTACT:
208 dbg("received v2N_INITIAL_CONTACT"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("received v2N_INITIAL_CONTACT"); } }
;
209 cst->st_seen_initialc = ike->sa.st_seen_initialc = TRUE1;
210 break;
211 case v2N_REKEY_SA:
212 dbg("received REKEY_SA already proceesd"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("received REKEY_SA already proceesd"); } }
;
213 break;
214 case v2N_PPK_IDENTITY:
215 dbg("received PPK_IDENTITY already processed"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("received PPK_IDENTITY already processed"); } }
;
216 break;
217 case v2N_NO_PPK_AUTH:
218 dbg("received NO_PPK_AUTH already processed"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("received NO_PPK_AUTH already processed"); } }
;
219 break;
220 default:
221 libreswan_log("received unsupported NOTIFY %s ",loglog(RC_LOG, "received unsupported NOTIFY %s ", enum_name(&
ikev2_notify_names, ntfy->payload.v2n.isan_type))
222 enum_name(&ikev2_notify_names,loglog(RC_LOG, "received unsupported NOTIFY %s ", enum_name(&
ikev2_notify_names, ntfy->payload.v2n.isan_type))
223 ntfy->payload.v2n.isan_type))loglog(RC_LOG, "received unsupported NOTIFY %s ", enum_name(&
ikev2_notify_names, ntfy->payload.v2n.isan_type))
;
224 }
225 }
226
227 {
228 /* verify if transport / tunnel mode is matches */
229 if ((c->policy & POLICY_TUNNEL((lset_t)1 << (POLICY_TUNNEL_IX))) == LEMPTY((lset_t)0)) {
230 /* we should have received transport mode request - and send one */
231 if (!cst->st_seen_use_transport) {
232 libreswan_log("policy dictates Transport Mode, but peer requested Tunnel Mode")loglog(RC_LOG, "policy dictates Transport Mode, but peer requested Tunnel Mode"
)
;
233 return STF_FAIL + v2N_NO_PROPOSAL_CHOSEN;
234 }
235 } else {
236 if (cst->st_seen_use_transport) {
237 /* RFC allows us to ignore their (wrong) request for transport mode */
238 libreswan_log("policy dictates Tunnel Mode, ignoring peer's request for Transport Mode")loglog(RC_LOG, "policy dictates Tunnel Mode, ignoring peer's request for Transport Mode"
)
;
239 }
240 }
241
242 if (c->policy & POLICY_COMPRESS((lset_t)1 << (POLICY_COMPRESS_IX))) {
243 if (!cst->st_seen_use_ipcomp) {
244 dbg("policy suggested compression, but peer did not offer support"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("policy suggested compression, but peer did not offer support"
); } }
;
245 }
246 } else {
247 if (cst->st_seen_use_ipcomp) {
248 dbg("policy did not allow compression, ignoring peer's request"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("policy did not allow compression, ignoring peer's request"
); } }
;
249 }
250 }
251
252 /*
253 * XXX: see above notes on 'role' - this must be the
254 * SA_RESPONDER.
255 */
256 stf_status ret = v2_emit_ts_payloads(pexpect_child_sa(cst),
257 outpbs, c);
258
259 if (ret != STF_OK)
260 return ret; /* should we delete_state cst? */
261 }
262
263 if (cst->st_seen_use_transport) {
264 if (c->policy & POLICY_TUNNEL((lset_t)1 << (POLICY_TUNNEL_IX))) {
265 libreswan_log("Local policy is tunnel mode - ignoring request for transport mode")loglog(RC_LOG, "Local policy is tunnel mode - ignoring request for transport mode"
)
;
266 } else {
267 dbg("Local policy is transport mode and received USE_TRANSPORT_MODE"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("Local policy is transport mode and received USE_TRANSPORT_MODE"
); } }
;
268 if (cst->st_esp.present) {
269 cst->st_esp.attrs.mode =
270 ENCAPSULATION_MODE_TRANSPORT2;
271 }
272 if (cst->st_ah.present) {
273 cst->st_ah.attrs.mode =
274 ENCAPSULATION_MODE_TRANSPORT2;
275 }
276 /* In v2, for parent, protoid must be 0 and SPI must be empty */
277 if (!emit_v2N(v2N_USE_TRANSPORT_MODE, outpbs))
278 return STF_INTERNAL_ERROR;
279 }
280 } else {
281 /* the peer wants tunnel mode */
282 if ((c->policy & POLICY_TUNNEL((lset_t)1 << (POLICY_TUNNEL_IX))) == LEMPTY((lset_t)0)) {
283 loglog(RC_LOG_SERIOUS, "Local policy is transport mode, but peer did not request that");
284 return STF_FAIL + v2N_NO_PROPOSAL_CHOSEN;
285 }
286 }
287
288 if (c->send_no_esp_tfc) {
289 dbg("Sending ESP_TFC_PADDING_NOT_SUPPORTED"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("Sending ESP_TFC_PADDING_NOT_SUPPORTED"); } }
;
290 if (!emit_v2N(v2N_ESP_TFC_PADDING_NOT_SUPPORTED, outpbs))
291 return STF_INTERNAL_ERROR;
292 }
293
294 if (!emit_v2N_compression(cst, cst->st_seen_use_ipcomp, outpbs))
295 return STF_INTERNAL_ERROR;
296
297 ikev2_derive_child_keys(pexpect_child_sa(cst));
298
299 /*
300 * Check to see if we need to release an old instance
301 * Note that this will call delete on the old connection
302 * we should do this after installing ipsec_sa, but that will
303 * give us a "eroute in use" error.
304 */
305 if (isa_xchg == ISAKMP_v2_CREATE_CHILD_SA) {
306 /* skip check for rekey */
307 ike->sa.st_connection->newest_isakmp_sa = ike->sa.st_serialno;
308 } else {
309#ifdef USE_XFRM_INTERFACE1
310 if (c->xfrmi != NULL((void*)0) && c->xfrmi->if_id != yn_no)
311 if (add_xfrmi(c, child->sa.st_logger))
312 return STF_FATAL;
313#endif
314 IKE_SA_established(ike);
315 }
316
317 /* install inbound and outbound SPI info */
318 if (!install_ipsec_sa(cst, TRUE1))
319 return STF_FATAL;
320
321 /* mark the connection as now having an IPsec SA associated with it. */
322 set_newest_ipsec_sa(enum_name(&ikev2_exchange_names, isa_xchg), cst);
323
324 return STF_OK;
325}
326
327static void ikev2_set_domain(pb_stream *cp_a_pbs, struct state *st)
328{
329 bool_Bool responder = (st->st_state->kind != STATE_PARENT_I2);
330
331 if (!responder) {
332 char *safestr = cisco_stringify(cp_a_pbs, "INTERNAL_DNS_DOMAIN");
333 append_st_cfg_domain(st, safestr);
334 } else {
335 libreswan_log("initiator INTERNAL_DNS_DOMAIN CP ignored")loglog(RC_LOG, "initiator INTERNAL_DNS_DOMAIN CP ignored");
336 }
337}
338
339static bool_Bool ikev2_set_dns(pb_stream *cp_a_pbs, struct state *st,
340 const struct ip_info *af)
341{
342 struct connection *c = st->st_connection;
343
344 if (c->policy & POLICY_OPPORTUNISTIC((lset_t)1 << (POLICY_OPPORTUNISTIC_IX))) {
345 libreswan_log("ignored INTERNAL_IP%d_DNS CP payload for Opportunistic IPsec",loglog(RC_LOG, "ignored INTERNAL_IP%d_DNS CP payload for Opportunistic IPsec"
, af->ip_version)
346 af->ip_version)loglog(RC_LOG, "ignored INTERNAL_IP%d_DNS CP payload for Opportunistic IPsec"
, af->ip_version)
;
347 return true1;
348 }
349
350 ip_address ip;
351 if (!pbs_in_address(&ip, af, cp_a_pbs, "INTERNAL_IP_DNS CP payload")) {
352 return false0;
353 }
354
355 /* i.e. all zeros */
356 if (address_is_any(&ip)) {
357 address_buf ip_str;
358 libreswan_log("ERROR INTERNAL_IP%d_DNS %s is invalid",loglog(RC_LOG, "ERROR INTERNAL_IP%d_DNS %s is invalid", af->
ip_version, ipstr(&ip, &ip_str))
359 af->ip_version, ipstr(&ip, &ip_str))loglog(RC_LOG, "ERROR INTERNAL_IP%d_DNS %s is invalid", af->
ip_version, ipstr(&ip, &ip_str))
;
360 return false0;
361 }
362
363 bool_Bool responder = (st->st_state->kind != STATE_PARENT_I2);
364 if (!responder) {
365 address_buf ip_buf;
366 const char *ip_str = ipstr(&ip, &ip_buf);
367 libreswan_log("received INTERNAL_IP%d_DNS %s",loglog(RC_LOG, "received INTERNAL_IP%d_DNS %s", af->ip_version
, ip_str)
368 af->ip_version, ip_str)loglog(RC_LOG, "received INTERNAL_IP%d_DNS %s", af->ip_version
, ip_str)
;
369 append_st_cfg_dns(st, ip_str);
370 } else {
371 libreswan_log("initiator INTERNAL_IP%d_DNS CP ignored",loglog(RC_LOG, "initiator INTERNAL_IP%d_DNS CP ignored", af->
ip_version)
372 af->ip_version)loglog(RC_LOG, "initiator INTERNAL_IP%d_DNS CP ignored", af->
ip_version)
;
373 }
374
375 return true1;
376}
377
378static bool_Bool ikev2_set_ia(pb_stream *cp_a_pbs, struct state *st,
379 const struct ip_info *af, bool_Bool *seen_an_address)
380{
381 struct connection *c = st->st_connection;
382
383 ip_address ip;
384 if (!pbs_in_address(&ip, af, cp_a_pbs, "INTERNAL_IP_ADDRESS")) {
385 return false0;
386 }
387
388 /*
389 * if (af->af == AF_INET6) pbs_in_address only reads 16 bytes.
390 * There should be one more byte in the pbs, 17th byte is prefix length.
391 */
392
393 if (address_is_any(&ip)) {
394 ipstr_buf ip_str;
395 libreswan_log("ERROR INTERNAL_IP%d_ADDRESS %s is invalid",loglog(RC_LOG, "ERROR INTERNAL_IP%d_ADDRESS %s is invalid", af
->ip_version, ipstr(&ip, &ip_str))
396 af->ip_version, ipstr(&ip, &ip_str))loglog(RC_LOG, "ERROR INTERNAL_IP%d_ADDRESS %s is invalid", af
->ip_version, ipstr(&ip, &ip_str))
;
397 return false0;
398 }
399
400 ipstr_buf ip_str;
401 libreswan_log("received INTERNAL_IP%d_ADDRESS %s%s",loglog(RC_LOG, "received INTERNAL_IP%d_ADDRESS %s%s", af->
ip_version, ipstr(&ip, &ip_str), *seen_an_address ? "; discarded"
: "")
402 af->ip_version, ipstr(&ip, &ip_str),loglog(RC_LOG, "received INTERNAL_IP%d_ADDRESS %s%s", af->
ip_version, ipstr(&ip, &ip_str), *seen_an_address ? "; discarded"
: "")
403 *seen_an_address ? "; discarded" : "")loglog(RC_LOG, "received INTERNAL_IP%d_ADDRESS %s%s", af->
ip_version, ipstr(&ip, &ip_str), *seen_an_address ? "; discarded"
: "")
;
404
405
406 bool_Bool responder = st->st_state->kind != STATE_PARENT_I2;
407 if (responder) {
408 libreswan_log("bogus responder CP ignored")loglog(RC_LOG, "bogus responder CP ignored");
409 return true1;
410 }
411
412 if (*seen_an_address) {
413 return true1;
414 }
415
416 *seen_an_address = true1;
417 c->spd.this.has_client = true1;
418 c->spd.this.has_internal_address = true1;
419
420 if (c->spd.this.cat) {
421 dbg("CAT is set, not setting host source IP address to %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("CAT is set, not setting host source IP address to %s"
, ipstr(&ip, &ip_str)); } }
422 ipstr(&ip, &ip_str)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("CAT is set, not setting host source IP address to %s"
, ipstr(&ip, &ip_str)); } }
;
423 if (sameaddr(&c->spd.this.client.addr, &ip)) {
424 /* The address we received is same as this side
425 * should we also check the host_srcip */
426 dbg("#%lu %s[%lu] received INTERNAL_IP%d_ADDRESS that is same as this.client.addr %s. Will not add CAT iptable rules",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("#%lu %s[%lu] received INTERNAL_IP%d_ADDRESS that is same as this.client.addr %s. Will not add CAT iptable rules"
, st->st_serialno, c->name, c->instance_serial, af->
ip_version, ipstr(&ip, &ip_str)); } }
427 st->st_serialno, c->name, c->instance_serial,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("#%lu %s[%lu] received INTERNAL_IP%d_ADDRESS that is same as this.client.addr %s. Will not add CAT iptable rules"
, st->st_serialno, c->name, c->instance_serial, af->
ip_version, ipstr(&ip, &ip_str)); } }
428 af->ip_version, ipstr(&ip, &ip_str)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("#%lu %s[%lu] received INTERNAL_IP%d_ADDRESS that is same as this.client.addr %s. Will not add CAT iptable rules"
, st->st_serialno, c->name, c->instance_serial, af->
ip_version, ipstr(&ip, &ip_str)); } }
;
429 } else {
430 c->spd.this.client.addr = ip;
431 c->spd.this.client.maskbits = af->mask_cnt;
432 st->st_ts_this = ikev2_end_to_ts(&c->spd.this);
433 c->spd.this.has_cat = TRUE1; /* create iptable entry */
434 }
435 } else {
436 endtosubnet(&ip, &c->spd.this.client, HERE(where_t) { .func = __func__, .basename = "ikev2_child.c" , .
line = 436}
);
437 setportof(0, &c->spd.this.client.addr){ *(&c->spd.this.client.addr) = set_endpoint_hport((&
c->spd.this.client.addr), ntohs(0)); }
; /* ??? redundant? */
438 /* only set sourceip= value if unset in configuration */
439 if (address_type(&c->spd.this.host_srcip) == NULL((void*)0) ||
440 isanyaddr(&c->spd.this.host_srcip)) {
441 dbg("setting host source IP address to %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("setting host source IP address to %s", ipstr(
&ip, &ip_str)); } }
442 ipstr(&ip, &ip_str)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("setting host source IP address to %s", ipstr(
&ip, &ip_str)); } }
;
443 c->spd.this.host_srcip = ip;
444 }
445 }
446
447 return true1;
448}
449
450bool_Bool ikev2_parse_cp_r_body(struct payload_digest *cp_pd, struct state *st)
451{
452 struct ikev2_cp *cp = &cp_pd->payload.v2cp;
453 struct connection *c = st->st_connection;
454 pb_stream *attrs = &cp_pd->pbs;
455
456 dbg("#%lu %s[%lu] parsing ISAKMP_NEXT_v2CP payload",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("#%lu %s[%lu] parsing ISAKMP_NEXT_v2CP payload"
, st->st_serialno, c->name, c->instance_serial); } }
457 st->st_serialno, c->name, c->instance_serial){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("#%lu %s[%lu] parsing ISAKMP_NEXT_v2CP payload"
, st->st_serialno, c->name, c->instance_serial); } }
;
458
459 if (st->st_state->kind == STATE_PARENT_I2 && cp->isacp_type != IKEv2_CP_CFG_REPLY) {
460 loglog(RC_LOG_SERIOUS, "ERROR expected IKEv2_CP_CFG_REPLY got a %s",
461 enum_name(&ikev2_cp_type_names, cp->isacp_type));
462 return FALSE0;
463 }
464
465 if (st->st_state->kind == STATE_PARENT_R1 && cp->isacp_type != IKEv2_CP_CFG_REQUEST) {
466 loglog(RC_LOG_SERIOUS, "ERROR expected IKEv2_CP_CFG_REQUEST got a %s",
467 enum_name(&ikev2_cp_type_names, cp->isacp_type));
468 return FALSE0;
469 }
470
471 bool_Bool seen_internal_address = false0;
472 while (pbs_left(attrs)((size_t)((attrs)->roof - (attrs)->cur)) > 0) {
473 struct ikev2_cp_attribute cp_a;
474 pb_stream cp_a_pbs;
475
476 if (!in_struct(&cp_a, &ikev2_cp_attribute_desc,
477 attrs, &cp_a_pbs)) {
478 loglog(RC_LOG_SERIOUS, "ERROR malformed CP attribute");
479 return FALSE0;
480 }
481
482 switch (cp_a.type) {
483 case IKEv2_INTERNAL_IP4_ADDRESS | ISAKMP_ATTR_AF_TLV0:
484 if (!ikev2_set_ia(&cp_a_pbs, st, &ipv4_info,
485 &seen_internal_address)) {
486 loglog(RC_LOG_SERIOUS, "ERROR malformed INTERNAL_IP4_ADDRESS attribute");
487 return FALSE0;
488 }
489 break;
490
491 case IKEv2_INTERNAL_IP4_DNS | ISAKMP_ATTR_AF_TLV0:
492 if (!ikev2_set_dns(&cp_a_pbs, st, &ipv4_info)) {
493 loglog(RC_LOG_SERIOUS, "ERROR malformed INTERNAL_IP4_DNS attribute");
494 return FALSE0;
495 }
496 break;
497
498 case IKEv2_INTERNAL_IP6_ADDRESS | ISAKMP_ATTR_AF_TLV0:
499 if (!ikev2_set_ia(&cp_a_pbs, st, &ipv6_info,
500 &seen_internal_address)) {
501 loglog(RC_LOG_SERIOUS, "ERROR malformed INTERNAL_IP6_ADDRESS attribute");
502 return FALSE0;
503 }
504 break;
505
506 case IKEv2_INTERNAL_IP6_DNS | ISAKMP_ATTR_AF_TLV0:
507 if (!ikev2_set_dns(&cp_a_pbs, st, &ipv6_info)) {
508 loglog(RC_LOG_SERIOUS, "ERROR malformed INTERNAL_IP6_DNS attribute");
509 return FALSE0;
510 }
511 break;
512
513 case IKEv2_INTERNAL_DNS_DOMAIN | ISAKMP_ATTR_AF_TLV0:
514 ikev2_set_domain(&cp_a_pbs, st); /* can't fail */
515 break;
516
517 default:
518 libreswan_log("unknown attribute %s length %u",loglog(RC_LOG, "unknown attribute %s length %u", enum_name(&
ikev2_cp_attribute_type_names, cp_a.type), cp_a.len)
519 enum_name(&ikev2_cp_attribute_type_names,loglog(RC_LOG, "unknown attribute %s length %u", enum_name(&
ikev2_cp_attribute_type_names, cp_a.type), cp_a.len)
520 cp_a.type),loglog(RC_LOG, "unknown attribute %s length %u", enum_name(&
ikev2_cp_attribute_type_names, cp_a.type), cp_a.len)
521 cp_a.len)loglog(RC_LOG, "unknown attribute %s length %u", enum_name(&
ikev2_cp_attribute_type_names, cp_a.type), cp_a.len)
;
522 break;
523 }
524 }
525 return TRUE1;
526}