Project

General

Profile

Download (17.2 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
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/setkey
33
	pfSense_MODULE:	ipsec
34
35 a93e56c5 Matthew Grooms
*/
36
37 3462a529 Matthew Grooms
/* IPsec defines */
38 c6efc8fd Ermal
$ipsec_loglevels = array("dmn" => "Daemon", "mgr" => "SA Manager", "ike" => "IKE SA", "chd" => "IKE Child SA",
39
	"job" => "Job Processing", "cfg" => "Configuration backend", "knl" => "Kernel Interface",
40
	"net" => "Networking", "asn" => "ASN encoding", "enc" => "Message encoding",
41
	"imc" => "Integrity checker", "imv" => "Integrity Verifier", "pts" => "Platform Trust Service",
42
	"tls" => "TLS handler", "app" => "Not daemon", "esp" => "IPSec traffic", "lib" => "StrongSWAN Lib");
43
44 3462a529 Matthew Grooms
$my_identifier_list = array(
45 b1fd7536 Carlos Eduardo Ramos
	'myaddress' => array( 'desc' => gettext('My IP address'), 'mobile' => true ),
46
	'address' => array( 'desc' => gettext('IP address'), 'mobile' => true ),
47
	'fqdn' => array( 'desc' => gettext('Distinguished name'), 'mobile' => true ),
48
	'user_fqdn' => array( 'desc' => gettext('User distinguished name'), 'mobile' => true ),
49
	'asn1dn' => array( 'desc' => gettext('ASN.1 distinguished Name'), 'mobile' => true ),
50
	'keyid tag' => array( 'desc' => gettext('KeyID tag'), 'mobile' => true ),
51
	'dyn_dns' => array( 'desc' => gettext('Dynamic DNS'), 'mobile' => true ));
52 3462a529 Matthew Grooms
53
$peer_identifier_list = array(
54 b1fd7536 Carlos Eduardo Ramos
	'peeraddress' => array( 'desc' => gettext('Peer IP address'), 'mobile' => false ),
55
	'address' => array( 'desc' => gettext('IP address'), 'mobile' => false ),
56
	'fqdn' => array( 'desc' => gettext('Distinguished name'), 'mobile' => true ),
57
	'user_fqdn' => array( 'desc' => gettext('User distinguished name'), 'mobile' => true ),
58
	'asn1dn' => array( 'desc' => gettext('ASN.1 distinguished Name'), 'mobile' => true ),
59
	'keyid tag' => array( 'desc' =>gettext('KeyID tag'), 'mobile' => true ));
60 3462a529 Matthew Grooms
61
$p1_ealgos = array(
62
	'aes' => array( 'name' => 'AES', 'keysel' => array( 'lo' => 128, 'hi' => 256, 'step' => 64 ) ),
63 9601df8a Ermal
	'blowfish' => array( 'name' => 'Blowfish', 'keysel' => array( 'lo' => 128, 'hi' => 256, 'step' => 64 ) ),
64 3462a529 Matthew Grooms
	'3des' => array( 'name' => '3DES' ),
65
	'cast128' => array( 'name' => 'CAST128' ),
66
	'des' => array( 'name' => 'DES' ));
67
68
$p2_ealgos = array(
69
	'aes' => array( 'name' => 'AES', 'keysel' => array( 'lo' => 128, 'hi' => 256, 'step' => 64 ) ),
70 d623693c Ermal
	'blowfish' => array( 'name' => 'Blowfish', 'keysel' => array( 'lo' => 128, 'hi' => 256, 'step' => 64 ) ),
71 3462a529 Matthew Grooms
	'3des' => array( 'name' => '3DES' ),
72
	'cast128' => array( 'name' => 'CAST128' ),
73
	'des' => array( 'name' => 'DES' ));
74
75
$p1_halgos = array(
76 665340db jim-p
	'md5' => 'MD5',
77 3462a529 Matthew Grooms
	'sha1' => 'SHA1',
78 665340db jim-p
	'sha256' => 'SHA256',
79
	'sha384' => 'SHA384',
80
	'sha512' => 'SHA512'
81
);
82
83
$p1_dhgroups = array(
84
	1  => '1 (768 bit)',
85
	2  => '2 (1024 bit)',
86
	5  => '5 (1536 bit)',
87
	14 => '14 (2048 bit)',
88
	15 => '15 (3072 bit)',
89
	16 => '16 (4096 bit)',
90
	17 => '17 (6144 bit)',
91
	18 => '18 (8192 bit)'
92
);
93 3462a529 Matthew Grooms
94
$p2_halgos = array(
95 665340db jim-p
	'hmac_md5' => 'MD5',
96 3462a529 Matthew Grooms
	'hmac_sha1' => 'SHA1',
97 665340db jim-p
	'hmac_sha256' => 'SHA256',
98
	'hmac_sha384' => 'SHA384',
99
	'hmac_sha512' => 'SHA512'
100
);
101 3462a529 Matthew Grooms
102
$p1_authentication_methods = array(
103
	'hybrid_rsa_server' => array( 'name' => 'Hybrid RSA + Xauth', 'mobile' => true ),
104 1703e5c5 sullrich
	'xauth_rsa_server' => array( 'name' => 'Mutual RSA + Xauth', 'mobile' => true ),
105
	'xauth_psk_server' => array( 'name' => 'Mutual PSK + Xauth', 'mobile' => true ),
106 3462a529 Matthew Grooms
	'rsasig' => array( 'name' => 'Mutual RSA', 'mobile' => false ),
107
	'pre_shared_key' => array( 'name' => 'Mutual PSK', 'mobile' => false ) );
108
109 4b96b367 mgrooms
$p2_modes = array(
110 98790f61 Seth Mos
	'tunnel' => 'Tunnel IPv4',
111
	'tunnel6' => 'Tunnel IPv6',
112 4b96b367 mgrooms
	'transport' => 'Transport');
113
114 3462a529 Matthew Grooms
$p2_protos = array(
115
	'esp' => 'ESP',
116
	'ah' => 'AH');
117
118
$p2_pfskeygroups = array(
119 665340db jim-p
	0 => 'off',
120
	1  => '1 (768 bit)',
121
	2  => '2 (1024 bit)',
122
	5  => '5 (1536 bit)',
123
	14 => '14 (2048 bit)',
124
	15 => '15 (3072 bit)',
125
	16 => '16 (4096 bit)',
126
	17 => '17 (6144 bit)',
127
	18 => '18 (8192 bit)'
128
);
129 3462a529 Matthew Grooms
130 d799787e Matthew Grooms
/*
131
 * ikeid management functions
132
 */
133
134
function ipsec_ikeid_used($ikeid) {
135
	global $config;
136
137
	foreach ($config['ipsec']['phase1'] as $ph1ent)
138
		if( $ikeid == $ph1ent['ikeid'] )
139
			return true;
140
141
	return false;
142
}
143
144
function ipsec_ikeid_next() {
145
146
	$ikeid = 1;
147
	while(ipsec_ikeid_used($ikeid))
148
		$ikeid++;
149
150
	return $ikeid;
151
}
152
153 a93e56c5 Matthew Grooms
/*
154
 * Return phase1 local address
155
 */
156
function ipsec_get_phase1_src(& $ph1ent) {
157
158 25f6730a Pierre POMES
	if ($ph1ent['interface']) {
159
		if (!is_ipaddr($ph1ent['interface'])) {
160 909de400 Ermal
			if ($ph1ent['protocol'] == "inet6") { 
161
				$if = get_failover_interface($ph1ent['interface'], "inet6");
162 e79b24ab Seth Mos
				$interfaceip = get_interface_ipv6($if);
163
			} else {
164 909de400 Ermal
				$if = get_failover_interface($ph1ent['interface']);
165 e79b24ab Seth Mos
				$interfaceip = get_interface_ip($if);
166
			}
167 25f6730a Pierre POMES
		} else {
168
			$interfaceip=$ph1ent['interface'];
169
		}
170 e79b24ab Seth Mos
	} else {
171 924876a8 Ermal Lu?i
		$if = "wan";
172 909de400 Ermal
		if ($ph1ent['protocol'] == "inet6")
173 e79b24ab Seth Mos
			$interfaceip = get_interface_ipv6($if);
174 909de400 Ermal
		else
175 e79b24ab Seth Mos
			$interfaceip = get_interface_ip($if);
176 25f6730a Pierre POMES
	}
177 a93e56c5 Matthew Grooms
178
	return $interfaceip;
179
}
180
181 3462a529 Matthew Grooms
/*
182
 * Return phase1 local address
183
 */
184
function ipsec_get_phase1_dst(& $ph1ent) {
185 df82fae1 smos
	global $g;
186 2ffafea3 Ermal
187 a6222c03 jim-p
	if (empty($ph1ent['remote-gateway']))
188 2f3554bb jim-p
		return false;
189 3462a529 Matthew Grooms
	$rg = $ph1ent['remote-gateway'];
190 33d5cb7a smos
	if (!is_ipaddr($rg)) {
191
		if(! $g['booting'])
192
			return resolve_retry($rg);
193
	}
194 0af7398a Matthew Grooms
	if(!is_ipaddr($rg))
195
		return false;
196
197 3462a529 Matthew Grooms
	return $rg;
198
}
199
200 a93e56c5 Matthew Grooms
/*
201
 * Return phase2 idinfo in cidr format
202
 */
203 2ffafea3 Ermal
function ipsec_idinfo_to_cidr(& $idinfo, $addrbits = false, $mode = "") {
204 a93e56c5 Matthew Grooms
	global $config;
205
206 2ffafea3 Ermal
	switch ($idinfo['type']) {
207 a93e56c5 Matthew Grooms
		case "address":
208 98790f61 Seth Mos
			if ($addrbits) {
209 2ffafea3 Ermal
				if ($mode == "tunnel6")
210 98790f61 Seth Mos
					return $idinfo['address']."/128";
211 2ffafea3 Ermal
				else
212 98790f61 Seth Mos
					return $idinfo['address']."/32";
213 2ffafea3 Ermal
			} else
214 a93e56c5 Matthew Grooms
				return $idinfo['address'];
215 2ffafea3 Ermal
			break; /* NOTREACHED */
216 a93e56c5 Matthew Grooms
		case "network":
217 2ffafea3 Ermal
			return "{$idinfo['address']}/{$idinfo['netbits']}";
218
			break; /* NOTREACHED */
219 63017a73 Ermal Lu?i
		case "none":
220 3462a529 Matthew Grooms
		case "mobile":
221
			return "0.0.0.0/0";
222 2ffafea3 Ermal
			break; /* NOTREACHED */
223 a55e9c70 Ermal Lu?i
		default:
224 2ffafea3 Ermal
			if (empty($mode) && !empty($idinfo['mode']))
225
				$mode = $idinfo['mode'];
226
227
			if ($mode == "tunnel6") {
228 98790f61 Seth Mos
				$address = get_interface_ipv6($idinfo['type']);
229
				$netbits = get_interface_subnetv6($idinfo['type']);
230
				$address = gen_subnetv6($address,$netbits);
231 2ffafea3 Ermal
				return "{$address}/{$netbits}";
232 98790f61 Seth Mos
			} else {
233
				$address = get_interface_ip($idinfo['type']);
234
				$netbits = get_interface_subnet($idinfo['type']);
235
				$address = gen_subnet($address,$netbits);
236 2ffafea3 Ermal
				return "{$address}/{$netbits}";
237 98790f61 Seth Mos
			}
238 2ffafea3 Ermal
			break; /* NOTREACHED */
239 98790f61 Seth Mos
	}
240 a93e56c5 Matthew Grooms
}
241
242
/*
243
 * Return phase2 idinfo in address/netmask format
244
 */
245
function ipsec_idinfo_to_subnet(& $idinfo,$addrbits = false) {
246
	global $config;
247
248 2ffafea3 Ermal
	switch ($idinfo['type']) {
249 a93e56c5 Matthew Grooms
		case "address":
250 98790f61 Seth Mos
			if ($addrbits) {
251 2ffafea3 Ermal
				if ($idinfo['mode'] == "tunnel6")
252 98790f61 Seth Mos
					return $idinfo['address']."/128";
253 2ffafea3 Ermal
				else
254 98790f61 Seth Mos
					return $idinfo['address']."/255.255.255.255";
255 2ffafea3 Ermal
			} else
256 a93e56c5 Matthew Grooms
				return $idinfo['address'];
257 2ffafea3 Ermal
			break; /* NOTREACHED */
258 63017a73 Ermal Lu?i
		case "none":
259 a93e56c5 Matthew Grooms
		case "network":
260
			return $idinfo['address']."/".gen_subnet_mask($idinfo['netbits']);
261 2ffafea3 Ermal
			break; /* NOTREACHED */
262 3462a529 Matthew Grooms
		case "mobile":
263
			return "0.0.0.0/0";
264 2ffafea3 Ermal
			break; /* NOTREACHED */
265 63017a73 Ermal Lu?i
		default:
266 2ffafea3 Ermal
			if ($idinfo['mode'] == "tunnel6") {
267 98790f61 Seth Mos
				$address = get_interface_ipv6($idinfo['type']);
268
				$netbits = get_interface_subnetv6($idinfo['type']);
269
				$address = gen_subnetv6($address,$netbits);
270
				return $address."/".$netbits;
271
			} else {
272
				$address = get_interface_ip($idinfo['type']);
273
				$netbits = get_interface_subnet($idinfo['type']);
274
				$address = gen_subnet($address,$netbits);
275
				return $address."/".$netbits;
276
			}
277 2ffafea3 Ermal
			break; /* NOTREACHED */
278 98790f61 Seth Mos
	}
279 a93e56c5 Matthew Grooms
}
280
281
/*
282
 *  Return phase2 idinfo in text format
283
 */
284
function ipsec_idinfo_to_text(& $idinfo) {
285 2ffafea3 Ermal
	global $config;
286 a93e56c5 Matthew Grooms
287 2ffafea3 Ermal
	switch ($idinfo['type']) {
288 a93e56c5 Matthew Grooms
        case "address":
289 2ffafea3 Ermal
		return $idinfo['address'];
290
		break; /* NOTREACHED */
291 a93e56c5 Matthew Grooms
        case "network":
292 2ffafea3 Ermal
		return $idinfo['address']."/".$idinfo['netbits'];
293
		break; /* NOTREACHED */
294 63017a73 Ermal Lu?i
	case "mobile":
295 b1fd7536 Carlos Eduardo Ramos
		return gettext("Mobile Client");
296 2ffafea3 Ermal
		break; /* NOTREACHED */
297 63017a73 Ermal Lu?i
	case "none":
298 b1fd7536 Carlos Eduardo Ramos
		return gettext("None");
299 2ffafea3 Ermal
		break; /* NOTREACHED */
300 a93e56c5 Matthew Grooms
        default:
301 2ffafea3 Ermal
		if (!empty($config['interfaces'][$idinfo['type']]))
302
			return convert_friendly_interface_to_friendly_descr($idinfo['type']);
303
		else
304
			return strtoupper($idinfo['type']);
305
		break; /* NOTREACHED */
306
	}
307 a93e56c5 Matthew Grooms
}
308
309
/*
310
 * Return phase1 association for phase2
311
 */
312 2ffafea3 Ermal
function ipsec_lookup_phase1(& $ph2ent,& $ph1ent) {
313
	global $config;
314
315
	if (!is_array($config['ipsec']))
316
		return;
317
	if (!is_array($config['ipsec']['phase1']))
318
		return;
319
	if (empty($config['ipsec']['phase1']))
320
		return;
321
322
	foreach ($config['ipsec']['phase1'] as $ph1tmp) {
323
	    if ($ph1tmp['ikeid'] == $ph2ent['ikeid']) {
324
		$ph1ent = $ph1tmp;
325
		return $ph1ent;
326
	    }
327
	}
328
329
	return false;
330 a93e56c5 Matthew Grooms
}
331
332
/*
333
 * Check phase1 communications status
334
 */
335
function ipsec_phase1_status(& $ph1ent) {
336
337
	$loc_ip = get_ipsec_tunnel_src($ph1ent);
338
	$rmt_ip = $ph1ent['remote-gateway'];
339
340 2ffafea3 Ermal
	if (ipsec_lookup_ipsakmp_sa($loc_ip,$rmt_ip))
341 a93e56c5 Matthew Grooms
		return true;
342
343
	return false;
344
}
345
346
/*
347
 * Check phase2 communications status
348
 */
349
function ipsec_phase2_status(& $spd,& $sad,& $ph1ent,& $ph2ent) {
350
351
	$loc_ip = ipsec_get_phase1_src($ph1ent);
352 a55be495 jim-p
	$rmt_ip = ipsec_get_phase1_dst($ph1ent);
353 a93e56c5 Matthew Grooms
354 3ec026a4 jim-p
	$loc_id = ipsec_idinfo_to_cidr($ph2ent['localid'],true,$ph2ent['mode']);
355 f3c338b3 Ermal
	if (!empty($ph2ent['natlocalid']))
356 3ec026a4 jim-p
		$natloc_id = ipsec_idinfo_to_cidr($ph2ent['natlocalid'],true,$ph2ent['mode']);
357
	$rmt_id = ipsec_idinfo_to_cidr($ph2ent['remoteid'],true,$ph2ent['mode']);
358 a93e56c5 Matthew Grooms
359
	/* check for established SA in both directions */
360 f3c338b3 Ermal
	if( ipsec_lookup_ipsec_sa($spd,$sad,"out",$loc_ip,$rmt_ip,$loc_id,$rmt_id)) {
361
		if (empty($ph2ent['natlocalid']) && ipsec_lookup_ipsec_sa($spd,$sad,"in",$rmt_ip,$loc_ip,$rmt_id,$loc_id))
362
			return true;
363 1bad1025 Michele Di Maria
		else if (!empty($ph2ent['natlocalid']) && ipsec_lookup_ipsec_sa($spd,$sad,"out",$loc_ip,$rmt_ip,$loc_id,$rmt_id))
364 f3c338b3 Ermal
			return true;
365
	}
366 a93e56c5 Matthew Grooms
367
	return false;
368
}
369
370
/*
371
 * Return ISAKMP SA details
372
 */
373
function ipsec_lookup_isakmp_sa($in_srcip,$in_dstip) {
374
	/* TODO : use racconctl to lookup iskamp SA */
375
	return NULL;
376
}
377
378
/*
379
 * Return IPsec SA details
380
 */
381
function ipsec_lookup_ipsec_sa(& $spd,& $sad,$dir,$in_srcip,$in_dstip,$in_srcid,$in_dstid) {
382
383
	/* match the phase1/2 to an SP */
384 3ec026a4 jim-p
	$in_srcip = ipsec_fixup_ip($in_srcip);
385
	$in_dstip = ipsec_fixup_ip($in_dstip);
386
	$in_srcid = ipsec_fixup_ip($in_srcid);
387
	$in_dstid = ipsec_fixup_ip($in_dstid);
388 a93e56c5 Matthew Grooms
389
	foreach($spd as $sp) {
390
391
		/* match direction */
392
393
		if($dir != $sp['dir'])
394
			continue;
395
396
		/* match IPs */
397
398 3ec026a4 jim-p
		if($in_srcip != ipsec_fixup_ip($sp['src']))
399 a93e56c5 Matthew Grooms
			continue;
400 3ec026a4 jim-p
		if($in_dstip != ipsec_fixup_ip($sp['dst']))
401 a93e56c5 Matthew Grooms
			continue;
402
403
		/* add netbits for address IDs */
404
405
		$sp_srcid = $sp['srcid'];
406
		$sp_dstid = $sp['dstid'];
407
408 3ec026a4 jim-p
		if (!strstr($sp_srcid,"/")) {
409 48f273cb Ermal
			if (is_ipaddrv4($sp_srcid))
410 3ec026a4 jim-p
				$sp_srcid .= '/32';
411 48f273cb Ermal
			elseif (is_ipaddrv6($sp_srcid))
412 3ec026a4 jim-p
				$sp_srcid .= '/128';
413
		}
414
		if (!strstr($sp_dstid,"/")) {
415 2379c48e jim-p
			if (is_ipaddrv4($sp_dstid))
416 3ec026a4 jim-p
				$sp_dstid .= '/32';
417 2379c48e jim-p
			elseif (is_ipaddrv6($sp_dstid))
418 3ec026a4 jim-p
				$sp_dstid .= '/128';
419
		}
420 a93e56c5 Matthew Grooms
421
		/* match IDs */
422
423 3ec026a4 jim-p
		if($in_srcid != ipsec_fixup_ip($sp_srcid))
424 a93e56c5 Matthew Grooms
			continue;
425 3ec026a4 jim-p
		if($in_dstid != ipsec_fixup_ip($sp_dstid))
426 a93e56c5 Matthew Grooms
			continue;
427
428
		/* match the SP to a unique SA by reqid */
429
430
		foreach($sad as $sa) {
431
432
			/* match REQIDs */
433
434
			if($sa[reqid] != $sp[reqid])
435
				continue;
436
437
			/* sanitize for NAT-T ports */
438
439
			$sa_srcip = $sa['src'];
440
			$sa_dstip = $sa['dst'];
441
442
			if (strstr($sa_srcip,"["))
443
				$sa_srcip = substr($sa_srcip,0,strcspn($sa_srcip,"["));
444
			if (strstr($sa_dstip,"["))
445
				$sa_dstip = substr($sa_dstip,0,strcspn($sa_dstip,"["));
446
447
			/* match IPs */
448
449 3ec026a4 jim-p
			if($in_srcip != ipsec_fixup_ip($sa_srcip))
450 a93e56c5 Matthew Grooms
				continue;
451 3ec026a4 jim-p
			if($in_dstip != ipsec_fixup_ip($sa_dstip))
452 a93e56c5 Matthew Grooms
				continue;
453
454
			return $sa;
455
		}
456
	}
457
458
	return NULL;
459
}
460
461 df0878b0 Ermal
function ipsec_smp_dump_status() {
462
	global $config, $g, $custom_listtags;
463
464
	if (!file_exists("{$g['varrun_path']}/charon.xml")) {
465
		log_error("IPSec daemon seems to have issues or not running!");
466
		return;
467
	}
468
469 c7fbdd6c Ermal
	$fd = @fsockopen("unix://{$g['varrun_path']}/charon.xml");
470 df0878b0 Ermal
	if (!$fd) {
471
		log_error("Could not read status from ipsec");
472
		return;
473
	}
474 2124fad4 Ermal
	$query = '<?xml version="1.0"?><message xmlns="http://www.strongswan.org/smp/1.0" type="request" id="1">';
475
	$query .= '<query><ikesalist/></query></message>';
476
477 df0878b0 Ermal
	@fwrite($fd, $query);
478
	$response = "";
479
	while (!strstr($sread, "</message>")) {
480
		$sread = fgets($fd);
481
		$response .= $sread;
482
	}
483
	fclose($fd);
484
485
	@file_put_contents("{$g['tmp_path']}/smp_status.xml", $response);
486
	unset($response, $sread);
487
488 c7fbdd6c Ermal
	$custom_listtags = array('ikesa', 'childsa', 'network');
489 df0878b0 Ermal
	$response = parse_xml_config("{$g['tmp_path']}/smp_status.xml", "message");
490
	@unlink("{$g['tmp_path']}/smp_status.xml");
491
	unset($custom_listtags);
492
493
	return $response;
494
}
495
496 a93e56c5 Matthew Grooms
/*
497
 * Return dump of SPD table
498
 */
499
function ipsec_dump_spd()
500
{
501
	$fd = @popen("/usr/local/sbin/setkey -DP", "r");
502
	$spd = array();
503
	if ($fd) {
504
		while (!feof($fd)) {
505
			$line = chop(fgets($fd));
506
			if (!$line)
507
				continue;
508
			if ($line == "No SPD entries.")
509
				break;
510
			if ($line[0] != "\t") {
511
				if (is_array($cursp))
512
					$spd[] = $cursp;
513
				$cursp = array();
514
				$linea = explode(" ", $line);
515
				$cursp['srcid'] = substr($linea[0], 0, strpos($linea[0], "["));
516
				$cursp['dstid'] = substr($linea[1], 0, strpos($linea[1], "["));
517
				$i = 0;
518
			} else if (is_array($cursp)) {
519
				$linea = explode(" ", trim($line));
520
				switch($i)
521
				{
522
					case 1:
523
						if ($linea[1] == "none")	/* don't show default anti-lockout rule */
524
							unset($cursp);
525
						else
526
							$cursp['dir'] = $linea[0];
527
						break;
528
					case 2:
529
						$upperspec = explode("/", $linea[0]);
530
						$cursp['proto'] = $upperspec[0];
531
						list($cursp['src'], $cursp['dst']) = explode("-", $upperspec[2]);
532
						$cursp['reqid'] =  substr($upperspec[3], strpos($upperspec[3], "#")+1);
533
						break;
534
				}
535
			}
536
			$i++;
537
		}
538
		if (is_array($cursp) && count($cursp))
539
			$spd[] = $cursp;
540
		pclose($fd);
541
	}
542
543
	return $spd;
544
}
545
546
/*
547
 * Return dump of SAD table
548
 */
549
function ipsec_dump_sad()
550
{
551
	$fd = @popen("/usr/local/sbin/setkey -D", "r");
552
	$sad = array();
553
	if ($fd) {
554
		while (!feof($fd)) {
555
			$line = chop(fgets($fd));
556 ed5f7e9e Renato Botelho
			if (!$line || $line[0] == " ")
557 a93e56c5 Matthew Grooms
				continue;
558
			if ($line == "No SAD entries.")
559
				break;
560
			if ($line[0] != "\t")
561
			{
562
				if (is_array($cursa))
563
					$sad[] = $cursa;
564
				$cursa = array();
565
				list($cursa['src'],$cursa['dst']) = explode(" ", $line);
566
				$i = 0;
567
			}
568
			else
569
			{
570
				$linea = explode(" ", trim($line));
571
				switch ($i) {
572
					case 1:
573
						$cursa['proto'] = $linea[0];
574
						$cursa['spi'] = substr($linea[2], strpos($linea[2], "x")+1, -1);
575
						$reqid = substr($linea[3], strpos($linea[3], "=")+1);
576
						$cursa['reqid'] = substr($reqid, 0, strcspn($reqid,"("));
577
						break;
578
					case 2:
579
						$cursa['ealgo'] = $linea[1];
580
						break;
581
					case 3:
582
						$cursa['aalgo'] = $linea[1];
583
						break;
584 f451ea09 jim-p
					case 8:
585
						$sadata = explode("(", $linea[1]);
586
						$cursa['data'] = $sadata[0] . " B";
587
						break;
588 a93e56c5 Matthew Grooms
				}
589
			}
590
			$i++;
591
		}
592
		if (is_array($cursa) && count($cursa))
593
			$sad[] = $cursa;
594
		pclose($fd);
595
	}
596
597
	return $sad;
598
}
599
600 6e0b68bf jim-p
/*
601
 * Return dump of mobile user list
602
 */
603
function ipsec_dump_mobile() {
604
	$command = "/usr/local/sbin/racoonctl show-users";
605
	$fd = @popen($command, "r");
606
	$mobile = array();
607
	if ($fd) {
608
		while (!feof($fd)) {
609
			$user = array();
610
			$line = chop(fgets($fd));
611
			if (!$line)
612
				continue;
613
			if ($line == "User|Source|Destination|CreatedOn|SPI")
614
				continue;
615
616
			// jim|192.168.20.243:4500|192.168.20.5:24146|2012-05-25 09:54:39|989d10e1e2d4eca4:7243830d5fd2afe7
617
			$linea = explode("|", trim($line));
618
			$user['username'] = $linea[0];
619
			$user['local'] = $linea[1];
620
			$user['remote'] = $linea[2];
621
			$user['logintime'] = $linea[3];
622
			$user['spi'] = $linea[4];
623 52ec5df8 jim-p
			if (!empty($user['username']))
624
				$mobile[] = $user;
625 6e0b68bf jim-p
		}
626
		pclose($fd);
627
	}
628
629
	return $mobile;
630
}
631
632 958420c5 jim-p
function ipsec_mobilekey_sort() {
633
	global $config;
634
635
	function mobilekeycmp($a, $b) {
636
		return strcmp($a['ident'][0], $b['ident'][0]);
637
	}
638
639
	usort($config['ipsec']['mobilekey'], "mobilekeycmp");
640
}
641
642 8f5c3d8d Pierre POMES
function ipsec_get_number_of_phase2($ikeid) {
643
	global $config;
644
    	$a_phase2 = $config['ipsec']['phase2'];
645
646
	$nbph2=0;
647
648
    	if (is_array($a_phase2) && count($a_phase2)) {
649
        	foreach ($a_phase2 as $ph2tmp) {
650
            		if ($ph2tmp['ikeid'] == $ikeid) {
651
				$nbph2++;
652
			}
653
		}
654
	}
655
656
	return $nbph2;
657
}
658
659 6e0b68bf jim-p
function ipsec_disconnect_mobile($username) {
660
	if (empty($username))
661
		return false;
662
	exec("/usr/local/sbin/racoonctl logout-user " . escapeshellarg($username));
663
}
664
665 3ec026a4 jim-p
function ipsec_fixup_ip($ipaddr) {
666 2379c48e jim-p
	if (is_ipaddrv6($ipaddr) || is_subnetv6($ipaddr))
667 3ec026a4 jim-p
		return Net_IPv6::compress(Net_IPv6::uncompress($ipaddr));
668
	else
669
		return $ipaddr;
670
}
671
672 8f5c3d8d Pierre POMES
?>