Project

General

Profile

Download (18.9 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	/sbin/route
33
	pfSense_MODULE:	ipsec
34

    
35
*/
36

    
37
/* IPsec defines */
38
global $ipsec_loglevels;
39
$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
	"tls" => "TLS handler", "esp" => "IPsec traffic", "lib" => "StrongSwan Lib");
44

    
45
global $my_identifier_list;
46
$my_identifier_list = array(
47
	'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

    
55
global $peer_identifier_list;
56
$peer_identifier_list = array(
57
	'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

    
64
global $ipsec_idhandling;
65
$ipsec_idhandling = array(
66
	'yes' => 'YES', 'no' => 'NO', 'never' => 'NEVER', 'keep' => 'KEEP'
67
	);
68

    
69
global $p1_ealgos;
70
$p1_ealgos = array(
71
	'aes' => array( 'name' => 'AES', 'keysel' => array( 'lo' => 128, 'hi' => 256, 'step' => 64 ) ),
72
	'blowfish' => array( 'name' => 'Blowfish', 'keysel' => array( 'lo' => 128, 'hi' => 256, 'step' => 64 ) ),
73
	'3des' => array( 'name' => '3DES' ),
74
	'cast128' => array( 'name' => 'CAST128' ),
75
	'des' => array( 'name' => 'DES' ));
76

    
77
global $p2_ealgos;
78
$p2_ealgos = array(
79
	'aes' => array( 'name' => 'AES', 'keysel' => array( 'lo' => 128, 'hi' => 256, 'step' => 64 ) ),
80
	'aes128gcm' => array( 'name' => 'AES128-GCM', 'keysel' => array( 'lo' => 64, 'hi' => 128, 'step' => 32 ) ),
81
	'aes192gcm' => array( 'name' => 'AES192-GCM', 'keysel' => array( 'lo' => 64, 'hi' => 128, 'step' => 32 ) ),
82
	'aes256gcm' => array( 'name' => 'AES256-GCM', 'keysel' => array( 'lo' => 64, 'hi' => 128, 'step' => 32 ) ),
83
	'blowfish' => array( 'name' => 'Blowfish', 'keysel' => array( 'lo' => 128, 'hi' => 256, 'step' => 64 ) ),
84
	'3des' => array( 'name' => '3DES' ),
85
	'cast128' => array( 'name' => 'CAST128' ),
86
	'des' => array( 'name' => 'DES' ));
87

    
88
global $p1_halgos;
89
$p1_halgos = array(
90
	'md5' => 'MD5',
91
	'sha1' => 'SHA1',
92
	'sha256' => 'SHA256',
93
	'sha384' => 'SHA384',
94
	'sha512' => 'SHA512',
95
	'aesxcbc' => 'AES-XCBC'
96
);
97

    
98
global $p1_dhgroups;
99
$p1_dhgroups = array(
100
	1  => '1 (768 bit)',
101
	2  => '2 (1024 bit)',
102
	5  => '5 (1536 bit)',
103
	14 => '14 (2048 bit)',
104
	15 => '15 (3072 bit)',
105
	16 => '16 (4096 bit)',
106
	17 => '17 (6144 bit)',
107
	18 => '18 (8192 bit)',
108
	19 => '19 (nist ecp256)',
109
	20 => '20 (nist ecp384)',
110
	21 => '21 (nist ecp521)',
111
	22 => '22 (1024(sub 160) bit)',
112
	23 => '23 (2048(sub 224) bit)',
113
	24 => '24 (2048(sub 256) bit)'
114
);
115

    
116
global $p2_halgos;
117
$p2_halgos = array(
118
	'hmac_md5' => 'MD5',
119
	'hmac_sha1' => 'SHA1',
120
	'hmac_sha256' => 'SHA256',
121
	'hmac_sha384' => 'SHA384',
122
	'hmac_sha512' => 'SHA512',
123
	'aesxcbc' => 'AES-XCBC'
124
);
125

    
126
global $p1_authentication_methods;
127
$p1_authentication_methods = array(
128
	'hybrid_rsa_server' => array( 'name' => 'Hybrid RSA + Xauth', 'mobile' => true ),
129
	'xauth_rsa_server' => array( 'name' => 'Mutual RSA + Xauth', 'mobile' => true ),
130
	'xauth_psk_server' => array( 'name' => 'Mutual PSK + Xauth', 'mobile' => true ),
131
	'eap-tls' => array( 'name' => 'EAP-TLS', 'mobile' => true),
132
	'eap-radius' => array( 'name' => 'EAP-RADIUS', 'mobile' => true),
133
	'eap-mschapv2' => array( 'name' => 'EAP-MSChapv2', 'mobile' => true),
134
	'rsasig' => array( 'name' => 'Mutual RSA', 'mobile' => false ),
135
	'pre_shared_key' => array( 'name' => 'Mutual PSK', 'mobile' => false ) );
136

    
137
global $ipsec_preshared_key_type;
138
$ipsec_preshared_key_type = array(
139
	'PSK' => 'PSK',
140
	'EAP' => 'EAP'
141
	);
142

    
143
global $p2_modes;
144
$p2_modes = array(
145
	'tunnel' => 'Tunnel IPv4',
146
	'tunnel6' => 'Tunnel IPv6',
147
	'transport' => 'Transport');
148

    
149
global $p2_protos;
150
$p2_protos = array(
151
	'esp' => 'ESP',
152
	'ah' => 'AH');
153

    
154
global $p2_pfskeygroups;
155
$p2_pfskeygroups = array(
156
	0 => 'off',
157
	1  => '1 (768 bit)',
158
	2  => '2 (1024 bit)',
159
	5  => '5 (1536 bit)',
160
	14 => '14 (2048 bit)',
161
	15 => '15 (3072 bit)',
162
	16 => '16 (4096 bit)',
163
	17 => '17 (6144 bit)',
164
	18 => '18 (8192 bit)'
165
);
166

    
167
/*
168
 * ikeid management functions
169
 */
170

    
171
function ipsec_ikeid_used($ikeid) {
172
	global $config;
173

    
174
	foreach ($config['ipsec']['phase1'] as $ph1ent)
175
		if( $ikeid == $ph1ent['ikeid'] )
176
			return true;
177

    
178
	return false;
179
}
180

    
181
function ipsec_ikeid_next() {
182

    
183
	$ikeid = 1;
184
	while(ipsec_ikeid_used($ikeid))
185
		$ikeid++;
186

    
187
	return $ikeid;
188
}
189

    
190
/*
191
 * Return phase1 local address
192
 */
193
function ipsec_get_phase1_src(& $ph1ent) {
194

    
195
	if ($ph1ent['interface']) {
196
		if (!is_ipaddr($ph1ent['interface'])) {
197
			if (strpos($ph1ent['interface'], '_vip')) {
198
				$if = $ph1ent['interface'];
199
			} else {
200
				$if = get_failover_interface($ph1ent['interface']);
201
			}
202
			if ($ph1ent['protocol'] == "inet6") {
203
				$interfaceip = get_interface_ipv6($if);
204
			} else {
205
				$interfaceip = get_interface_ip($if);
206
			}
207
		} else {
208
			$interfaceip=$ph1ent['interface'];
209
		}
210
	} else {
211
		$if = "wan";
212
		if ($ph1ent['protocol'] == "inet6")
213
			$interfaceip = get_interface_ipv6($if);
214
		else
215
			$interfaceip = get_interface_ip($if);
216
	}
217

    
218
	return $interfaceip;
219
}
220

    
221
/*
222
 * Return phase1 local address
223
 */
224
function ipsec_get_phase1_dst(& $ph1ent) {
225
	global $g;
226

    
227
	if (empty($ph1ent['remote-gateway']))
228
		return false;
229
	$rg = $ph1ent['remote-gateway'];
230
	if (!is_ipaddr($rg)) {
231
		if(! platform_booting())
232
			return resolve_retry($rg);
233
	}
234
	if(!is_ipaddr($rg))
235
		return false;
236

    
237
	return $rg;
238
}
239

    
240
/*
241
 * Return phase2 idinfo in cidr format
242
 */
243
function ipsec_idinfo_to_cidr(& $idinfo, $addrbits = false, $mode = "") {
244
	global $config;
245

    
246
	switch ($idinfo['type']) {
247
		case "address":
248
			if ($addrbits) {
249
				if ($mode == "tunnel6")
250
					return $idinfo['address']."/128";
251
				else
252
					return $idinfo['address']."/32";
253
			} else
254
				return $idinfo['address'];
255
			break; /* NOTREACHED */
256
		case "network":
257
			return "{$idinfo['address']}/{$idinfo['netbits']}";
258
			break; /* NOTREACHED */
259
		case "none":
260
		case "mobile":
261
			return '0.0.0.0/0';
262
			break; /* NOTREACHED */
263
		default:
264
			if (empty($mode) && !empty($idinfo['mode']))
265
				$mode = $idinfo['mode'];
266

    
267
			if ($mode == "tunnel6") {
268
				$address = get_interface_ipv6($idinfo['type']);
269
				$netbits = get_interface_subnetv6($idinfo['type']);
270
				$address = gen_subnetv6($address,$netbits);
271
				return "{$address}/{$netbits}";
272
			} else {
273
				$address = get_interface_ip($idinfo['type']);
274
				$netbits = get_interface_subnet($idinfo['type']);
275
				$address = gen_subnet($address,$netbits);
276
				return "{$address}/{$netbits}";
277
			}
278
			break; /* NOTREACHED */
279
	}
280
}
281

    
282
/*
283
 * Return phase2 idinfo in address/netmask format
284
 */
285
function ipsec_idinfo_to_subnet(& $idinfo,$addrbits = false) {
286
	global $config;
287

    
288
	switch ($idinfo['type']) {
289
		case "address":
290
			if ($addrbits) {
291
				if ($idinfo['mode'] == "tunnel6")
292
					return $idinfo['address']."/128";
293
				else
294
					return $idinfo['address']."/255.255.255.255";
295
			} else
296
				return $idinfo['address'];
297
			break; /* NOTREACHED */
298
		case "none":
299
		case "network":
300
			return $idinfo['address']."/".gen_subnet_mask($idinfo['netbits']);
301
			break; /* NOTREACHED */
302
		case "mobile":
303
			return "0.0.0.0/0";
304
			break; /* NOTREACHED */
305
		default:
306
			if ($idinfo['mode'] == "tunnel6") {
307
				$address = get_interface_ipv6($idinfo['type']);
308
				$netbits = get_interface_subnetv6($idinfo['type']);
309
				$address = gen_subnetv6($address,$netbits);
310
				return $address."/".$netbits;
311
			} else {
312
				$address = get_interface_ip($idinfo['type']);
313
				$netbits = get_interface_subnet($idinfo['type']);
314
				$address = gen_subnet($address,$netbits);
315
				return $address."/".$netbits;
316
			}
317
			break; /* NOTREACHED */
318
	}
319
}
320

    
321
/*
322
 *  Return phase2 idinfo in text format
323
 */
324
function ipsec_idinfo_to_text(& $idinfo) {
325
	global $config;
326

    
327
	switch ($idinfo['type']) {
328
        case "address":
329
		return $idinfo['address'];
330
		break; /* NOTREACHED */
331
        case "network":
332
		return $idinfo['address']."/".$idinfo['netbits'];
333
		break; /* NOTREACHED */
334
	case "mobile":
335
		return gettext("Mobile Client");
336
		break; /* NOTREACHED */
337
	case "none":
338
		return gettext("None");
339
		break; /* NOTREACHED */
340
        default:
341
		if (!empty($config['interfaces'][$idinfo['type']]))
342
			return convert_friendly_interface_to_friendly_descr($idinfo['type']);
343
		else
344
			return strtoupper($idinfo['type']);
345
		break; /* NOTREACHED */
346
	}
347
}
348

    
349
/*
350
 * Return phase1 association for phase2
351
 */
352
function ipsec_lookup_phase1(& $ph2ent,& $ph1ent) {
353
	global $config;
354

    
355
	if (!is_array($config['ipsec']))
356
		return false;
357
	if (!is_array($config['ipsec']['phase1']))
358
		return false;
359
	if (empty($config['ipsec']['phase1']))
360
		return false;
361

    
362
	foreach ($config['ipsec']['phase1'] as $ph1tmp) {
363
	    if ($ph1tmp['ikeid'] == $ph2ent['ikeid']) {
364
		$ph1ent = $ph1tmp;
365
		return $ph1ent;
366
	    }
367
	}
368

    
369
	return false;
370
}
371

    
372
/*
373
 * Check phase1 communications status
374
 */
375
function ipsec_phase1_status(&$ipsec_status, $ikeid) {
376

    
377
	foreach ($ipsec_status as $ike) {
378
		if ($ike['id'] == $ikeid) {
379
			if ($ike['status'] == 'established')
380
				return true;
381
		}
382
	}
383

    
384
	return false;
385
}
386

    
387
/*
388
 * Check phase2 communications status
389
 */
390
function ipsec_phase2_status(&$ipsec_status, &$phase2) {
391

    
392
	if (ipsec_lookup_phase1($ph2ent,$ph1ent))
393
		return ipsec_phase1_status($ipsec_status, $ph1ent['ikeid']);
394

    
395
	return false;
396
}
397

    
398
function ipsec_smp_dump_status() {
399
	global $config, $g, $custom_listtags;
400

    
401
        if (isset($config['ipsec']['enable'])) {
402
            if (!file_exists("{$g['varrun_path']}/charon.xml")) {
403
                log_error("IPsec daemon not running or has a problem!");
404
                return;
405
            }
406
        } else {
407
            return;
408
        }
409

    
410
	$fd = @fsockopen("unix://{$g['varrun_path']}/charon.xml");
411
	if (!$fd) {
412
		log_error("Could not read status from IPsec");
413
		return;
414
	}
415
	$query = '<?xml version="1.0"?><message xmlns="http://www.strongswan.org/smp/1.0" type="request" id="1">';
416
	$query .= '<query><ikesalist/></query></message>';
417

    
418
	@fwrite($fd, $query);
419
	$response = "";
420
	while (!strstr($sread, "</message>")) {
421
		$sread = fgets($fd);
422
		if ($sread === false)
423
			break;
424
		$response .= $sread;
425
	}
426
	fclose($fd);
427

    
428
	if ($sread === false) {
429
		log_error("Error during reading of status from IPsec");
430
		return;
431
	}
432

    
433
	@file_put_contents("{$g['tmp_path']}/smp_status.xml", $response);
434
	unset($response, $sread);
435

    
436
	$custom_listtags = array('ikesa', 'childsa', 'network', 'auth');
437
	$response = parse_xml_config("{$g['tmp_path']}/smp_status.xml", "message");
438
	@unlink("{$g['tmp_path']}/smp_status.xml");
439
	unset($custom_listtags);
440

    
441
	return $response;
442
}
443

    
444
/*
445
 * Return dump of SPD table
446
 */
447
function ipsec_dump_spd()
448
{
449
	$fd = @popen("/sbin/setkey -DP", "r");
450
	$spd = array();
451
	if ($fd) {
452
		while (!feof($fd)) {
453
			$line = chop(fgets($fd));
454
			if (!$line)
455
				continue;
456
			if ($line == "No SPD entries.")
457
				break;
458
			if ($line[0] != "\t") {
459
				if (is_array($cursp))
460
					$spd[] = $cursp;
461
				$cursp = array();
462
				$linea = explode(" ", $line);
463
				$cursp['srcid'] = substr($linea[0], 0, strpos($linea[0], "["));
464
				$cursp['dstid'] = substr($linea[1], 0, strpos($linea[1], "["));
465
				$i = 0;
466
			} else if (is_array($cursp)) {
467
				$line = trim($line, "\t\r\n ");
468
				$linea = explode(" ", $line);
469
				switch($i)
470
				{
471
					case 1:
472
						if ($linea[1] == "none")	/* don't show default anti-lockout rule */
473
							unset($cursp);
474
						else
475
							$cursp['dir'] = $linea[0];
476
						break;
477
					case 2:
478
						$upperspec = explode("/", $linea[0]);
479
						$cursp['proto'] = $upperspec[0];
480
						list($cursp['src'], $cursp['dst']) = explode("-", $upperspec[2]);
481
						$cursp['reqid'] =  substr($upperspec[3], strpos($upperspec[3], "#")+1);
482
						break;
483
				}
484
			}
485
			$i++;
486
		}
487
		if (is_array($cursp) && count($cursp))
488
			$spd[] = $cursp;
489
		pclose($fd);
490
	}
491

    
492
	return $spd;
493
}
494

    
495
/*
496
 * Return dump of SAD table
497
 */
498
function ipsec_dump_sad()
499
{
500
	$fd = @popen("/sbin/setkey -D", "r");
501
	$sad = array();
502
	if ($fd) {
503
		while (!feof($fd)) {
504
			$line = chop(fgets($fd));
505
			if (!$line || $line[0] == " ")
506
				continue;
507
			if ($line == "No SAD entries.")
508
				break;
509
			if ($line[0] != "\t")
510
			{
511
				if (is_array($cursa))
512
					$sad[] = $cursa;
513
				$cursa = array();
514
				list($cursa['src'],$cursa['dst']) = explode(" ", $line);
515
			}
516
			else
517
			{
518
				$line = trim($line, "\t\n\r ");
519
				$linea = explode(" ", $line);
520
				foreach ($linea as $idx => $linee) {
521
					if ($linee == 'esp' || $linee == 'ah' || $linee[0] == '#')
522
						$cursa['proto'] = $linee;
523
					else if (substr($linee, 0, 3) == 'spi')
524
						$cursa['spi'] = substr($linee, strpos($linee, 'x') + 1, -1);
525
					else if (substr($linee, 0, 5) == 'reqid')
526
						$cursa['reqid'] = substr($linee, strpos($linee, 'x') + 1, -1);
527
					else if (substr($linee, 0, 2) == 'E:') {
528
						$cursa['ealgo'] = $linea[$idx + 1];
529
						break;
530
					} else if (substr($linee, 0, 2) == 'A:') {
531
						$cursa['aalgo'] = $linea[$idx + 1];
532
						break;
533
					} else if (substr($linee, 0, 8) == 'current:') {
534
						$cursa['data'] = substr($linea[$idx + 1], 0, strpos($linea[$idx + 1], 'bytes') - 1) . ' B';
535
						break;
536
					}
537
						
538
				}
539
			}
540
		}
541
		if (is_array($cursa) && count($cursa))
542
			$sad[] = $cursa;
543
		pclose($fd);
544
	}
545

    
546
	return $sad;
547
}
548

    
549
/*
550
 * Return dump of mobile user list
551
 */
552
function ipsec_dump_mobile() {
553
	global $g, $custom_listtags;
554

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

    
557
	if (!file_exists("{$g['tmp_path']}/strongswan_leases.xml")) {
558
		log_error(gettext("Unable to find IPsec daemon leases file. Could not display mobile user stats!"));
559
		return array();
560
	}
561

    
562
	/* This is needed for fixing #4130 */
563
	if (filesize("{$g['tmp_path']}/strongswan_leases.xml") < 200)
564
		return array();
565

    
566
	$custom_listtags = array('lease', 'pool');
567
	$response = parse_xml_config("{$g['tmp_path']}/strongswan_leases.xml", "leases");
568
	@unlink("{$g['tmp_path']}/strongswan_leases.xml");
569
	unset($custom_listtags, $_gb);
570

    
571
	return $response;
572
}
573

    
574
function ipsec_mobilekey_sort() {
575
	global $config;
576

    
577
	function mobilekeycmp($a, $b) {
578
		return strcmp($a['ident'][0], $b['ident'][0]);
579
	}
580

    
581
	usort($config['ipsec']['mobilekey'], "mobilekeycmp");
582
}
583

    
584
function ipsec_get_number_of_phase2($ikeid) {
585
	global $config;
586
    	$a_phase2 = $config['ipsec']['phase2'];
587

    
588
	$nbph2=0;
589

    
590
    	if (is_array($a_phase2) && count($a_phase2)) {
591
        	foreach ($a_phase2 as $ph2tmp) {
592
            		if ($ph2tmp['ikeid'] == $ikeid) {
593
				$nbph2++;
594
			}
595
		}
596
	}
597

    
598
	return $nbph2;
599
}
600

    
601
function ipsec_get_descr($ikeid) {
602
	global $config;
603

    
604
	if (!isset($config['ipsec']['phase1']) ||
605
	    !is_array($config['ipsec']['phase1']))
606
		return '';
607

    
608
	foreach ($config['ipsec']['phase1'] as $p1) {
609
		if ($p1['ikeid'] == $ikeid) {
610
			return $p1['descr'];
611
		}
612
	}
613

    
614
	return '';
615
}
616

    
617
function ipsec_get_phase1($ikeid) {
618
        global $config;
619

    
620
        if (!isset($config['ipsec']['phase1']) ||
621
            !is_array($config['ipsec']['phase1']))
622
                return '';
623

    
624
        $a_phase1 = $config['ipsec']['phase1'];
625
        foreach ($a_phase1 as $p1) {
626
                if ($p1['ikeid'] == $ikeid) {
627
                        return $p1;
628
                }
629
        }
630
        unset($a_phase1);
631
}
632

    
633
function ipsec_fixup_ip($ipaddr) {
634
	if (is_ipaddrv6($ipaddr) || is_subnetv6($ipaddr))
635
		return Net_IPv6::compress(Net_IPv6::uncompress($ipaddr));
636
	else
637
		return $ipaddr;
638
}
639

    
640
function ipsec_find_id(& $ph1ent, $side = "local", $rgmap = array()) {
641
	if ($side == "local") {
642
		$id_type = $ph1ent['myid_type'];
643
		$id_data = $ph1ent['myid_data'];
644

    
645
		$addr = ipsec_get_phase1_src($ph1ent);
646
		if (!$addr)
647
			return array();
648
	} elseif ($side == "peer") {
649
		$id_type = $ph1ent['peerid_type'];
650
		$id_data = $ph1ent['peerid_data'];
651

    
652
		if (isset($ph1ent['mobile']))
653
			$addr = "%any";
654
		else
655
			$addr = $ph1ent['remote-gateway'];
656
	} else
657
		return array();
658

    
659

    
660
	$thisid_type = $id_type;
661
	switch ($thisid_type) {
662
	case 'myaddress':
663
		$thisid_type = 'address';
664
		$thisid_data = $addr;
665
		break;
666
	case 'dyn_dns':
667
		$thisid_type = 'dns';
668
		$thisid_data = $id_data;
669
		break;
670
	case 'peeraddress':
671
		$thisid_type = 'address';
672
		$thisid_data = $rgmap[$ph1ent['remote-gateway']];
673
		break;
674
	case 'address':
675
		$thisid_data = $id_data;
676
		break;
677
	case 'fqdn':
678
		$thisid_data = "{$id_data}";
679
		break;
680
	case 'keyid tag':
681
		$thisid_type = 'keyid';
682
		$thisid_data = "{$thisid_data}";
683
		break;
684
	case 'user_fqdn':
685
		$thisid_type = 'userfqdn';
686
		$thisid_data = "{$id_data}";
687
		break;
688
	case 'asn1dn':
689
		$thisid_data = $id_data;
690
		$thisid_data = "{$id_data}";
691
		break;
692
	}
693
	return array($thisid_type, $thisid_data);
694
}
695

    
696
function ipsec_fixup_network($network) {
697
	if (substr($network, -3) == '|/0')
698
		$result = substr($network, 0, -3);
699
	else {
700
		$tmp = explode('|', $network);
701
		if (isset($tmp[1]))
702
			$result = $tmp[1];
703
		else
704
			$result = $tmp[0];
705
		unset($tmp);
706
	}
707

    
708
	return $result;
709
}
710

    
711
function ipsec_new_reqid() {
712
	global $config;
713

    
714
	if (!is_array($config['ipsec']) || !is_array($config['ipsec']['phase2']))
715
		return;
716

    
717
	$ipsecreqid = lock('ipsecreqids', LOCK_EX);
718
	$keyids = array();
719
	$keyid = 1;
720
	foreach ($config['ipsec']['phase2'] as $ph2)
721
		$keyids[$ph2['reqid']] = $ph2['reqid'];
722

    
723
	for ($i = 1; $i < 16000; $i++) {
724
		if (!isset($keyids[$i])) {
725
			$keyid = $i;
726
			break;
727
		}
728
	}
729
	unlock($ipsecreqid);
730

    
731
	return $keyid;
732
}
733

    
734
?>
(28-28/67)