Project

General

Profile

Download (21.6 KB) Statistics
| Branch: | Tag: | Revision:
1 a93e56c5 Matthew Grooms
<?php
2
/*
3 8acd654a Renato Botelho
 * ipsec.inc
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6 aaec5634 Renato Botelho
 * Copyright (c) 2008 Shrew Soft Inc.
7 8acd654a Renato Botelho
 * Copyright (c) 2007-2016 Electric Sheep Fencing, LLC
8
 * All rights reserved.
9
 *
10
 * Redistribution and use in source and binary forms, with or without
11
 * modification, are permitted provided that the following conditions are met:
12
 *
13
 * 1. Redistributions of source code must retain the above copyright notice,
14
 *    this list of conditions and the following disclaimer.
15
 *
16
 * 2. Redistributions in binary form must reproduce the above copyright
17
 *    notice, this list of conditions and the following disclaimer in
18
 *    the documentation and/or other materials provided with the
19
 *    distribution.
20
 *
21
 * 3. All advertising materials mentioning features or use of this software
22
 *    must display the following acknowledgment:
23
 *    "This product includes software developed by the pfSense Project
24
 *    for use in the pfSense® software distribution. (http://www.pfsense.org/).
25
 *
26
 * 4. The names "pfSense" and "pfSense Project" must not be used to
27
 *    endorse or promote products derived from this software without
28
 *    prior written permission. For written permission, please contact
29
 *    coreteam@pfsense.org.
30
 *
31
 * 5. Products derived from this software may not be called "pfSense"
32
 *    nor may "pfSense" appear in their names without prior written
33
 *    permission of the Electric Sheep Fencing, LLC.
34
 *
35
 * 6. Redistributions of any form whatsoever must retain the following
36
 *    acknowledgment:
37
 *
38
 * "This product includes software developed by the pfSense Project
39
 * for use in the pfSense software distribution (http://www.pfsense.org/).
40
 *
41
 * THIS SOFTWARE IS PROVIDED BY THE pfSense PROJECT ``AS IS'' AND ANY
42
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
44
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE pfSense PROJECT OR
45
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
46
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
47
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
48
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
49
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
50
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
51
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
52
 * OF THE POSSIBILITY OF SUCH DAMAGE.
53
 */
54 a93e56c5 Matthew Grooms
55 3462a529 Matthew Grooms
/* IPsec defines */
56 62657a7f jim-p
global $ipsec_loglevels;
57 e8c516a0 Phil Davis
$ipsec_loglevels = array(
58
	"dmn" => gettext("Daemon"),
59
	"mgr" => gettext("SA Manager"),
60
	"ike" => gettext("IKE SA"),
61
	"chd" => gettext("IKE Child SA"),
62
	"job" => gettext("Job Processing"),
63
	"cfg" => gettext("Configuration backend"),
64
	"knl" => gettext("Kernel Interface"),
65
	"net" => gettext("Networking"),
66
	"asn" => gettext("ASN encoding"),
67
	"enc" => gettext("Message encoding"),
68
	"imc" => gettext("Integrity checker"),
69
	"imv" => gettext("Integrity Verifier"),
70
	"pts" => gettext("Platform Trust Service"),
71
	"tls" => gettext("TLS handler"),
72
	"esp" => gettext("IPsec traffic"),
73
	"lib" => gettext("StrongSwan Lib")
74
);
75 c6efc8fd Ermal
76 c53e411f Matt Smith
global $ipsec_log_sevs;
77
$ipsec_log_sevs = array(
78 e8c516a0 Phil Davis
	'-1' => gettext('Silent'),
79
	'0' => gettext('Audit'),
80
	'1' => gettext('Control'),
81
	'2' => gettext('Diag'),
82
	'3' => gettext('Raw'),
83
	'4' => gettext('Highest')
84 c53e411f Matt Smith
);
85
86
global $ipsec_log_cats;
87
$ipsec_log_cats = array(
88 e8c516a0 Phil Davis
	"dmn" => gettext("Daemon"),
89
	"mgr" => gettext("SA Manager"),
90
	"ike" => gettext("IKE SA"),
91
	"chd" => gettext("IKE Child SA"),
92
	"job" => gettext("Job Processing"),
93
	"cfg" => gettext("Configuration backend"),
94
	"knl" => gettext("Kernel Interface"),
95
	"net" => gettext("Networking"),
96
	"asn" => gettext("ASN encoding"),
97
	"enc" => gettext("Message encoding"),
98
	"imc" => gettext("Integrity checker"),
99
	"imv" => gettext("Integrity Verifier"),
100
	"pts" => gettext("Platform Trust Service"),
101
	"tls" => gettext("TLS handler"),
102
	"esp" => gettext("IPsec traffic"),
103
	"lib" => gettext("StrongSwan Lib")
104 c53e411f Matt Smith
);
105
106 62657a7f jim-p
global $my_identifier_list;
107 3462a529 Matthew Grooms
$my_identifier_list = array(
108 086cf944 Phil Davis
	'myaddress' => array('desc' => gettext('My IP address'), 'mobile' => true),
109
	'address' => array('desc' => gettext('IP address'), 'mobile' => true),
110
	'fqdn' => array('desc' => gettext('Distinguished name'), 'mobile' => true),
111
	'user_fqdn' => array('desc' => gettext('User distinguished name'), 'mobile' => true),
112
	'asn1dn' => array('desc' => gettext('ASN.1 distinguished Name'), 'mobile' => true),
113
	'keyid tag' => array('desc' => gettext('KeyID tag'), 'mobile' => true),
114 e8c516a0 Phil Davis
	'dyn_dns' => array('desc' => gettext('Dynamic DNS'), 'mobile' => true)
115
);
116 3462a529 Matthew Grooms
117 62657a7f jim-p
global $peer_identifier_list;
118 3462a529 Matthew Grooms
$peer_identifier_list = array(
119 b0994811 Chris Buechler
	'any' => array('desc' => gettext('Any'), 'mobile' => true),
120 086cf944 Phil Davis
	'peeraddress' => array('desc' => gettext('Peer IP address'), 'mobile' => false),
121
	'address' => array('desc' => gettext('IP address'), 'mobile' => false),
122
	'fqdn' => array('desc' => gettext('Distinguished name'), 'mobile' => true),
123
	'user_fqdn' => array('desc' => gettext('User distinguished name'), 'mobile' => true),
124
	'asn1dn' => array('desc' => gettext('ASN.1 distinguished Name'), 'mobile' => true),
125 e8c516a0 Phil Davis
	'keyid tag' => array('desc' =>gettext('KeyID tag'), 'mobile' => true)
126
);
127 3462a529 Matthew Grooms
128 62657a7f jim-p
global $ipsec_idhandling;
129 86e1846f Ermal LUÇI
$ipsec_idhandling = array(
130
	'yes' => 'YES', 'no' => 'NO', 'never' => 'NEVER', 'keep' => 'KEEP'
131 e8c516a0 Phil Davis
);
132 86e1846f Ermal LUÇI
133 62657a7f jim-p
global $p1_ealgos;
134 3462a529 Matthew Grooms
$p1_ealgos = array(
135 086cf944 Phil Davis
	'aes' => array('name' => 'AES', 'keysel' => array('lo' => 128, 'hi' => 256, 'step' => 64)),
136 76a0eecb Chris Buechler
	'aes128gcm' => array('name' => 'AES128-GCM', 'keysel' => array('lo' => 64, 'hi' => 128, 'step' => 32)),
137
	'aes192gcm' => array('name' => 'AES192-GCM', 'keysel' => array('lo' => 64, 'hi' => 128, 'step' => 32)),
138
	'aes256gcm' => array('name' => 'AES256-GCM', 'keysel' => array('lo' => 64, 'hi' => 128, 'step' => 32)),
139 086cf944 Phil Davis
	'blowfish' => array('name' => 'Blowfish', 'keysel' => array('lo' => 128, 'hi' => 256, 'step' => 64)),
140
	'3des' => array('name' => '3DES'),
141 e8c516a0 Phil Davis
	'cast128' => array('name' => 'CAST128')
142
);
143 3462a529 Matthew Grooms
144 62657a7f jim-p
global $p2_ealgos;
145 3462a529 Matthew Grooms
$p2_ealgos = array(
146 086cf944 Phil Davis
	'aes' => array('name' => 'AES', 'keysel' => array('lo' => 128, 'hi' => 256, 'step' => 64)),
147
	'aes128gcm' => array('name' => 'AES128-GCM', 'keysel' => array('lo' => 64, 'hi' => 128, 'step' => 32)),
148
	'aes192gcm' => array('name' => 'AES192-GCM', 'keysel' => array('lo' => 64, 'hi' => 128, 'step' => 32)),
149
	'aes256gcm' => array('name' => 'AES256-GCM', 'keysel' => array('lo' => 64, 'hi' => 128, 'step' => 32)),
150
	'blowfish' => array('name' => 'Blowfish', 'keysel' => array('lo' => 128, 'hi' => 256, 'step' => 64)),
151
	'3des' => array('name' => '3DES'),
152 e8c516a0 Phil Davis
	'cast128' => array('name' => 'CAST128')
153
);
154 3462a529 Matthew Grooms
155 62657a7f jim-p
global $p1_halgos;
156 3462a529 Matthew Grooms
$p1_halgos = array(
157 665340db jim-p
	'md5' => 'MD5',
158 3462a529 Matthew Grooms
	'sha1' => 'SHA1',
159 665340db jim-p
	'sha256' => 'SHA256',
160
	'sha384' => 'SHA384',
161 b0cbebeb Ermal
	'sha512' => 'SHA512',
162
	'aesxcbc' => 'AES-XCBC'
163 665340db jim-p
);
164
165 62657a7f jim-p
global $p1_dhgroups;
166 665340db jim-p
$p1_dhgroups = array(
167
	1  => '1 (768 bit)',
168
	2  => '2 (1024 bit)',
169
	5  => '5 (1536 bit)',
170
	14 => '14 (2048 bit)',
171
	15 => '15 (3072 bit)',
172
	16 => '16 (4096 bit)',
173
	17 => '17 (6144 bit)',
174 b0cbebeb Ermal
	18 => '18 (8192 bit)',
175 7a747654 Ermal LUÇI
	19 => '19 (nist ecp256)',
176
	20 => '20 (nist ecp384)',
177
	21 => '21 (nist ecp521)',
178 b0cbebeb Ermal
	22 => '22 (1024(sub 160) bit)',
179
	23 => '23 (2048(sub 224) bit)',
180 c55ec98a Bruno Thomsen
	24 => '24 (2048(sub 256) bit)',
181
	28 => '28 (brainpool ecp256)',
182
	29 => '29 (brainpool ecp384)',
183
	30 => '30 (brainpool ecp512)'
184 665340db jim-p
);
185 3462a529 Matthew Grooms
186 62657a7f jim-p
global $p2_halgos;
187 3462a529 Matthew Grooms
$p2_halgos = array(
188 665340db jim-p
	'hmac_md5' => 'MD5',
189 3462a529 Matthew Grooms
	'hmac_sha1' => 'SHA1',
190 665340db jim-p
	'hmac_sha256' => 'SHA256',
191
	'hmac_sha384' => 'SHA384',
192 b0cbebeb Ermal
	'hmac_sha512' => 'SHA512',
193
	'aesxcbc' => 'AES-XCBC'
194 665340db jim-p
);
195 3462a529 Matthew Grooms
196 62657a7f jim-p
global $p1_authentication_methods;
197 3462a529 Matthew Grooms
$p1_authentication_methods = array(
198 e8c516a0 Phil Davis
	'hybrid_rsa_server' => array('name' => gettext('Hybrid RSA + Xauth'), 'mobile' => true),
199
	'xauth_rsa_server' => array('name' => gettext('Mutual RSA + Xauth'), 'mobile' => true),
200
	'xauth_psk_server' => array('name' => gettext('Mutual PSK + Xauth'), 'mobile' => true),
201
	'eap-tls' => array('name' => gettext('EAP-TLS'), 'mobile' => true),
202
	'eap-radius' => array('name' => gettext('EAP-RADIUS'), 'mobile' => true),
203
	'eap-mschapv2' => array('name' => gettext('EAP-MSChapv2'), 'mobile' => true),
204
	'rsasig' => array('name' => gettext('Mutual RSA'), 'mobile' => false),
205
	'pre_shared_key' => array('name' => gettext('Mutual PSK'), 'mobile' => false)
206
);
207 3462a529 Matthew Grooms
208 62657a7f jim-p
global $ipsec_preshared_key_type;
209 10e2acb5 Ermal LUÇI
$ipsec_preshared_key_type = array(
210
	'PSK' => 'PSK',
211
	'EAP' => 'EAP'
212 e8c516a0 Phil Davis
);
213 10e2acb5 Ermal LUÇI
214 62657a7f jim-p
global $p2_modes;
215 4b96b367 mgrooms
$p2_modes = array(
216 e8c516a0 Phil Davis
	'tunnel' => gettext('Tunnel IPv4'),
217
	'tunnel6' => gettext('Tunnel IPv6'),
218
	'transport' => gettext('Transport')
219
);
220 4b96b367 mgrooms
221 62657a7f jim-p
global $p2_protos;
222 3462a529 Matthew Grooms
$p2_protos = array(
223
	'esp' => 'ESP',
224 e8c516a0 Phil Davis
	'ah' => 'AH'
225
);
226 3462a529 Matthew Grooms
227 62657a7f jim-p
global $p2_pfskeygroups;
228 3462a529 Matthew Grooms
$p2_pfskeygroups = array(
229 e8c516a0 Phil Davis
	0 => gettext('off'),
230
	1  => gettext('1 (768 bit)'),
231
	2  => gettext('2 (1024 bit)'),
232
	5  => gettext('5 (1536 bit)'),
233
	14 => gettext('14 (2048 bit)'),
234
	15 => gettext('15 (3072 bit)'),
235
	16 => gettext('16 (4096 bit)'),
236
	17 => gettext('17 (6144 bit)'),
237
	18 => gettext('18 (8192 bit)'),
238
	19 => gettext('19 (nist ecp256)'),
239
	20 => gettext('20 (nist ecp384)'),
240
	21 => gettext('21 (nist ecp521)'),
241
	28 => gettext('28 (brainpool ecp256)'),
242
	29 => gettext('29 (brainpool ecp384)'),
243
	30 => gettext('30 (brainpool ecp512)')
244 665340db jim-p
);
245 3462a529 Matthew Grooms
246 4e96112a Luiz Otavio O Souza
function ipsec_enabled() {
247
	global $config;
248
249 4e322e2c Phil Davis
	if (!isset($config['ipsec']) || !is_array($config['ipsec'])) {
250 4e96112a Luiz Otavio O Souza
		return false;
251 4e322e2c Phil Davis
	}
252 4e96112a Luiz Otavio O Souza
253 fef38e5a Luiz Otavio O Souza
	/* Check if we have at least one phase 1 entry. */
254 4e96112a Luiz Otavio O Souza
	if (!isset($config['ipsec']['phase1']) ||
255
	    !is_array($config['ipsec']['phase1']) ||
256
	    empty($config['ipsec']['phase1'])) {
257
		return false;
258
	}
259 fef38e5a Luiz Otavio O Souza
	/* Check if at least one phase 1 entry is enabled. */
260
	foreach ($config['ipsec']['phase1'] as $phase1) {
261 4e322e2c Phil Davis
		if (!isset($phase1['disabled'])) {
262 fef38e5a Luiz Otavio O Souza
			return true;
263 4e322e2c Phil Davis
		}
264 fef38e5a Luiz Otavio O Souza
	}
265 4e96112a Luiz Otavio O Souza
266 fef38e5a Luiz Otavio O Souza
	return false;
267 4e96112a Luiz Otavio O Souza
}
268
269 d799787e Matthew Grooms
/*
270
 * ikeid management functions
271
 */
272
273
function ipsec_ikeid_used($ikeid) {
274
	global $config;
275
276 b37a2e8c Phil Davis
	foreach ($config['ipsec']['phase1'] as $ph1ent) {
277 086cf944 Phil Davis
		if ($ikeid == $ph1ent['ikeid']) {
278 d799787e Matthew Grooms
			return true;
279 b37a2e8c Phil Davis
		}
280
	}
281 d799787e Matthew Grooms
282
	return false;
283
}
284
285
function ipsec_ikeid_next() {
286
287
	$ikeid = 1;
288 b37a2e8c Phil Davis
	while (ipsec_ikeid_used($ikeid)) {
289 d799787e Matthew Grooms
		$ikeid++;
290 b37a2e8c Phil Davis
	}
291 d799787e Matthew Grooms
292
	return $ikeid;
293
}
294
295 a93e56c5 Matthew Grooms
/*
296
 * Return phase1 local address
297
 */
298
function ipsec_get_phase1_src(& $ph1ent) {
299
300 25f6730a Pierre POMES
	if ($ph1ent['interface']) {
301 d9901ff4 Chris Buechler
		if (substr($ph1ent['interface'], 0, 4) == "_vip") {
302 2a5960b0 Luiz Otavio O Souza
			$if = $ph1ent['interface'];
303 d9901ff4 Chris Buechler
		} else {
304 2a5960b0 Luiz Otavio O Souza
			$if = get_failover_interface($ph1ent['interface']);
305 d9901ff4 Chris Buechler
		}
306
	} else {
307 924876a8 Ermal Lu?i
		$if = "wan";
308 d9901ff4 Chris Buechler
	}
309
	if ($ph1ent['protocol'] == "inet6") {
310 2a5960b0 Luiz Otavio O Souza
		$interfaceip = get_interface_ipv6($if);
311 d9901ff4 Chris Buechler
	} else {
312 2a5960b0 Luiz Otavio O Souza
		$interfaceip = get_interface_ip($if);
313 d9901ff4 Chris Buechler
	}
314 a93e56c5 Matthew Grooms
315
	return $interfaceip;
316
}
317
318 3462a529 Matthew Grooms
/*
319
 * Return phase1 local address
320
 */
321
function ipsec_get_phase1_dst(& $ph1ent) {
322 df82fae1 smos
	global $g;
323 2ffafea3 Ermal
324 b37a2e8c Phil Davis
	if (empty($ph1ent['remote-gateway'])) {
325 2f3554bb jim-p
		return false;
326 b37a2e8c Phil Davis
	}
327 3462a529 Matthew Grooms
	$rg = $ph1ent['remote-gateway'];
328 33d5cb7a smos
	if (!is_ipaddr($rg)) {
329 086cf944 Phil Davis
		if (!platform_booting()) {
330 33d5cb7a smos
			return resolve_retry($rg);
331 b37a2e8c Phil Davis
		}
332 33d5cb7a smos
	}
333 b37a2e8c Phil Davis
	if (!is_ipaddr($rg)) {
334 0af7398a Matthew Grooms
		return false;
335 b37a2e8c Phil Davis
	}
336 0af7398a Matthew Grooms
337 3462a529 Matthew Grooms
	return $rg;
338
}
339
340 a93e56c5 Matthew Grooms
/*
341
 * Return phase2 idinfo in cidr format
342
 */
343 2ffafea3 Ermal
function ipsec_idinfo_to_cidr(& $idinfo, $addrbits = false, $mode = "") {
344 a93e56c5 Matthew Grooms
	global $config;
345
346 2ffafea3 Ermal
	switch ($idinfo['type']) {
347 a93e56c5 Matthew Grooms
		case "address":
348 98790f61 Seth Mos
			if ($addrbits) {
349 b37a2e8c Phil Davis
				if ($mode == "tunnel6") {
350 98790f61 Seth Mos
					return $idinfo['address']."/128";
351 b37a2e8c Phil Davis
				} else {
352 98790f61 Seth Mos
					return $idinfo['address']."/32";
353 b37a2e8c Phil Davis
				}
354 086cf944 Phil Davis
			} else {
355 a93e56c5 Matthew Grooms
				return $idinfo['address'];
356 086cf944 Phil Davis
			}
357 2ffafea3 Ermal
			break; /* NOTREACHED */
358 a93e56c5 Matthew Grooms
		case "network":
359 2ffafea3 Ermal
			return "{$idinfo['address']}/{$idinfo['netbits']}";
360
			break; /* NOTREACHED */
361 63017a73 Ermal Lu?i
		case "none":
362 3462a529 Matthew Grooms
		case "mobile":
363 00b56e04 Ermal LUÇI
			return '0.0.0.0/0';
364 2ffafea3 Ermal
			break; /* NOTREACHED */
365 a55e9c70 Ermal Lu?i
		default:
366 b37a2e8c Phil Davis
			if (empty($mode) && !empty($idinfo['mode'])) {
367 2ffafea3 Ermal
				$mode = $idinfo['mode'];
368 b37a2e8c Phil Davis
			}
369 2ffafea3 Ermal
370
			if ($mode == "tunnel6") {
371 98790f61 Seth Mos
				$address = get_interface_ipv6($idinfo['type']);
372
				$netbits = get_interface_subnetv6($idinfo['type']);
373 086cf944 Phil Davis
				$address = gen_subnetv6($address, $netbits);
374 2ffafea3 Ermal
				return "{$address}/{$netbits}";
375 98790f61 Seth Mos
			} else {
376
				$address = get_interface_ip($idinfo['type']);
377
				$netbits = get_interface_subnet($idinfo['type']);
378 086cf944 Phil Davis
				$address = gen_subnet($address, $netbits);
379 2ffafea3 Ermal
				return "{$address}/{$netbits}";
380 98790f61 Seth Mos
			}
381 2ffafea3 Ermal
			break; /* NOTREACHED */
382 98790f61 Seth Mos
	}
383 a93e56c5 Matthew Grooms
}
384
385
/*
386
 * Return phase2 idinfo in address/netmask format
387
 */
388 086cf944 Phil Davis
function ipsec_idinfo_to_subnet(& $idinfo, $addrbits = false) {
389 a93e56c5 Matthew Grooms
	global $config;
390
391 2ffafea3 Ermal
	switch ($idinfo['type']) {
392 a93e56c5 Matthew Grooms
		case "address":
393 98790f61 Seth Mos
			if ($addrbits) {
394 b37a2e8c Phil Davis
				if ($idinfo['mode'] == "tunnel6") {
395 98790f61 Seth Mos
					return $idinfo['address']."/128";
396 b37a2e8c Phil Davis
				} else {
397 98790f61 Seth Mos
					return $idinfo['address']."/255.255.255.255";
398 b37a2e8c Phil Davis
				}
399 086cf944 Phil Davis
			} else {
400 a93e56c5 Matthew Grooms
				return $idinfo['address'];
401 086cf944 Phil Davis
			}
402 2ffafea3 Ermal
			break; /* NOTREACHED */
403 63017a73 Ermal Lu?i
		case "none":
404 a93e56c5 Matthew Grooms
		case "network":
405
			return $idinfo['address']."/".gen_subnet_mask($idinfo['netbits']);
406 2ffafea3 Ermal
			break; /* NOTREACHED */
407 3462a529 Matthew Grooms
		case "mobile":
408
			return "0.0.0.0/0";
409 2ffafea3 Ermal
			break; /* NOTREACHED */
410 63017a73 Ermal Lu?i
		default:
411 2ffafea3 Ermal
			if ($idinfo['mode'] == "tunnel6") {
412 98790f61 Seth Mos
				$address = get_interface_ipv6($idinfo['type']);
413
				$netbits = get_interface_subnetv6($idinfo['type']);
414 086cf944 Phil Davis
				$address = gen_subnetv6($address, $netbits);
415 98790f61 Seth Mos
				return $address."/".$netbits;
416
			} else {
417
				$address = get_interface_ip($idinfo['type']);
418
				$netbits = get_interface_subnet($idinfo['type']);
419 086cf944 Phil Davis
				$address = gen_subnet($address, $netbits);
420 98790f61 Seth Mos
				return $address."/".$netbits;
421
			}
422 2ffafea3 Ermal
			break; /* NOTREACHED */
423 98790f61 Seth Mos
	}
424 a93e56c5 Matthew Grooms
}
425
426
/*
427
 *  Return phase2 idinfo in text format
428
 */
429
function ipsec_idinfo_to_text(& $idinfo) {
430 2ffafea3 Ermal
	global $config;
431 a93e56c5 Matthew Grooms
432 2ffafea3 Ermal
	switch ($idinfo['type']) {
433 b37a2e8c Phil Davis
		case "address":
434
			return $idinfo['address'];
435
			break; /* NOTREACHED */
436
		case "network":
437
			return $idinfo['address']."/".$idinfo['netbits'];
438
			break; /* NOTREACHED */
439
		case "mobile":
440
			return gettext("Mobile Client");
441
			break; /* NOTREACHED */
442
		case "none":
443
			return gettext("None");
444
			break; /* NOTREACHED */
445
		default:
446
			if (!empty($config['interfaces'][$idinfo['type']])) {
447
				return convert_friendly_interface_to_friendly_descr($idinfo['type']);
448
			} else {
449
				return strtoupper($idinfo['type']);
450
			}
451
			break; /* NOTREACHED */
452 2ffafea3 Ermal
	}
453 a93e56c5 Matthew Grooms
}
454
455
/*
456
 * Return phase1 association for phase2
457
 */
458 086cf944 Phil Davis
function ipsec_lookup_phase1(& $ph2ent, & $ph1ent) {
459 2ffafea3 Ermal
	global $config;
460
461 b37a2e8c Phil Davis
	if (!is_array($config['ipsec'])) {
462 fe12d7ea Ermal
		return false;
463 b37a2e8c Phil Davis
	}
464
	if (!is_array($config['ipsec']['phase1'])) {
465 fe12d7ea Ermal
		return false;
466 b37a2e8c Phil Davis
	}
467
	if (empty($config['ipsec']['phase1'])) {
468 fe12d7ea Ermal
		return false;
469 b37a2e8c Phil Davis
	}
470 2ffafea3 Ermal
471
	foreach ($config['ipsec']['phase1'] as $ph1tmp) {
472 b37a2e8c Phil Davis
		if ($ph1tmp['ikeid'] == $ph2ent['ikeid']) {
473
			$ph1ent = $ph1tmp;
474
			return $ph1ent;
475
		}
476 2ffafea3 Ermal
	}
477
478
	return false;
479 a93e56c5 Matthew Grooms
}
480
481
/*
482
 * Check phase1 communications status
483
 */
484 ed6e93ea Chris Buechler
function ipsec_phase1_status(&$ipsec_status, $ikeid) {
485 a93e56c5 Matthew Grooms
486 39f93e00 Ermal
	foreach ($ipsec_status as $ike) {
487 17318511 Ermal LUÇI
		if ($ike['id'] == $ikeid) {
488 b37a2e8c Phil Davis
			if ($ike['status'] == 'established') {
489 17318511 Ermal LUÇI
				return true;
490 b37a2e8c Phil Davis
			}
491 17318511 Ermal LUÇI
		}
492 fe12d7ea Ermal
	}
493 a93e56c5 Matthew Grooms
494
	return false;
495
}
496
497
/*
498
 * Check phase2 communications status
499
 */
500 ed6e93ea Chris Buechler
function ipsec_phase2_status(&$ipsec_status, &$phase2) {
501 a93e56c5 Matthew Grooms
502 086cf944 Phil Davis
	if (ipsec_lookup_phase1($ph2ent, $ph1ent)) {
503 fe12d7ea Ermal
		return ipsec_phase1_status($ipsec_status, $ph1ent['ikeid']);
504 b37a2e8c Phil Davis
	}
505 a93e56c5 Matthew Grooms
506
	return false;
507
}
508
509 1dade399 Renato Botelho
/*
510
 * Wrapper to call pfSense_ipsec_list_sa() when IPsec is enabled
511
 */
512
function ipsec_list_sa() {
513
514 4e322e2c Phil Davis
	if (ipsec_enabled()) {
515 1dade399 Renato Botelho
		return pfSense_ipsec_list_sa();
516 4e322e2c Phil Davis
	}
517 1dade399 Renato Botelho
518
	return array();
519
}
520
521 e1c34c69 Renato Botelho
/*
522
 * Return dump of SPD table
523
 */
524
function ipsec_dump_spd() {
525
	$fd = @popen("/sbin/setkey -DP", "r");
526
	$spd = array();
527
	if ($fd) {
528
		while (!feof($fd)) {
529
			$line = chop(fgets($fd));
530
			if (!$line) {
531
				continue;
532
			}
533
			if ($line == "No SPD entries.") {
534
				break;
535
			}
536
			if ($line[0] != "\t") {
537
				if (is_array($cursp)) {
538
					$spd[] = $cursp;
539
				}
540
				$cursp = array();
541
				$linea = explode(" ", $line);
542
				$cursp['srcid'] = substr($linea[0], 0, strpos($linea[0], "["));
543
				$cursp['dstid'] = substr($linea[1], 0, strpos($linea[1], "["));
544
				$i = 0;
545
			} else if (is_array($cursp)) {
546
				$line = trim($line, "\t\r\n ");
547
				$linea = explode(" ", $line);
548
				switch ($i) {
549
					case 1:
550
						if ($linea[1] == "none")	/* don't show default anti-lockout rule */ {
551
							unset($cursp);
552
						} else {
553
							$cursp['dir'] = $linea[0];
554
						}
555
						break;
556
					case 2:
557
						$upperspec = explode("/", $linea[0]);
558
						$cursp['proto'] = $upperspec[0];
559
						list($cursp['src'], $cursp['dst']) = explode("-", $upperspec[2]);
560
						$cursp['reqid'] = substr($upperspec[3], strpos($upperspec[3], "#")+1);
561
						break;
562
				}
563
			}
564
			$i++;
565
		}
566
		if (is_array($cursp) && count($cursp)) {
567
			$spd[] = $cursp;
568
		}
569
		pclose($fd);
570
	}
571
572
	return $spd;
573
}
574
575 a93e56c5 Matthew Grooms
/*
576
 * Return dump of SAD table
577
 */
578 086cf944 Phil Davis
function ipsec_dump_sad() {
579 30c591d6 Ermal
	$fd = @popen("/sbin/setkey -D", "r");
580 a93e56c5 Matthew Grooms
	$sad = array();
581
	if ($fd) {
582
		while (!feof($fd)) {
583
			$line = chop(fgets($fd));
584 b37a2e8c Phil Davis
			if (!$line || $line[0] == " ") {
585 a93e56c5 Matthew Grooms
				continue;
586 b37a2e8c Phil Davis
			}
587
			if ($line == "No SAD entries.") {
588 a93e56c5 Matthew Grooms
				break;
589 b37a2e8c Phil Davis
			}
590
			if ($line[0] != "\t") {
591
				if (is_array($cursa)) {
592 a93e56c5 Matthew Grooms
					$sad[] = $cursa;
593 b37a2e8c Phil Davis
				}
594 a93e56c5 Matthew Grooms
				$cursa = array();
595 086cf944 Phil Davis
				list($cursa['src'], $cursa['dst']) = explode(" ", $line);
596 b37a2e8c Phil Davis
			} else {
597 648661c5 Ermal LUÇI
				$line = trim($line, "\t\n\r ");
598
				$linea = explode(" ", $line);
599
				foreach ($linea as $idx => $linee) {
600 b37a2e8c Phil Davis
					if ($linee == 'esp' || $linee == 'ah' || $linee[0] == '#') {
601 648661c5 Ermal LUÇI
						$cursa['proto'] = $linee;
602 b37a2e8c Phil Davis
					} else if (substr($linee, 0, 3) == 'spi') {
603 648661c5 Ermal LUÇI
						$cursa['spi'] = substr($linee, strpos($linee, 'x') + 1, -1);
604 b37a2e8c Phil Davis
					} else if (substr($linee, 0, 5) == 'reqid') {
605 648661c5 Ermal LUÇI
						$cursa['reqid'] = substr($linee, strpos($linee, 'x') + 1, -1);
606 b37a2e8c Phil Davis
					} else if (substr($linee, 0, 2) == 'E:') {
607 648661c5 Ermal LUÇI
						$cursa['ealgo'] = $linea[$idx + 1];
608 a93e56c5 Matthew Grooms
						break;
609 648661c5 Ermal LUÇI
					} else if (substr($linee, 0, 2) == 'A:') {
610
						$cursa['aalgo'] = $linea[$idx + 1];
611 a93e56c5 Matthew Grooms
						break;
612 648661c5 Ermal LUÇI
					} else if (substr($linee, 0, 8) == 'current:') {
613
						$cursa['data'] = substr($linea[$idx + 1], 0, strpos($linea[$idx + 1], 'bytes') - 1) . ' B';
614 f451ea09 jim-p
						break;
615 648661c5 Ermal LUÇI
					}
616 a93e56c5 Matthew Grooms
				}
617
			}
618
		}
619 b37a2e8c Phil Davis
		if (is_array($cursa) && count($cursa)) {
620 a93e56c5 Matthew Grooms
			$sad[] = $cursa;
621 b37a2e8c Phil Davis
		}
622 a93e56c5 Matthew Grooms
		pclose($fd);
623
	}
624
625
	return $sad;
626
}
627
628 6e0b68bf jim-p
/*
629
 * Return dump of mobile user list
630
 */
631
function ipsec_dump_mobile() {
632 796b7651 Renato Botelho
	global $g;
633 ed5fc757 Ermal
634 796b7651 Renato Botelho
	$_gb = exec("/usr/local/sbin/ipsec leases 2>/dev/null", $output, $rc);
635 6e0b68bf jim-p
636 796b7651 Renato Botelho
	if ($rc != 0) {
637 276efd64 Chris Buechler
		log_error(gettext("Unable to find IPsec daemon leases file. Could not display mobile user stats!"));
638 7ab6ad70 Ermal
		return array();
639 6e0b68bf jim-p
	}
640
641 796b7651 Renato Botelho
	$response = array();
642
	$id = -1;
643
644
	/* Leases in pool '10.7.200.0/24', usage: 1/254, 1 online */
645
	$lease_regex='/^Leases *in *pool *\'(?P<name>.+)\', *usage: *(?P<usage>\d+)\/(?P<size>\d+), *(?P<online>\d+) *online/';
646
	/* 10.7.200.1   online   'jimp' */
647
	$pool_regex='/\s*(?P<host>[\d\.]+)\s+(?P<status>online|offline)\s+\'(?P<id>.*)\'/';
648
	/* no matching leases found */
649
	$nopool_regex='/no *matching *leases *found/';
650
651
	$lease=false;
652
	foreach ($output as $line) {
653
		if (preg_match($lease_regex, $line, $matches)) {
654
			$id++;
655
			$response['pool'][$id] = array(
656
			    'name'   => $matches['name'],
657
			    'usage'  => $matches['usage'],
658
			    'size'   => $matches['size'],
659
			    'online' => $matches['online'],
660
			);
661
			$lease=true;
662
		} else if ($lease) {
663
			if (preg_match($nopool_regex, $line)) {
664
				$response['pool'][$id]['lease'][] = array();
665
				$lease=false;
666
			} else if (preg_match($pool_regex, $line, $matches)) {
667
				$response['pool'][$id]['lease'][] = array(
668
				    'host'   => $matches['host'],
669
				    'status' => $matches['status'],
670
				    'id'     => $matches['id']
671
				);
672
			}
673
		}
674 f3e15492 Renato Botelho
	}
675
676 796b7651 Renato Botelho
	unset($_gb, $lease, $output, $rc, $id, $lease_regex, $pool_regex,
677
	    $nopool_regex);
678 7ab6ad70 Ermal
679
	return $response;
680 6e0b68bf jim-p
}
681
682 958420c5 jim-p
function ipsec_mobilekey_sort() {
683
	global $config;
684
685
	function mobilekeycmp($a, $b) {
686
		return strcmp($a['ident'][0], $b['ident'][0]);
687
	}
688
689
	usort($config['ipsec']['mobilekey'], "mobilekeycmp");
690
}
691
692 8f5c3d8d Pierre POMES
function ipsec_get_number_of_phase2($ikeid) {
693
	global $config;
694 b37a2e8c Phil Davis
	$a_phase2 = $config['ipsec']['phase2'];
695 8f5c3d8d Pierre POMES
696 6c07db48 Phil Davis
	$nbph2 = 0;
697 8f5c3d8d Pierre POMES
698 b37a2e8c Phil Davis
	if (is_array($a_phase2) && count($a_phase2)) {
699
		foreach ($a_phase2 as $ph2tmp) {
700
			if ($ph2tmp['ikeid'] == $ikeid) {
701 8f5c3d8d Pierre POMES
				$nbph2++;
702
			}
703
		}
704
	}
705
706
	return $nbph2;
707
}
708
709 859a5304 Renato Botelho
function ipsec_get_descr($ikeid) {
710
	global $config;
711
712
	if (!isset($config['ipsec']['phase1']) ||
713 b37a2e8c Phil Davis
	    !is_array($config['ipsec']['phase1'])) {
714 c607f306 Ermal LUÇI
		return '';
715 b37a2e8c Phil Davis
	}
716 859a5304 Renato Botelho
717 c607f306 Ermal LUÇI
	foreach ($config['ipsec']['phase1'] as $p1) {
718 859a5304 Renato Botelho
		if ($p1['ikeid'] == $ikeid) {
719 c607f306 Ermal LUÇI
			return $p1['descr'];
720 859a5304 Renato Botelho
		}
721
	}
722
723 c607f306 Ermal LUÇI
	return '';
724 859a5304 Renato Botelho
}
725
726 483c3b5b Ermal LUÇI
function ipsec_get_phase1($ikeid) {
727 b37a2e8c Phil Davis
		global $config;
728
729
		if (!isset($config['ipsec']['phase1']) ||
730
		    !is_array($config['ipsec']['phase1'])) {
731
			return '';
732
		}
733
734
		$a_phase1 = $config['ipsec']['phase1'];
735
		foreach ($a_phase1 as $p1) {
736
			if ($p1['ikeid'] == $ikeid) {
737
				return $p1;
738
			}
739
		}
740
		unset($a_phase1);
741 483c3b5b Ermal LUÇI
}
742
743 3ec026a4 jim-p
function ipsec_fixup_ip($ipaddr) {
744 b37a2e8c Phil Davis
	if (is_ipaddrv6($ipaddr) || is_subnetv6($ipaddr)) {
745 3ec026a4 jim-p
		return Net_IPv6::compress(Net_IPv6::uncompress($ipaddr));
746 b37a2e8c Phil Davis
	} else {
747 3ec026a4 jim-p
		return $ipaddr;
748 b37a2e8c Phil Davis
	}
749 3ec026a4 jim-p
}
750
751 95589abd jim-p
function ipsec_find_id(& $ph1ent, $side = "local", $rgmap = array()) {
752
	if ($side == "local") {
753
		$id_type = $ph1ent['myid_type'];
754
		$id_data = $ph1ent['myid_data'];
755
756
		$addr = ipsec_get_phase1_src($ph1ent);
757 b37a2e8c Phil Davis
		if (!$addr) {
758 95589abd jim-p
			return array();
759 b37a2e8c Phil Davis
		}
760 664aef0b Chris Buechler
	} elseif ($side == "peer") {
761 95589abd jim-p
		$id_type = $ph1ent['peerid_type'];
762
		$id_data = $ph1ent['peerid_data'];
763
764 b37a2e8c Phil Davis
		if (isset($ph1ent['mobile'])) {
765 95589abd jim-p
			$addr = "%any";
766 b37a2e8c Phil Davis
		} else {
767 95589abd jim-p
			$addr = $ph1ent['remote-gateway'];
768 b37a2e8c Phil Davis
		}
769
	} else {
770 95589abd jim-p
		return array();
771 b37a2e8c Phil Davis
	}
772 95589abd jim-p
773
774
	$thisid_type = $id_type;
775
	switch ($thisid_type) {
776 b37a2e8c Phil Davis
		case 'myaddress':
777
			$thisid_type = 'address';
778
			$thisid_data = $addr;
779
			break;
780
		case 'dyn_dns':
781
			$thisid_type = 'dns';
782
			$thisid_data = $id_data;
783
			break;
784
		case 'peeraddress':
785
			$thisid_type = 'address';
786
			$thisid_data = $rgmap[$ph1ent['remote-gateway']];
787
			break;
788
		case 'address':
789
			$thisid_data = $id_data;
790
			break;
791
		case 'fqdn':
792
			$thisid_data = "{$id_data}";
793
			break;
794
		case 'keyid tag':
795
			$thisid_type = 'keyid';
796 10439116 Bruno Thomsen
			$thisid_data = "{$id_data}";
797 b37a2e8c Phil Davis
			break;
798
		case 'user_fqdn':
799
			$thisid_type = 'userfqdn';
800
			$thisid_data = "{$id_data}";
801
			break;
802
		case 'asn1dn':
803
			$thisid_data = $id_data;
804
			break;
805 95589abd jim-p
	}
806
	return array($thisid_type, $thisid_data);
807
}
808 060c3ac0 Renato Botelho
809
function ipsec_fixup_network($network) {
810 b37a2e8c Phil Davis
	if (substr($network, -3) == '|/0') {
811 060c3ac0 Renato Botelho
		$result = substr($network, 0, -3);
812 b37a2e8c Phil Davis
	} else {
813 060c3ac0 Renato Botelho
		$tmp = explode('|', $network);
814 b37a2e8c Phil Davis
		if (isset($tmp[1])) {
815 060c3ac0 Renato Botelho
			$result = $tmp[1];
816 b37a2e8c Phil Davis
		} else {
817 060c3ac0 Renato Botelho
			$result = $tmp[0];
818 b37a2e8c Phil Davis
		}
819 060c3ac0 Renato Botelho
		unset($tmp);
820
	}
821
822
	return $result;
823
}
824
825 1fe208ec Ermal LUÇI
function ipsec_new_reqid() {
826
	global $config;
827
828 b37a2e8c Phil Davis
	if (!is_array($config['ipsec']) || !is_array($config['ipsec']['phase2'])) {
829 1fe208ec Ermal LUÇI
		return;
830 b37a2e8c Phil Davis
	}
831 1fe208ec Ermal LUÇI
832
	$ipsecreqid = lock('ipsecreqids', LOCK_EX);
833
	$keyids = array();
834
	$keyid = 1;
835 b37a2e8c Phil Davis
	foreach ($config['ipsec']['phase2'] as $ph2) {
836 1fe208ec Ermal LUÇI
		$keyids[$ph2['reqid']] = $ph2['reqid'];
837 b37a2e8c Phil Davis
	}
838 1fe208ec Ermal LUÇI
839
	for ($i = 1; $i < 16000; $i++) {
840
		if (!isset($keyids[$i])) {
841
			$keyid = $i;
842
			break;
843
		}
844
	}
845
	unlock($ipsecreqid);
846
847
	return $keyid;
848
}
849
850 8f5c3d8d Pierre POMES
?>