Project

General

Profile

Download (18.2 KB) Statistics
| Branch: | Tag: | Revision:
1
<?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

    
32
	pfSense_BUILDER_BINARIES:	/sbin/setkey
33
	pfSense_MODULE:	ipsec
34

    
35
*/
36

    
37
/* IPsec defines */
38
$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", "esp" => "IPsec traffic", "lib" => "StrongSWAN Lib");
43

    
44
$my_identifier_list = array(
45
	'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

    
53
$peer_identifier_list = array(
54
	'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

    
61
$p1_ealgos = array(
62
	'aes' => array( 'name' => 'AES', 'keysel' => array( 'lo' => 128, 'hi' => 256, 'step' => 64 ) ),
63
	'blowfish' => array( 'name' => 'Blowfish', 'keysel' => array( 'lo' => 128, 'hi' => 256, 'step' => 64 ) ),
64
	'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
	'aes128gcm' => array( 'name' => 'AES128-GCM', 'keysel' => array( 'lo' => 64, 'hi' => 128, 'step' => 32 ) ),
71
	'aes192gcm' => array( 'name' => 'AES192-GCM', 'keysel' => array( 'lo' => 64, 'hi' => 128, 'step' => 32 ) ),
72
	'aes256gcm' => array( 'name' => 'AES256-GCM', 'keysel' => array( 'lo' => 64, 'hi' => 128, 'step' => 32 ) ),
73
	'blowfish' => array( 'name' => 'Blowfish', 'keysel' => array( 'lo' => 128, 'hi' => 256, 'step' => 64 ) ),
74
	'3des' => array( 'name' => '3DES' ),
75
	'cast128' => array( 'name' => 'CAST128' ),
76
	'des' => array( 'name' => 'DES' ));
77

    
78
$p1_halgos = array(
79
	'md5' => 'MD5',
80
	'sha1' => 'SHA1',
81
	'sha256' => 'SHA256',
82
	'sha384' => 'SHA384',
83
	'sha512' => 'SHA512',
84
	'aesxcbc' => 'AES-XCBC'
85
);
86

    
87
$p1_dhgroups = array(
88
	1  => '1 (768 bit)',
89
	2  => '2 (1024 bit)',
90
	5  => '5 (1536 bit)',
91
	14 => '14 (2048 bit)',
92
	15 => '15 (3072 bit)',
93
	16 => '16 (4096 bit)',
94
	17 => '17 (6144 bit)',
95
	18 => '18 (8192 bit)',
96
	22 => '22 (1024(sub 160) bit)',
97
	23 => '23 (2048(sub 224) bit)',
98
	24 => '24 (2048(sub 256) bit)'
99
);
100

    
101
$p2_halgos = array(
102
	'hmac_md5' => 'MD5',
103
	'hmac_sha1' => 'SHA1',
104
	'hmac_sha256' => 'SHA256',
105
	'hmac_sha384' => 'SHA384',
106
	'hmac_sha512' => 'SHA512',
107
	'aesxcbc' => 'AES-XCBC'
108
);
109

    
110
$p1_authentication_methods = array(
111
	'hybrid_rsa_server' => array( 'name' => 'Hybrid RSA + Xauth', 'mobile' => true ),
112
	'xauth_rsa_server' => array( 'name' => 'Mutual RSA + Xauth', 'mobile' => true ),
113
	'xauth_psk_server' => array( 'name' => 'Mutual PSK + Xauth', 'mobile' => true ),
114
	'eap-tls' => array( 'name' => 'EAP-TLS', 'mobile' => true),
115
	'rsasig' => array( 'name' => 'Mutual RSA', 'mobile' => false ),
116
	'pre_shared_key' => array( 'name' => 'Mutual PSK', 'mobile' => false ) );
117

    
118
$p2_modes = array(
119
	'tunnel' => 'Tunnel IPv4',
120
	'tunnel6' => 'Tunnel IPv6',
121
	'transport' => 'Transport');
122

    
123
$p2_protos = array(
124
	'esp' => 'ESP',
125
	'ah' => 'AH');
126

    
127
$p2_pfskeygroups = array(
128
	0 => 'off',
129
	1  => '1 (768 bit)',
130
	2  => '2 (1024 bit)',
131
	5  => '5 (1536 bit)',
132
	14 => '14 (2048 bit)',
133
	15 => '15 (3072 bit)',
134
	16 => '16 (4096 bit)',
135
	17 => '17 (6144 bit)',
136
	18 => '18 (8192 bit)'
137
);
138

    
139
/*
140
 * ikeid management functions
141
 */
142

    
143
function ipsec_ikeid_used($ikeid) {
144
	global $config;
145

    
146
	foreach ($config['ipsec']['phase1'] as $ph1ent)
147
		if( $ikeid == $ph1ent['ikeid'] )
148
			return true;
149

    
150
	return false;
151
}
152

    
153
function ipsec_ikeid_next() {
154

    
155
	$ikeid = 1;
156
	while(ipsec_ikeid_used($ikeid))
157
		$ikeid++;
158

    
159
	return $ikeid;
160
}
161

    
162
/*
163
 * Return phase1 local address
164
 */
165
function ipsec_get_phase1_src(& $ph1ent) {
166

    
167
	if ($ph1ent['interface']) {
168
		if (!is_ipaddr($ph1ent['interface'])) {
169
			if ($ph1ent['protocol'] == "inet6") { 
170
				$if = get_failover_interface($ph1ent['interface'], "inet6");
171
				$interfaceip = get_interface_ipv6($if);
172
			} else {
173
				$if = get_failover_interface($ph1ent['interface']);
174
				$interfaceip = get_interface_ip($if);
175
			}
176
		} else {
177
			$interfaceip=$ph1ent['interface'];
178
		}
179
	} else {
180
		$if = "wan";
181
		if ($ph1ent['protocol'] == "inet6")
182
			$interfaceip = get_interface_ipv6($if);
183
		else
184
			$interfaceip = get_interface_ip($if);
185
	}
186

    
187
	return $interfaceip;
188
}
189

    
190
/*
191
 * Return phase1 local address
192
 */
193
function ipsec_get_phase1_dst(& $ph1ent) {
194
	global $g;
195

    
196
	if (empty($ph1ent['remote-gateway']))
197
		return false;
198
	$rg = $ph1ent['remote-gateway'];
199
	if (!is_ipaddr($rg)) {
200
		if(! platform_booting())
201
			return resolve_retry($rg);
202
	}
203
	if(!is_ipaddr($rg))
204
		return false;
205

    
206
	return $rg;
207
}
208

    
209
/*
210
 * Return phase2 idinfo in cidr format
211
 */
212
function ipsec_idinfo_to_cidr(& $idinfo, $addrbits = false, $mode = "") {
213
	global $config;
214

    
215
	switch ($idinfo['type']) {
216
		case "address":
217
			if ($addrbits) {
218
				if ($mode == "tunnel6")
219
					return $idinfo['address']."/128";
220
				else
221
					return $idinfo['address']."/32";
222
			} else
223
				return $idinfo['address'];
224
			break; /* NOTREACHED */
225
		case "network":
226
			return "{$idinfo['address']}/{$idinfo['netbits']}";
227
			break; /* NOTREACHED */
228
		case "none":
229
		case "mobile":
230
			return "0.0.0.0/0";
231
			break; /* NOTREACHED */
232
		default:
233
			if (empty($mode) && !empty($idinfo['mode']))
234
				$mode = $idinfo['mode'];
235

    
236
			if ($mode == "tunnel6") {
237
				$address = get_interface_ipv6($idinfo['type']);
238
				$netbits = get_interface_subnetv6($idinfo['type']);
239
				$address = gen_subnetv6($address,$netbits);
240
				return "{$address}/{$netbits}";
241
			} else {
242
				$address = get_interface_ip($idinfo['type']);
243
				$netbits = get_interface_subnet($idinfo['type']);
244
				$address = gen_subnet($address,$netbits);
245
				return "{$address}/{$netbits}";
246
			}
247
			break; /* NOTREACHED */
248
	}
249
}
250

    
251
/*
252
 * Return phase2 idinfo in address/netmask format
253
 */
254
function ipsec_idinfo_to_subnet(& $idinfo,$addrbits = false) {
255
	global $config;
256

    
257
	switch ($idinfo['type']) {
258
		case "address":
259
			if ($addrbits) {
260
				if ($idinfo['mode'] == "tunnel6")
261
					return $idinfo['address']."/128";
262
				else
263
					return $idinfo['address']."/255.255.255.255";
264
			} else
265
				return $idinfo['address'];
266
			break; /* NOTREACHED */
267
		case "none":
268
		case "network":
269
			return $idinfo['address']."/".gen_subnet_mask($idinfo['netbits']);
270
			break; /* NOTREACHED */
271
		case "mobile":
272
			return "0.0.0.0/0";
273
			break; /* NOTREACHED */
274
		default:
275
			if ($idinfo['mode'] == "tunnel6") {
276
				$address = get_interface_ipv6($idinfo['type']);
277
				$netbits = get_interface_subnetv6($idinfo['type']);
278
				$address = gen_subnetv6($address,$netbits);
279
				return $address."/".$netbits;
280
			} else {
281
				$address = get_interface_ip($idinfo['type']);
282
				$netbits = get_interface_subnet($idinfo['type']);
283
				$address = gen_subnet($address,$netbits);
284
				return $address."/".$netbits;
285
			}
286
			break; /* NOTREACHED */
287
	}
288
}
289

    
290
/*
291
 *  Return phase2 idinfo in text format
292
 */
293
function ipsec_idinfo_to_text(& $idinfo) {
294
	global $config;
295

    
296
	switch ($idinfo['type']) {
297
        case "address":
298
		return $idinfo['address'];
299
		break; /* NOTREACHED */
300
        case "network":
301
		return $idinfo['address']."/".$idinfo['netbits'];
302
		break; /* NOTREACHED */
303
	case "mobile":
304
		return gettext("Mobile Client");
305
		break; /* NOTREACHED */
306
	case "none":
307
		return gettext("None");
308
		break; /* NOTREACHED */
309
        default:
310
		if (!empty($config['interfaces'][$idinfo['type']]))
311
			return convert_friendly_interface_to_friendly_descr($idinfo['type']);
312
		else
313
			return strtoupper($idinfo['type']);
314
		break; /* NOTREACHED */
315
	}
316
}
317

    
318
/*
319
 * Return phase1 association for phase2
320
 */
321
function ipsec_lookup_phase1(& $ph2ent,& $ph1ent) {
322
	global $config;
323

    
324
	if (!is_array($config['ipsec']))
325
		return false;
326
	if (!is_array($config['ipsec']['phase1']))
327
		return false;
328
	if (empty($config['ipsec']['phase1']))
329
		return false;
330

    
331
	foreach ($config['ipsec']['phase1'] as $ph1tmp) {
332
	    if ($ph1tmp['ikeid'] == $ph2ent['ikeid']) {
333
		$ph1ent = $ph1tmp;
334
		return $ph1ent;
335
	    }
336
	}
337

    
338
	return false;
339
}
340

    
341
/*
342
 * Check phase1 communications status
343
 */
344
function ipsec_phase1_status(&$ipsec_status, $ikeid) {
345

    
346
	foreach ($ipsec_status as $ike) {
347
		if ($ike['id'] != $ikeid)
348
			continue;
349
		if ($ike['status'] == 'established')
350
			return true;
351
		break;
352
	}
353

    
354
	return false;
355
}
356

    
357
/*
358
 * Check phase2 communications status
359
 */
360
function ipsec_phase2_status(&$ipsec_status, &$phase2) {
361

    
362
	if (ipsec_lookup_phase1($ph2ent,$ph1ent))
363
		return ipsec_phase1_status($ipsec_status, $ph1ent['ikeid']);
364

    
365
	return false;
366
}
367

    
368
/*
369
 * Return IPsec SA details
370
 */
371
function ipsec_lookup_ipsec_sa(& $spd,& $sad,$dir,$in_srcip,$in_dstip,$in_srcid,$in_dstid) {
372

    
373
	/* match the phase1/2 to an SP */
374
	$in_srcip = ipsec_fixup_ip($in_srcip);
375
	$in_dstip = ipsec_fixup_ip($in_dstip);
376
	$in_srcid = ipsec_fixup_ip($in_srcid);
377
	$in_dstid = ipsec_fixup_ip($in_dstid);
378

    
379
	foreach($spd as $sp) {
380

    
381
		/* match direction */
382

    
383
		if($dir != $sp['dir'])
384
			continue;
385

    
386
		/* match IPs */
387

    
388
		if($in_srcip != ipsec_fixup_ip($sp['src']))
389
			continue;
390
		if($in_dstip != ipsec_fixup_ip($sp['dst']))
391
			continue;
392

    
393
		/* add netbits for address IDs */
394

    
395
		$sp_srcid = $sp['srcid'];
396
		$sp_dstid = $sp['dstid'];
397

    
398
		if (!strstr($sp_srcid,"/")) {
399
			if (is_ipaddrv4($sp_srcid))
400
				$sp_srcid .= '/32';
401
			elseif (is_ipaddrv6($sp_srcid))
402
				$sp_srcid .= '/128';
403
		}
404
		if (!strstr($sp_dstid,"/")) {
405
			if (is_ipaddrv4($sp_dstid))
406
				$sp_dstid .= '/32';
407
			elseif (is_ipaddrv6($sp_dstid))
408
				$sp_dstid .= '/128';
409
		}
410

    
411
		/* match IDs */
412

    
413
		if($in_srcid != ipsec_fixup_ip($sp_srcid))
414
			continue;
415
		if($in_dstid != ipsec_fixup_ip($sp_dstid))
416
			continue;
417

    
418
		/* match the SP to a unique SA by reqid */
419

    
420
		foreach($sad as $sa) {
421

    
422
			/* match REQIDs */
423

    
424
			if($sa[reqid] != $sp[reqid])
425
				continue;
426

    
427
			/* sanitize for NAT-T ports */
428

    
429
			$sa_srcip = $sa['src'];
430
			$sa_dstip = $sa['dst'];
431

    
432
			if (strstr($sa_srcip,"["))
433
				$sa_srcip = substr($sa_srcip,0,strcspn($sa_srcip,"["));
434
			if (strstr($sa_dstip,"["))
435
				$sa_dstip = substr($sa_dstip,0,strcspn($sa_dstip,"["));
436

    
437
			/* match IPs */
438

    
439
			if($in_srcip != ipsec_fixup_ip($sa_srcip))
440
				continue;
441
			if($in_dstip != ipsec_fixup_ip($sa_dstip))
442
				continue;
443

    
444
			return $sa;
445
		}
446
	}
447

    
448
	return NULL;
449
}
450

    
451
function ipsec_smp_dump_status() {
452
	global $config, $g, $custom_listtags;
453

    
454
	if (!file_exists("{$g['varrun_path']}/charon.xml")) {
455
		log_error("IPsec daemon not running or has a problem!");
456
		return;
457
	}
458

    
459
	$fd = @fsockopen("unix://{$g['varrun_path']}/charon.xml");
460
	if (!$fd) {
461
		log_error("Could not read status from IPsec");
462
		return;
463
	}
464
	$query = '<?xml version="1.0"?><message xmlns="http://www.strongswan.org/smp/1.0" type="request" id="1">';
465
	$query .= '<query><ikesalist/></query></message>';
466

    
467
	@fwrite($fd, $query);
468
	$response = "";
469
	while (!strstr($sread, "</message>")) {
470
		$sread = fgets($fd);
471
		$response .= $sread;
472
	}
473
	fclose($fd);
474

    
475
	@file_put_contents("{$g['tmp_path']}/smp_status.xml", $response);
476
	unset($response, $sread);
477

    
478
	$custom_listtags = array('ikesa', 'childsa', 'network', 'auth');
479
	$response = parse_xml_config("{$g['tmp_path']}/smp_status.xml", "message");
480
	@unlink("{$g['tmp_path']}/smp_status.xml");
481
	unset($custom_listtags);
482

    
483
	return $response;
484
}
485

    
486
/*
487
 * Return dump of SPD table
488
 */
489
function ipsec_dump_spd()
490
{
491
	$fd = @popen("/sbin/setkey -DP", "r");
492
	$spd = array();
493
	if ($fd) {
494
		while (!feof($fd)) {
495
			$line = chop(fgets($fd));
496
			if (!$line)
497
				continue;
498
			if ($line == "No SPD entries.")
499
				break;
500
			if ($line[0] != "\t") {
501
				if (is_array($cursp))
502
					$spd[] = $cursp;
503
				$cursp = array();
504
				$linea = explode(" ", $line);
505
				$cursp['srcid'] = substr($linea[0], 0, strpos($linea[0], "["));
506
				$cursp['dstid'] = substr($linea[1], 0, strpos($linea[1], "["));
507
				$i = 0;
508
			} else if (is_array($cursp)) {
509
				$linea = explode(" ", trim($line));
510
				switch($i)
511
				{
512
					case 1:
513
						if ($linea[1] == "none")	/* don't show default anti-lockout rule */
514
							unset($cursp);
515
						else
516
							$cursp['dir'] = $linea[0];
517
						break;
518
					case 2:
519
						$upperspec = explode("/", $linea[0]);
520
						$cursp['proto'] = $upperspec[0];
521
						list($cursp['src'], $cursp['dst']) = explode("-", $upperspec[2]);
522
						$cursp['reqid'] =  substr($upperspec[3], strpos($upperspec[3], "#")+1);
523
						break;
524
				}
525
			}
526
			$i++;
527
		}
528
		if (is_array($cursp) && count($cursp))
529
			$spd[] = $cursp;
530
		pclose($fd);
531
	}
532

    
533
	return $spd;
534
}
535

    
536
/*
537
 * Return dump of SAD table
538
 */
539
function ipsec_dump_sad()
540
{
541
	$fd = @popen("/sbin/setkey -D", "r");
542
	$sad = array();
543
	if ($fd) {
544
		while (!feof($fd)) {
545
			$line = chop(fgets($fd));
546
			if (!$line || $line[0] == " ")
547
				continue;
548
			if ($line == "No SAD entries.")
549
				break;
550
			if ($line[0] != "\t")
551
			{
552
				if (is_array($cursa))
553
					$sad[] = $cursa;
554
				$cursa = array();
555
				list($cursa['src'],$cursa['dst']) = explode(" ", $line);
556
				$i = 0;
557
			}
558
			else
559
			{
560
				$linea = explode(" ", trim($line));
561
				switch ($i) {
562
					case 1:
563
						$cursa['proto'] = $linea[0];
564
						$cursa['spi'] = substr($linea[2], strpos($linea[2], "x")+1, -1);
565
						$reqid = substr($linea[3], strpos($linea[3], "=")+1);
566
						$cursa['reqid'] = substr($reqid, 0, strcspn($reqid,"("));
567
						break;
568
					case 2:
569
						$cursa['ealgo'] = $linea[1];
570
						break;
571
					case 3:
572
						$cursa['aalgo'] = $linea[1];
573
						break;
574
					case 8:
575
						$sadata = explode("(", $linea[1]);
576
						$cursa['data'] = $sadata[0] . " B";
577
						break;
578
				}
579
			}
580
			$i++;
581
		}
582
		if (is_array($cursa) && count($cursa))
583
			$sad[] = $cursa;
584
		pclose($fd);
585
	}
586

    
587
	return $sad;
588
}
589

    
590
/*
591
 * Return dump of mobile user list
592
 */
593
function ipsec_dump_mobile() {
594
	global $g, $custom_listtags;
595

    
596
	$_gb = exec("/usr/local/sbin/ipsec stroke leases > {$g['tmp_path']}/strongswan_leases.xml");
597

    
598
	if (!file_exists("{$g['tmp_path']}/strongswan_leases.xml")) {
599
		log_error(gettext("Unable to find IPsec daemon leases file. Could not display mobile user stats!"));
600
		return array();
601
	}
602

    
603
	$custom_listtags = array('lease', 'pool');
604
	$response = parse_xml_config("{$g['tmp_path']}/strongswan_leases.xml", "leases");
605
	@unlink("{$g['tmp_path']}/strongswan_leases.xml");
606
	unset($custom_listtags, $_gb);
607

    
608
	return $response;
609
}
610

    
611
function ipsec_mobilekey_sort() {
612
	global $config;
613

    
614
	function mobilekeycmp($a, $b) {
615
		return strcmp($a['ident'][0], $b['ident'][0]);
616
	}
617

    
618
	usort($config['ipsec']['mobilekey'], "mobilekeycmp");
619
}
620

    
621
function ipsec_get_number_of_phase2($ikeid) {
622
	global $config;
623
    	$a_phase2 = $config['ipsec']['phase2'];
624

    
625
	$nbph2=0;
626

    
627
    	if (is_array($a_phase2) && count($a_phase2)) {
628
        	foreach ($a_phase2 as $ph2tmp) {
629
            		if ($ph2tmp['ikeid'] == $ikeid) {
630
				$nbph2++;
631
			}
632
		}
633
	}
634

    
635
	return $nbph2;
636
}
637

    
638
function ipsec_get_descr($ikeid) {
639
	global $config;
640

    
641
	if (!isset($config['ipsec']['phase1']) ||
642
	    !is_array($config['ipsec']['phase1']))
643
		return "";
644

    
645
	$descr = '';
646
	$a_phase1 = $config['ipsec']['phase1'];
647
	foreach ($a_phase1 as $p1) {
648
		if ($p1['ikeid'] == $ikeid) {
649
			$descr = $p1['descr'];
650
			break;
651
		}
652
	}
653
	unset($a_phase1);
654

    
655
	return $descr;
656
}
657

    
658
function ipsec_fixup_ip($ipaddr) {
659
	if (is_ipaddrv6($ipaddr) || is_subnetv6($ipaddr))
660
		return Net_IPv6::compress(Net_IPv6::uncompress($ipaddr));
661
	else
662
		return $ipaddr;
663
}
664

    
665
function ipsec_find_id(& $ph1ent, $side = "local", $rgmap = array()) {
666
	if ($side == "local") {
667
		$id_type = $ph1ent['myid_type'];
668
		$id_data = $ph1ent['myid_data'];
669

    
670
		$addr = ipsec_get_phase1_src($ph1ent);
671
		if (!$addr)
672
			return array();
673
	} elseif ($side = "peer") {
674
		$id_type = $ph1ent['peerid_type'];
675
		$id_data = $ph1ent['peerid_data'];
676

    
677
		if (isset($ph1ent['mobile']))
678
			$addr = "%any";
679
		else
680
			$addr = $ph1ent['remote-gateway'];
681
	} else {
682
		return array();
683
	}
684

    
685

    
686
	$thisid_type = $id_type;
687
	switch ($thisid_type) {
688
	case "myaddress":
689
		$thisid_type = "address";
690
		$thisid_data = $addr;
691
		break;
692

    
693
	case "dyn_dns":
694
		$thisid_type = "address";
695
		$thisid_data = resolve_retry($id_data);
696
		break;
697

    
698
	case "peeraddress":
699
		$thisid_type = "address";
700
		$thisid_data = $rgmap[$ph1ent['remote-gateway']];
701
		break;
702

    
703
	case "address";
704
		$thisid_data = $id_data;
705
		break;
706

    
707
	case "fqdn";
708
	case "keyid tag";
709
	case "user_fqdn";
710
	case "asn1dn";
711
		$thisid_data = $id_data;
712
		if( $thisid_data )
713
			$thisid_data = "{$thisid_data}";
714
		break;
715
	}
716
	return array($thisid_type, $thisid_data);
717
}
718

    
719
function ipsec_fixup_network($network) {
720
	if (substr($network, -3) == '|/0')
721
		$result = substr($network, 0, -3);
722
	else {
723
		$tmp = explode('|', $network);
724
		if (isset($tmp[1]))
725
			$result = $tmp[1];
726
		else
727
			$result = $tmp[0];
728
		unset($tmp);
729
	}
730

    
731
	return $result;
732
}
733

    
734
?>
(29-29/68)