• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.net.ipsec.ike;
18 
19 import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP4_ADDRESS;
20 import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP4_DHCP;
21 import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP4_DNS;
22 import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP4_NETMASK;
23 import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP4_SUBNET;
24 import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP6_ADDRESS;
25 import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP6_DNS;
26 import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP6_SUBNET;
27 
28 import android.annotation.NonNull;
29 import android.annotation.SystemApi;
30 import android.net.IpPrefix;
31 import android.net.LinkAddress;
32 
33 import com.android.internal.net.ipsec.ike.message.IkeConfigPayload;
34 import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttribute;
35 import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv4Address;
36 import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv4Dhcp;
37 import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv4Dns;
38 import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv4Netmask;
39 import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv4Subnet;
40 import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv6Address;
41 import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv6Dns;
42 import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv6Subnet;
43 
44 import java.net.InetAddress;
45 import java.util.ArrayList;
46 import java.util.Collections;
47 import java.util.List;
48 import java.util.Objects;
49 
50 /**
51  * ChildSessionConfiguration represents the negotiated configuration for a Child Session.
52  *
53  * <p>Configurations include traffic selectors and internal network information.
54  */
55 public final class ChildSessionConfiguration {
56     private static final int IPv4_DEFAULT_PREFIX_LEN = 32;
57 
58     private final List<IkeTrafficSelector> mInboundTs = new ArrayList<>();
59     private final List<IkeTrafficSelector> mOutboundTs = new ArrayList<>();
60     private final List<LinkAddress> mInternalAddressList = new ArrayList<>();
61     private final List<InetAddress> mInternalDnsAddressList = new ArrayList<>();
62     private final List<IpPrefix> mSubnetAddressList = new ArrayList<>();
63     private final List<InetAddress> mInternalDhcpAddressList = new ArrayList<>();
64 
65     /**
66      * Construct an instance of {@link ChildSessionConfiguration}.
67      *
68      * <p>ChildSessionConfiguration may contain negotiated configuration information that is
69      * included in a Configure(Reply) Payload. Thus the input configPayload should always be a
70      * Configure(Reply), and never be a Configure(Request).
71      *
72      * @hide
73      */
ChildSessionConfiguration( List<IkeTrafficSelector> inTs, List<IkeTrafficSelector> outTs, IkeConfigPayload configPayload)74     public ChildSessionConfiguration(
75             List<IkeTrafficSelector> inTs,
76             List<IkeTrafficSelector> outTs,
77             IkeConfigPayload configPayload) {
78         this(inTs, outTs);
79 
80         if (configPayload.configType != IkeConfigPayload.CONFIG_TYPE_REPLY) {
81             throw new IllegalArgumentException(
82                     "Cannot build ChildSessionConfiguration with configuration type: "
83                             + configPayload.configType);
84         }
85 
86         // It is validated in IkeConfigPayload that a config reply only has at most one non-empty
87         // netmask and netmask exists only when IPv4 internal address exists.
88         ConfigAttributeIpv4Netmask netmaskAttr = null;
89         for (ConfigAttribute att : configPayload.recognizedAttributeList) {
90             if (att.attributeType == CONFIG_ATTR_INTERNAL_IP4_NETMASK && !att.isEmptyValue()) {
91                 netmaskAttr = (ConfigAttributeIpv4Netmask) att;
92             }
93         }
94 
95         for (ConfigAttribute att : configPayload.recognizedAttributeList) {
96             if (att.isEmptyValue()) continue;
97             switch (att.attributeType) {
98                 case CONFIG_ATTR_INTERNAL_IP4_ADDRESS:
99                     ConfigAttributeIpv4Address addressAttr = (ConfigAttributeIpv4Address) att;
100                     if (netmaskAttr != null) {
101                         mInternalAddressList.add(
102                                 new LinkAddress(addressAttr.address, netmaskAttr.getPrefixLen()));
103                     } else {
104                         mInternalAddressList.add(
105                                 new LinkAddress(addressAttr.address, IPv4_DEFAULT_PREFIX_LEN));
106                     }
107                     break;
108                 case CONFIG_ATTR_INTERNAL_IP4_NETMASK:
109                     // No action.
110                     break;
111                 case CONFIG_ATTR_INTERNAL_IP6_ADDRESS:
112                     mInternalAddressList.add(((ConfigAttributeIpv6Address) att).linkAddress);
113                     break;
114                 case CONFIG_ATTR_INTERNAL_IP4_DNS:
115                     mInternalDnsAddressList.add(((ConfigAttributeIpv4Dns) att).address);
116                     break;
117                 case CONFIG_ATTR_INTERNAL_IP6_DNS:
118                     mInternalDnsAddressList.add(((ConfigAttributeIpv6Dns) att).address);
119                     break;
120                 case CONFIG_ATTR_INTERNAL_IP4_SUBNET:
121                     ConfigAttributeIpv4Subnet ipv4SubnetAttr = (ConfigAttributeIpv4Subnet) att;
122                     mSubnetAddressList.add(
123                             new IpPrefix(
124                                     ipv4SubnetAttr.linkAddress.getAddress(),
125                                     ipv4SubnetAttr.linkAddress.getPrefixLength()));
126                     break;
127                 case CONFIG_ATTR_INTERNAL_IP6_SUBNET:
128                     ConfigAttributeIpv6Subnet ipV6SubnetAttr = (ConfigAttributeIpv6Subnet) att;
129                     mSubnetAddressList.add(
130                             new IpPrefix(
131                                     ipV6SubnetAttr.linkAddress.getAddress(),
132                                     ipV6SubnetAttr.linkAddress.getPrefixLength()));
133                     break;
134                 case CONFIG_ATTR_INTERNAL_IP4_DHCP:
135                     mInternalDhcpAddressList.add(((ConfigAttributeIpv4Dhcp) att).address);
136                     break;
137                 default:
138                     // Not relevant to child session
139             }
140         }
141     }
142 
143     /**
144      * Construct an instance of {@link ChildSessionConfiguration}.
145      *
146      * @hide
147      */
ChildSessionConfiguration( List<IkeTrafficSelector> inTs, List<IkeTrafficSelector> outTs)148     public ChildSessionConfiguration(
149             List<IkeTrafficSelector> inTs, List<IkeTrafficSelector> outTs) {
150         mInboundTs.addAll(inTs);
151         mOutboundTs.addAll(outTs);
152     }
153 
154     /**
155      * Construct an instance of {@link ChildSessionConfiguration}.
156      *
157      * @hide
158      */
ChildSessionConfiguration( List<IkeTrafficSelector> inTs, List<IkeTrafficSelector> outTs, List<LinkAddress> internalAddresses, List<IpPrefix> internalSubnets, List<InetAddress> internalDnsServers, List<InetAddress> internalDhcpServers)159     private ChildSessionConfiguration(
160             List<IkeTrafficSelector> inTs,
161             List<IkeTrafficSelector> outTs,
162             List<LinkAddress> internalAddresses,
163             List<IpPrefix> internalSubnets,
164             List<InetAddress> internalDnsServers,
165             List<InetAddress> internalDhcpServers) {
166         this(inTs, outTs);
167         mInternalAddressList.addAll(internalAddresses);
168         mSubnetAddressList.addAll(internalSubnets);
169         mInternalDnsAddressList.addAll(internalDnsServers);
170         mInternalDhcpAddressList.addAll(internalDhcpServers);
171     }
172 
173 
174     /**
175      * Returns the negotiated inbound traffic selectors.
176      *
177      * <p>Only inbound traffic within the range is acceptable to the Child Session.
178      *
179      * <p>The Android platform does not support port-based routing. Port ranges of traffic selectors
180      * are only informational.
181      *
182      * @return the inbound traffic selectors.
183      */
184     @NonNull
getInboundTrafficSelectors()185     public List<IkeTrafficSelector> getInboundTrafficSelectors() {
186         return mInboundTs;
187     }
188 
189     /**
190      * Returns the negotiated outbound traffic selectors.
191      *
192      * <p>Only outbound traffic within the range is acceptable to the Child Session.
193      *
194      * <p>The Android platform does not support port-based routing. Port ranges of traffic selectors
195      * are only informational.
196      *
197      * @return the outbound traffic selectors.
198      */
199     @NonNull
getOutboundTrafficSelectors()200     public List<IkeTrafficSelector> getOutboundTrafficSelectors() {
201         return mOutboundTs;
202     }
203 
204     /**
205      * Returns the assigned internal addresses.
206      *
207      * @return the assigned internal addresses, or an empty list when no addresses are assigned by
208      *     the remote IKE server (e.g. for a non-tunnel mode Child Session).
209      * @hide
210      */
211     @SystemApi
212     @NonNull
getInternalAddresses()213     public List<LinkAddress> getInternalAddresses() {
214         return Collections.unmodifiableList(mInternalAddressList);
215     }
216 
217     /**
218      * Returns the internal subnets protected by the IKE server.
219      *
220      * @return the internal subnets, or an empty list when no information of protected subnets is
221      *     provided by the IKE server (e.g. for a non-tunnel mode Child Session).
222      * @hide
223      */
224     @SystemApi
225     @NonNull
getInternalSubnets()226     public List<IpPrefix> getInternalSubnets() {
227         return Collections.unmodifiableList(mSubnetAddressList);
228     }
229 
230     /**
231      * Returns the internal DNS server addresses.
232      *
233      * @return the internal DNS server addresses, or an empty list when no DNS server is provided by
234      *     the IKE server (e.g. for a non-tunnel mode Child Session).
235      * @hide
236      */
237     @SystemApi
238     @NonNull
getInternalDnsServers()239     public List<InetAddress> getInternalDnsServers() {
240         return Collections.unmodifiableList(mInternalDnsAddressList);
241     }
242 
243     /**
244      * Returns the internal DHCP server addresses.
245      *
246      * @return the internal DHCP server addresses, or an empty list when no DHCP server is provided
247      *     by the IKE server (e.g. for a non-tunnel mode Child Session).
248      * @hide
249      */
250     @SystemApi
251     @NonNull
getInternalDhcpServers()252     public List<InetAddress> getInternalDhcpServers() {
253         return Collections.unmodifiableList(mInternalDhcpAddressList);
254     }
255 
256     /**
257      * This class can be used to incrementally construct a {@link ChildSessionConfiguration}.
258      *
259      * <p>Except for testing, IKE library users normally do not instantiate {@link
260      * ChildSessionConfiguration} themselves but instead get a reference via {@link
261      * ChildSessionCallback}
262      */
263     public static final class Builder {
264         private final List<IkeTrafficSelector> mInboundTs = new ArrayList<>();
265         private final List<IkeTrafficSelector> mOutboundTs = new ArrayList<>();
266         private final List<LinkAddress> mInternalAddressList = new ArrayList<>();
267         private final List<IpPrefix> mSubnetAddressList = new ArrayList<>();
268         private final List<InetAddress> mInternalDnsAddressList = new ArrayList<>();
269         private final List<InetAddress> mInternalDhcpAddressList = new ArrayList<>();
270 
271         /**
272          * Constructs a Builder.
273          *
274          * @param inTs the negotiated inbound traffic selectors
275          * @param outTs the negotiated outbound traffic selectors
276          */
Builder( @onNull List<IkeTrafficSelector> inTs, @NonNull List<IkeTrafficSelector> outTs)277         public Builder(
278                 @NonNull List<IkeTrafficSelector> inTs, @NonNull List<IkeTrafficSelector> outTs) {
279             Objects.requireNonNull(inTs, "inTs was null");
280             Objects.requireNonNull(outTs, "outTs was null");
281             if (inTs.isEmpty() || outTs.isEmpty()) {
282                 throw new IllegalArgumentException("inTs or outTs is empty.");
283             }
284             mInboundTs.addAll(inTs);
285             mOutboundTs.addAll(outTs);
286         }
287 
288         /**
289          * Adds an assigned internal address for the {@link ChildSessionConfiguration} being built.
290          *
291          * @param address an assigned internal addresses
292          * @return Builder this, to facilitate chaining
293          * @hide
294          */
295         @SystemApi
296         @NonNull
addInternalAddress(@onNull LinkAddress address)297         public Builder addInternalAddress(@NonNull LinkAddress address) {
298             Objects.requireNonNull(address, "address was null");
299             mInternalAddressList.add(address);
300             return this;
301         }
302 
303         /**
304          * Clears all assigned internal addresses from the {@link ChildSessionConfiguration} being
305          * built.
306          *
307          * @return Builder this, to facilitate chaining
308          * @hide
309          */
310         @SystemApi
311         @NonNull
clearInternalAddresses()312         public Builder clearInternalAddresses() {
313             mInternalAddressList.clear();
314             return this;
315         }
316 
317         /**
318          * Adds an assigned internal subnet for the {@link ChildSessionConfiguration} being built.
319          *
320          * @param subnet an assigned internal subnet
321          * @return Builder this, to facilitate chaining
322          * @hide
323          */
324         @SystemApi
325         @NonNull
addInternalSubnet(@onNull IpPrefix subnet)326         public Builder addInternalSubnet(@NonNull IpPrefix subnet) {
327             Objects.requireNonNull(subnet, "subnet was null");
328             mSubnetAddressList.add(subnet);
329             return this;
330         }
331 
332         /**
333          * Clears all assigned internal subnets from the {@link ChildSessionConfiguration} being
334          * built.
335          *
336          * @return Builder this, to facilitate chaining
337          * @hide
338          */
339         @SystemApi
340         @NonNull
clearInternalSubnets()341         public Builder clearInternalSubnets() {
342             mSubnetAddressList.clear();
343             return this;
344         }
345 
346         /**
347          * Adds an assigned internal DNS server for the {@link ChildSessionConfiguration} being
348          * built.
349          *
350          * @param dnsServer an assigned internal DNS server
351          * @return Builder this, to facilitate chaining
352          * @hide
353          */
354         @SystemApi
355         @NonNull
addInternalDnsServer(@onNull InetAddress dnsServer)356         public Builder addInternalDnsServer(@NonNull InetAddress dnsServer) {
357             Objects.requireNonNull(dnsServer, "dnsServer was null");
358             mInternalDnsAddressList.add(dnsServer);
359             return this;
360         }
361 
362         /**
363          * Clears all assigned internal DNS servers from the {@link ChildSessionConfiguration} being
364          * built.
365          *
366          * @return Builder this, to facilitate chaining
367          * @hide
368          */
369         @SystemApi
370         @NonNull
clearInternalDnsServers()371         public Builder clearInternalDnsServers() {
372             mInternalDnsAddressList.clear();
373             return this;
374         }
375 
376         /**
377          * Adds an assigned internal DHCP server for the {@link ChildSessionConfiguration} being
378          * built.
379          *
380          * @param dhcpServer an assigned internal DHCP server
381          * @return Builder this, to facilitate chaining
382          * @hide
383          */
384         @SystemApi
385         @NonNull
addInternalDhcpServer(@onNull InetAddress dhcpServer)386         public Builder addInternalDhcpServer(@NonNull InetAddress dhcpServer) {
387             Objects.requireNonNull(dhcpServer, "dhcpServer was null");
388             mInternalDhcpAddressList.add(dhcpServer);
389             return this;
390         }
391 
392         /**
393          * Clears all assigned internal DHCP servers for the {@link ChildSessionConfiguration} being
394          * built.
395          *
396          * @return Builder this, to facilitate chaining
397          * @hide
398          */
399         @SystemApi
400         @NonNull
clearInternalDhcpServers()401         public Builder clearInternalDhcpServers() {
402             mInternalDhcpAddressList.clear();
403             return this;
404         }
405 
406         /** Constructs an {@link ChildSessionConfiguration} instance. */
407         @NonNull
build()408         public ChildSessionConfiguration build() {
409             return new ChildSessionConfiguration(
410                     mInboundTs,
411                     mOutboundTs,
412                     mInternalAddressList,
413                     mSubnetAddressList,
414                     mInternalDnsAddressList,
415                     mInternalDhcpAddressList);
416         }
417     }
418 }
419