Project

General

Profile

Download (19 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 30c591d6 Ermal
	pfSense_BUILDER_BINARIES:	/sbin/setkey
33 523855b0 Scott Ullrich
	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 b0cbebeb Ermal
	'aes128gcm' => array( 'name' => 'AES128-GCM', 'keysel' => array( 'lo' => 64, 'hi' => 128, 'step' => 32 ) ),
64
	'aes192gcm' => array( 'name' => 'AES192-GCM', 'keysel' => array( 'lo' => 64, 'hi' => 128, 'step' => 32 ) ),
65
	'aes256gcm' => array( 'name' => 'AES256-GCM', 'keysel' => array( 'lo' => 64, 'hi' => 128, 'step' => 32 ) ),
66 9601df8a Ermal
	'blowfish' => array( 'name' => 'Blowfish', 'keysel' => array( 'lo' => 128, 'hi' => 256, 'step' => 64 ) ),
67 3462a529 Matthew Grooms
	'3des' => array( 'name' => '3DES' ),
68
	'cast128' => array( 'name' => 'CAST128' ),
69
	'des' => array( 'name' => 'DES' ));
70
71
$p2_ealgos = array(
72
	'aes' => array( 'name' => 'AES', 'keysel' => array( 'lo' => 128, 'hi' => 256, 'step' => 64 ) ),
73 b0cbebeb Ermal
	'aes128gcm' => array( 'name' => 'AES128-GCM', 'keysel' => array( 'lo' => 64, 'hi' => 128, 'step' => 32 ) ),
74
	'aes192gcm' => array( 'name' => 'AES192-GCM', 'keysel' => array( 'lo' => 64, 'hi' => 128, 'step' => 32 ) ),
75
	'aes256gcm' => array( 'name' => 'AES256-GCM', 'keysel' => array( 'lo' => 64, 'hi' => 128, 'step' => 32 ) ),
76 d623693c Ermal
	'blowfish' => array( 'name' => 'Blowfish', 'keysel' => array( 'lo' => 128, 'hi' => 256, 'step' => 64 ) ),
77 3462a529 Matthew Grooms
	'3des' => array( 'name' => '3DES' ),
78
	'cast128' => array( 'name' => 'CAST128' ),
79
	'des' => array( 'name' => 'DES' ));
80
81
$p1_halgos = array(
82 665340db jim-p
	'md5' => 'MD5',
83 3462a529 Matthew Grooms
	'sha1' => 'SHA1',
84 665340db jim-p
	'sha256' => 'SHA256',
85
	'sha384' => 'SHA384',
86 b0cbebeb Ermal
	'sha512' => 'SHA512',
87
	'aesxcbc' => 'AES-XCBC'
88 665340db jim-p
);
89
90
$p1_dhgroups = array(
91
	1  => '1 (768 bit)',
92
	2  => '2 (1024 bit)',
93
	5  => '5 (1536 bit)',
94
	14 => '14 (2048 bit)',
95
	15 => '15 (3072 bit)',
96
	16 => '16 (4096 bit)',
97
	17 => '17 (6144 bit)',
98 b0cbebeb Ermal
	18 => '18 (8192 bit)',
99
	22 => '22 (1024(sub 160) bit)',
100
	23 => '23 (2048(sub 224) bit)',
101
	24 => '24 (2048(sub 256) bit)'
102 665340db jim-p
);
103 3462a529 Matthew Grooms
104
$p2_halgos = array(
105 665340db jim-p
	'hmac_md5' => 'MD5',
106 3462a529 Matthew Grooms
	'hmac_sha1' => 'SHA1',
107 665340db jim-p
	'hmac_sha256' => 'SHA256',
108
	'hmac_sha384' => 'SHA384',
109 b0cbebeb Ermal
	'hmac_sha512' => 'SHA512',
110
	'aesxcbc' => 'AES-XCBC'
111 665340db jim-p
);
112 3462a529 Matthew Grooms
113
$p1_authentication_methods = array(
114
	'hybrid_rsa_server' => array( 'name' => 'Hybrid RSA + Xauth', 'mobile' => true ),
115 1703e5c5 sullrich
	'xauth_rsa_server' => array( 'name' => 'Mutual RSA + Xauth', 'mobile' => true ),
116
	'xauth_psk_server' => array( 'name' => 'Mutual PSK + Xauth', 'mobile' => true ),
117 3462a529 Matthew Grooms
	'rsasig' => array( 'name' => 'Mutual RSA', 'mobile' => false ),
118
	'pre_shared_key' => array( 'name' => 'Mutual PSK', 'mobile' => false ) );
119
120 4b96b367 mgrooms
$p2_modes = array(
121 98790f61 Seth Mos
	'tunnel' => 'Tunnel IPv4',
122
	'tunnel6' => 'Tunnel IPv6',
123 4b96b367 mgrooms
	'transport' => 'Transport');
124
125 3462a529 Matthew Grooms
$p2_protos = array(
126
	'esp' => 'ESP',
127
	'ah' => 'AH');
128
129
$p2_pfskeygroups = array(
130 665340db jim-p
	0 => 'off',
131
	1  => '1 (768 bit)',
132
	2  => '2 (1024 bit)',
133
	5  => '5 (1536 bit)',
134
	14 => '14 (2048 bit)',
135
	15 => '15 (3072 bit)',
136
	16 => '16 (4096 bit)',
137
	17 => '17 (6144 bit)',
138
	18 => '18 (8192 bit)'
139
);
140 3462a529 Matthew Grooms
141 d799787e Matthew Grooms
/*
142
 * ikeid management functions
143
 */
144
145
function ipsec_ikeid_used($ikeid) {
146
	global $config;
147
148
	foreach ($config['ipsec']['phase1'] as $ph1ent)
149
		if( $ikeid == $ph1ent['ikeid'] )
150
			return true;
151
152
	return false;
153
}
154
155
function ipsec_ikeid_next() {
156
157
	$ikeid = 1;
158
	while(ipsec_ikeid_used($ikeid))
159
		$ikeid++;
160
161
	return $ikeid;
162
}
163
164 a93e56c5 Matthew Grooms
/*
165
 * Return phase1 local address
166
 */
167
function ipsec_get_phase1_src(& $ph1ent) {
168
169 25f6730a Pierre POMES
	if ($ph1ent['interface']) {
170
		if (!is_ipaddr($ph1ent['interface'])) {
171 909de400 Ermal
			if ($ph1ent['protocol'] == "inet6") { 
172
				$if = get_failover_interface($ph1ent['interface'], "inet6");
173 e79b24ab Seth Mos
				$interfaceip = get_interface_ipv6($if);
174
			} else {
175 909de400 Ermal
				$if = get_failover_interface($ph1ent['interface']);
176 e79b24ab Seth Mos
				$interfaceip = get_interface_ip($if);
177
			}
178 25f6730a Pierre POMES
		} else {
179
			$interfaceip=$ph1ent['interface'];
180
		}
181 e79b24ab Seth Mos
	} else {
182 924876a8 Ermal Lu?i
		$if = "wan";
183 909de400 Ermal
		if ($ph1ent['protocol'] == "inet6")
184 e79b24ab Seth Mos
			$interfaceip = get_interface_ipv6($if);
185 909de400 Ermal
		else
186 e79b24ab Seth Mos
			$interfaceip = get_interface_ip($if);
187 25f6730a Pierre POMES
	}
188 a93e56c5 Matthew Grooms
189
	return $interfaceip;
190
}
191
192 3462a529 Matthew Grooms
/*
193
 * Return phase1 local address
194
 */
195
function ipsec_get_phase1_dst(& $ph1ent) {
196 df82fae1 smos
	global $g;
197 2ffafea3 Ermal
198 a6222c03 jim-p
	if (empty($ph1ent['remote-gateway']))
199 2f3554bb jim-p
		return false;
200 3462a529 Matthew Grooms
	$rg = $ph1ent['remote-gateway'];
201 33d5cb7a smos
	if (!is_ipaddr($rg)) {
202
		if(! $g['booting'])
203
			return resolve_retry($rg);
204
	}
205 0af7398a Matthew Grooms
	if(!is_ipaddr($rg))
206
		return false;
207
208 3462a529 Matthew Grooms
	return $rg;
209
}
210
211 a93e56c5 Matthew Grooms
/*
212
 * Return phase2 idinfo in cidr format
213
 */
214 2ffafea3 Ermal
function ipsec_idinfo_to_cidr(& $idinfo, $addrbits = false, $mode = "") {
215 a93e56c5 Matthew Grooms
	global $config;
216
217 2ffafea3 Ermal
	switch ($idinfo['type']) {
218 a93e56c5 Matthew Grooms
		case "address":
219 98790f61 Seth Mos
			if ($addrbits) {
220 2ffafea3 Ermal
				if ($mode == "tunnel6")
221 98790f61 Seth Mos
					return $idinfo['address']."/128";
222 2ffafea3 Ermal
				else
223 98790f61 Seth Mos
					return $idinfo['address']."/32";
224 2ffafea3 Ermal
			} else
225 a93e56c5 Matthew Grooms
				return $idinfo['address'];
226 2ffafea3 Ermal
			break; /* NOTREACHED */
227 a93e56c5 Matthew Grooms
		case "network":
228 2ffafea3 Ermal
			return "{$idinfo['address']}/{$idinfo['netbits']}";
229
			break; /* NOTREACHED */
230 63017a73 Ermal Lu?i
		case "none":
231 3462a529 Matthew Grooms
		case "mobile":
232
			return "0.0.0.0/0";
233 2ffafea3 Ermal
			break; /* NOTREACHED */
234 a55e9c70 Ermal Lu?i
		default:
235 2ffafea3 Ermal
			if (empty($mode) && !empty($idinfo['mode']))
236
				$mode = $idinfo['mode'];
237
238
			if ($mode == "tunnel6") {
239 98790f61 Seth Mos
				$address = get_interface_ipv6($idinfo['type']);
240
				$netbits = get_interface_subnetv6($idinfo['type']);
241
				$address = gen_subnetv6($address,$netbits);
242 2ffafea3 Ermal
				return "{$address}/{$netbits}";
243 98790f61 Seth Mos
			} else {
244
				$address = get_interface_ip($idinfo['type']);
245
				$netbits = get_interface_subnet($idinfo['type']);
246
				$address = gen_subnet($address,$netbits);
247 2ffafea3 Ermal
				return "{$address}/{$netbits}";
248 98790f61 Seth Mos
			}
249 2ffafea3 Ermal
			break; /* NOTREACHED */
250 98790f61 Seth Mos
	}
251 a93e56c5 Matthew Grooms
}
252
253
/*
254
 * Return phase2 idinfo in address/netmask format
255
 */
256
function ipsec_idinfo_to_subnet(& $idinfo,$addrbits = false) {
257
	global $config;
258
259 2ffafea3 Ermal
	switch ($idinfo['type']) {
260 a93e56c5 Matthew Grooms
		case "address":
261 98790f61 Seth Mos
			if ($addrbits) {
262 2ffafea3 Ermal
				if ($idinfo['mode'] == "tunnel6")
263 98790f61 Seth Mos
					return $idinfo['address']."/128";
264 2ffafea3 Ermal
				else
265 98790f61 Seth Mos
					return $idinfo['address']."/255.255.255.255";
266 2ffafea3 Ermal
			} else
267 a93e56c5 Matthew Grooms
				return $idinfo['address'];
268 2ffafea3 Ermal
			break; /* NOTREACHED */
269 63017a73 Ermal Lu?i
		case "none":
270 a93e56c5 Matthew Grooms
		case "network":
271
			return $idinfo['address']."/".gen_subnet_mask($idinfo['netbits']);
272 2ffafea3 Ermal
			break; /* NOTREACHED */
273 3462a529 Matthew Grooms
		case "mobile":
274
			return "0.0.0.0/0";
275 2ffafea3 Ermal
			break; /* NOTREACHED */
276 63017a73 Ermal Lu?i
		default:
277 2ffafea3 Ermal
			if ($idinfo['mode'] == "tunnel6") {
278 98790f61 Seth Mos
				$address = get_interface_ipv6($idinfo['type']);
279
				$netbits = get_interface_subnetv6($idinfo['type']);
280
				$address = gen_subnetv6($address,$netbits);
281
				return $address."/".$netbits;
282
			} else {
283
				$address = get_interface_ip($idinfo['type']);
284
				$netbits = get_interface_subnet($idinfo['type']);
285
				$address = gen_subnet($address,$netbits);
286
				return $address."/".$netbits;
287
			}
288 2ffafea3 Ermal
			break; /* NOTREACHED */
289 98790f61 Seth Mos
	}
290 a93e56c5 Matthew Grooms
}
291
292
/*
293
 *  Return phase2 idinfo in text format
294
 */
295
function ipsec_idinfo_to_text(& $idinfo) {
296 2ffafea3 Ermal
	global $config;
297 a93e56c5 Matthew Grooms
298 2ffafea3 Ermal
	switch ($idinfo['type']) {
299 a93e56c5 Matthew Grooms
        case "address":
300 2ffafea3 Ermal
		return $idinfo['address'];
301
		break; /* NOTREACHED */
302 a93e56c5 Matthew Grooms
        case "network":
303 2ffafea3 Ermal
		return $idinfo['address']."/".$idinfo['netbits'];
304
		break; /* NOTREACHED */
305 63017a73 Ermal Lu?i
	case "mobile":
306 b1fd7536 Carlos Eduardo Ramos
		return gettext("Mobile Client");
307 2ffafea3 Ermal
		break; /* NOTREACHED */
308 63017a73 Ermal Lu?i
	case "none":
309 b1fd7536 Carlos Eduardo Ramos
		return gettext("None");
310 2ffafea3 Ermal
		break; /* NOTREACHED */
311 a93e56c5 Matthew Grooms
        default:
312 2ffafea3 Ermal
		if (!empty($config['interfaces'][$idinfo['type']]))
313
			return convert_friendly_interface_to_friendly_descr($idinfo['type']);
314
		else
315
			return strtoupper($idinfo['type']);
316
		break; /* NOTREACHED */
317
	}
318 a93e56c5 Matthew Grooms
}
319
320
/*
321
 * Return phase1 association for phase2
322
 */
323 2ffafea3 Ermal
function ipsec_lookup_phase1(& $ph2ent,& $ph1ent) {
324
	global $config;
325
326
	if (!is_array($config['ipsec']))
327 fe12d7ea Ermal
		return false;
328 2ffafea3 Ermal
	if (!is_array($config['ipsec']['phase1']))
329 fe12d7ea Ermal
		return false;
330 2ffafea3 Ermal
	if (empty($config['ipsec']['phase1']))
331 fe12d7ea Ermal
		return false;
332 2ffafea3 Ermal
333
	foreach ($config['ipsec']['phase1'] as $ph1tmp) {
334
	    if ($ph1tmp['ikeid'] == $ph2ent['ikeid']) {
335
		$ph1ent = $ph1tmp;
336
		return $ph1ent;
337
	    }
338
	}
339
340
	return false;
341 a93e56c5 Matthew Grooms
}
342
343
/*
344
 * Check phase1 communications status
345
 */
346 fe12d7ea Ermal
function ipsec_phase1_status($ipsec_status, $ikeid) {
347 a93e56c5 Matthew Grooms
348 fe12d7ea Ermal
	foreach ($ipsec_status as $ike) {
349 17402c63 Ermal
		if ($ike['id'] != $ikeid)
350 fe12d7ea Ermal
			continue;
351 17402c63 Ermal
		if ($ike['status'] == 'established')
352 fe12d7ea Ermal
			return true;
353
		break;
354
	}
355 a93e56c5 Matthew Grooms
356
	return false;
357
}
358
359
/*
360
 * Check phase2 communications status
361
 */
362 fe12d7ea Ermal
function ipsec_phase2_status($ipsec_status, &$phase2) {
363 a93e56c5 Matthew Grooms
364 fe12d7ea Ermal
	if (ipsec_lookup_phase1($ph2ent,$ph1ent))
365
		return ipsec_phase1_status($ipsec_status, $ph1ent['ikeid']);
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 fa9667d2 Ermal
	$custom_listtags = array('ikesa', 'childsa', 'network', 'auth');
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 30c591d6 Ermal
	$fd = @popen("/sbin/setkey -DP", "r");
502 a93e56c5 Matthew Grooms
	$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 30c591d6 Ermal
	$fd = @popen("/sbin/setkey -D", "r");
552 a93e56c5 Matthew Grooms
	$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 859a5304 Renato Botelho
function ipsec_get_descr($ikeid) {
660
	global $config;
661
662
	if (!isset($config['ipsec']['phase1']) ||
663
	    !is_array($config['ipsec']['phase1']))
664
		return "";
665
666
	$descr = '';
667
	$a_phase1 = $config['ipsec']['phase1'];
668
	foreach ($a_phase1 as $p1) {
669
		if ($p1['ikeid'] == $ikeid) {
670
			$descr = $p1['descr'];
671
			break;
672
		}
673
	}
674
	unset($a_phase1);
675
676
	return $descr;
677
}
678
679 6e0b68bf jim-p
function ipsec_disconnect_mobile($username) {
680
	if (empty($username))
681
		return false;
682
	exec("/usr/local/sbin/racoonctl logout-user " . escapeshellarg($username));
683
}
684
685 3ec026a4 jim-p
function ipsec_fixup_ip($ipaddr) {
686 2379c48e jim-p
	if (is_ipaddrv6($ipaddr) || is_subnetv6($ipaddr))
687 3ec026a4 jim-p
		return Net_IPv6::compress(Net_IPv6::uncompress($ipaddr));
688
	else
689
		return $ipaddr;
690
}
691
692 95589abd jim-p
function ipsec_find_id(& $ph1ent, $side = "local", $rgmap = array()) {
693
	if ($side == "local") {
694
		$id_type = $ph1ent['myid_type'];
695
		$id_data = $ph1ent['myid_data'];
696
697
		$addr = ipsec_get_phase1_src($ph1ent);
698
		if (!$addr)
699
			return array();
700
	} elseif ($side = "peer") {
701
		$id_type = $ph1ent['peerid_type'];
702
		$id_data = $ph1ent['peerid_data'];
703
704
		if (isset($ph1ent['mobile']))
705
			$addr = "%any";
706
		else
707
			$addr = $ph1ent['remote-gateway'];
708
	} else {
709
		return array();
710
	}
711
712
713
	$thisid_type = $id_type;
714
	switch ($thisid_type) {
715
	case "myaddress":
716
		$thisid_type = "address";
717
		$thisid_data = $addr;
718
		break;
719
720
	case "dyn_dns":
721
		$thisid_type = "address";
722
		$thisid_data = resolve_retry($id_data);
723
		break;
724
725
	case "peeraddress":
726
		$thisid_type = "address";
727
		$thisid_data = $rgmap[$ph1ent['remote-gateway']];
728
		break;
729
730
	case "address";
731
		$thisid_data = $id_data;
732
		break;
733
734
	case "fqdn";
735
	case "keyid tag";
736
	case "user_fqdn";
737
	case "asn1dn";
738
		$thisid_data = $id_data;
739
		if( $thisid_data )
740
			$thisid_data = "{$thisid_data}";
741
		break;
742
	}
743
	return array($thisid_type, $thisid_data);
744
}
745 060c3ac0 Renato Botelho
746
function ipsec_fixup_network($network) {
747
	if (substr($network, -3) == '|/0')
748
		$result = substr($network, 0, -3);
749
	else {
750
		$tmp = explode('|', $network);
751
		if (isset($tmp[1]))
752
			$result = $tmp[1];
753
		else
754
			$result = $tmp[0];
755
		unset($tmp);
756
	}
757
758
	return $result;
759
}
760
761 8f5c3d8d Pierre POMES
?>