Project

General

Profile

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