Project

General

Profile

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