Project

General

Profile

Download (18.1 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
	'eap-mschapv2' => array( 'name' => 'EAP-MSChapv2', 'mobile' => true),
116
	'rsasig' => array( 'name' => 'Mutual RSA', 'mobile' => false ),
117
	'pre_shared_key' => array( 'name' => 'Mutual PSK', 'mobile' => false ) );
118

    
119
$ipsec_preshared_key_type = array(
120
	'PSK' => 'PSK',
121
	'EAP' => 'EAP'
122
	);
123

    
124
$p2_modes = array(
125
	'tunnel' => 'Tunnel IPv4',
126
	'tunnel6' => 'Tunnel IPv6',
127
	'transport' => 'Transport');
128

    
129
$p2_protos = array(
130
	'esp' => 'ESP',
131
	'ah' => 'AH');
132

    
133
$p2_pfskeygroups = array(
134
	0 => 'off',
135
	1  => '1 (768 bit)',
136
	2  => '2 (1024 bit)',
137
	5  => '5 (1536 bit)',
138
	14 => '14 (2048 bit)',
139
	15 => '15 (3072 bit)',
140
	16 => '16 (4096 bit)',
141
	17 => '17 (6144 bit)',
142
	18 => '18 (8192 bit)'
143
);
144

    
145
/*
146
 * ikeid management functions
147
 */
148

    
149
function ipsec_ikeid_used($ikeid) {
150
	global $config;
151

    
152
	foreach ($config['ipsec']['phase1'] as $ph1ent)
153
		if( $ikeid == $ph1ent['ikeid'] )
154
			return true;
155

    
156
	return false;
157
}
158

    
159
function ipsec_ikeid_next() {
160

    
161
	$ikeid = 1;
162
	while(ipsec_ikeid_used($ikeid))
163
		$ikeid++;
164

    
165
	return $ikeid;
166
}
167

    
168
/*
169
 * Return phase1 local address
170
 */
171
function ipsec_get_phase1_src(& $ph1ent) {
172

    
173
	if ($ph1ent['interface']) {
174
		if (!is_ipaddr($ph1ent['interface'])) {
175
			if ($ph1ent['protocol'] == "inet6") { 
176
				$interfaceip = get_interface_ipv6($ph1ent['interface']);
177
			} else {
178
				$interfaceip = get_interface_ip($ph1ent['interface']);
179
			}
180
		} else {
181
			$interfaceip=$ph1ent['interface'];
182
		}
183
	} else {
184
		$if = "wan";
185
		if ($ph1ent['protocol'] == "inet6")
186
			$interfaceip = get_interface_ipv6($if);
187
		else
188
			$interfaceip = get_interface_ip($if);
189
	}
190

    
191
	return $interfaceip;
192
}
193

    
194
/*
195
 * Return phase1 local address
196
 */
197
function ipsec_get_phase1_dst(& $ph1ent) {
198
	global $g;
199

    
200
	if (empty($ph1ent['remote-gateway']))
201
		return false;
202
	$rg = $ph1ent['remote-gateway'];
203
	if (!is_ipaddr($rg)) {
204
		if(! platform_booting())
205
			return resolve_retry($rg);
206
	}
207
	if(!is_ipaddr($rg))
208
		return false;
209

    
210
	return $rg;
211
}
212

    
213
/*
214
 * Return phase2 idinfo in cidr format
215
 */
216
function ipsec_idinfo_to_cidr(& $idinfo, $addrbits = false, $mode = "") {
217
	global $config;
218

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

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

    
255
/*
256
 * Return phase2 idinfo in address/netmask format
257
 */
258
function ipsec_idinfo_to_subnet(& $idinfo,$addrbits = false) {
259
	global $config;
260

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

    
294
/*
295
 *  Return phase2 idinfo in text format
296
 */
297
function ipsec_idinfo_to_text(& $idinfo) {
298
	global $config;
299

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

    
322
/*
323
 * Return phase1 association for phase2
324
 */
325
function ipsec_lookup_phase1(& $ph2ent,& $ph1ent) {
326
	global $config;
327

    
328
	if (!is_array($config['ipsec']))
329
		return false;
330
	if (!is_array($config['ipsec']['phase1']))
331
		return false;
332
	if (empty($config['ipsec']['phase1']))
333
		return false;
334

    
335
	foreach ($config['ipsec']['phase1'] as $ph1tmp) {
336
	    if ($ph1tmp['ikeid'] == $ph2ent['ikeid']) {
337
		$ph1ent = $ph1tmp;
338
		return $ph1ent;
339
	    }
340
	}
341

    
342
	return false;
343
}
344

    
345
/*
346
 * Check phase1 communications status
347
 */
348
function ipsec_phase1_status(&$ipsec_status, $ikeid) {
349

    
350
	foreach ($ipsec_status as $ike) {
351
		if ($ike['id'] == $ikeid) {
352
			if ($ike['status'] == 'established')
353
				return true;
354
		}
355
	}
356

    
357
	return false;
358
}
359

    
360
/*
361
 * Check phase2 communications status
362
 */
363
function ipsec_phase2_status(&$ipsec_status, &$phase2) {
364

    
365
	if (ipsec_lookup_phase1($ph2ent,$ph1ent))
366
		return ipsec_phase1_status($ipsec_status, $ph1ent['ikeid']);
367

    
368
	return false;
369
}
370

    
371
function ipsec_smp_dump_status() {
372
	global $config, $g, $custom_listtags;
373

    
374
	if (!file_exists("{$g['varrun_path']}/charon.xml")) {
375
		log_error("IPsec daemon not running or has a problem!");
376
		return;
377
	}
378

    
379
	$fd = @fsockopen("unix://{$g['varrun_path']}/charon.xml");
380
	if (!$fd) {
381
		log_error("Could not read status from IPsec");
382
		return;
383
	}
384
	$query = '<?xml version="1.0"?><message xmlns="http://www.strongswan.org/smp/1.0" type="request" id="1">';
385
	$query .= '<query><ikesalist/></query></message>';
386

    
387
	@fwrite($fd, $query);
388
	$response = "";
389
	while (!strstr($sread, "</message>")) {
390
		$sread = fgets($fd);
391
		if ($sread === false)
392
			break;
393
		$response .= $sread;
394
	}
395
	fclose($fd);
396

    
397
	if ($sread === false) {
398
		log_error("Error during reading of status from IPsec");
399
		return;
400
	}
401

    
402
	@file_put_contents("{$g['tmp_path']}/smp_status.xml", $response);
403
	unset($response, $sread);
404

    
405
	$custom_listtags = array('ikesa', 'childsa', 'network', 'auth');
406
	$response = parse_xml_config("{$g['tmp_path']}/smp_status.xml", "message");
407
	@unlink("{$g['tmp_path']}/smp_status.xml");
408
	unset($custom_listtags);
409

    
410
	return $response;
411
}
412

    
413
/*
414
 * Return dump of SPD table
415
 */
416
function ipsec_dump_spd()
417
{
418
	$fd = @popen("/sbin/setkey -DP", "r");
419
	$spd = array();
420
	if ($fd) {
421
		while (!feof($fd)) {
422
			$line = chop(fgets($fd));
423
			if (!$line)
424
				continue;
425
			if ($line == "No SPD entries.")
426
				break;
427
			if ($line[0] != "\t") {
428
				if (is_array($cursp))
429
					$spd[] = $cursp;
430
				$cursp = array();
431
				$linea = explode(" ", $line);
432
				$cursp['srcid'] = substr($linea[0], 0, strpos($linea[0], "["));
433
				$cursp['dstid'] = substr($linea[1], 0, strpos($linea[1], "["));
434
				$i = 0;
435
			} else if (is_array($cursp)) {
436
				$line = trim($line, "\t\r\n ");
437
				$linea = explode(" ", $line);
438
				switch($i)
439
				{
440
					case 1:
441
						if ($linea[1] == "none")	/* don't show default anti-lockout rule */
442
							unset($cursp);
443
						else
444
							$cursp['dir'] = $linea[0];
445
						break;
446
					case 2:
447
						$upperspec = explode("/", $linea[0]);
448
						$cursp['proto'] = $upperspec[0];
449
						list($cursp['src'], $cursp['dst']) = explode("-", $upperspec[2]);
450
						$cursp['reqid'] =  substr($upperspec[3], strpos($upperspec[3], "#")+1);
451
						break;
452
				}
453
			}
454
			$i++;
455
		}
456
		if (is_array($cursp) && count($cursp))
457
			$spd[] = $cursp;
458
		pclose($fd);
459
	}
460

    
461
	return $spd;
462
}
463

    
464
/*
465
 * Return dump of SAD table
466
 */
467
function ipsec_dump_sad()
468
{
469
	$fd = @popen("/sbin/setkey -D", "r");
470
	$sad = array();
471
	if ($fd) {
472
		while (!feof($fd)) {
473
			$line = chop(fgets($fd));
474
			if (!$line || $line[0] == " ")
475
				continue;
476
			if ($line == "No SAD entries.")
477
				break;
478
			if ($line[0] != "\t")
479
			{
480
				if (is_array($cursa))
481
					$sad[] = $cursa;
482
				$cursa = array();
483
				list($cursa['src'],$cursa['dst']) = explode(" ", $line);
484
			}
485
			else
486
			{
487
				$line = trim($line, "\t\n\r ");
488
				$linea = explode(" ", $line);
489
				foreach ($linea as $idx => $linee) {
490
					if ($linee == 'esp' || $linee == 'ah' || $linee[0] == '#')
491
						$cursa['proto'] = $linee;
492
					else if (substr($linee, 0, 3) == 'spi')
493
						$cursa['spi'] = substr($linee, strpos($linee, 'x') + 1, -1);
494
					else if (substr($linee, 0, 5) == 'reqid')
495
						$cursa['reqid'] = substr($linee, strpos($linee, 'x') + 1, -1);
496
					else if (substr($linee, 0, 2) == 'E:') {
497
						$cursa['ealgo'] = $linea[$idx + 1];
498
						break;
499
					} else if (substr($linee, 0, 2) == 'A:') {
500
						$cursa['aalgo'] = $linea[$idx + 1];
501
						break;
502
					} else if (substr($linee, 0, 8) == 'current:') {
503
						$cursa['data'] = substr($linea[$idx + 1], 0, strpos($linea[$idx + 1], 'bytes') - 1) . ' B';
504
						break;
505
					}
506
						
507
				}
508
			}
509
		}
510
		if (is_array($cursa) && count($cursa))
511
			$sad[] = $cursa;
512
		pclose($fd);
513
	}
514

    
515
	return $sad;
516
}
517

    
518
/*
519
 * Return dump of mobile user list
520
 */
521
function ipsec_dump_mobile() {
522
	global $g, $custom_listtags;
523

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

    
526
	if (!file_exists("{$g['tmp_path']}/strongswan_leases.xml")) {
527
		log_error(gettext("Unable to find IPsec daemon leases file. Could not display mobile user stats!"));
528
		return array();
529
	}
530

    
531
	/* This is needed for fixing #4130 */
532
	if (filesize("{$g['tmp_path']}/strongswan_leases.xml") < 200)
533
		return array();
534

    
535
	$custom_listtags = array('lease', 'pool');
536
	$response = parse_xml_config("{$g['tmp_path']}/strongswan_leases.xml", "leases");
537
	@unlink("{$g['tmp_path']}/strongswan_leases.xml");
538
	unset($custom_listtags, $_gb);
539

    
540
	return $response;
541
}
542

    
543
function ipsec_mobilekey_sort() {
544
	global $config;
545

    
546
	function mobilekeycmp($a, $b) {
547
		return strcmp($a['ident'][0], $b['ident'][0]);
548
	}
549

    
550
	usort($config['ipsec']['mobilekey'], "mobilekeycmp");
551
}
552

    
553
function ipsec_get_number_of_phase2($ikeid) {
554
	global $config;
555
    	$a_phase2 = $config['ipsec']['phase2'];
556

    
557
	$nbph2=0;
558

    
559
    	if (is_array($a_phase2) && count($a_phase2)) {
560
        	foreach ($a_phase2 as $ph2tmp) {
561
            		if ($ph2tmp['ikeid'] == $ikeid) {
562
				$nbph2++;
563
			}
564
		}
565
	}
566

    
567
	return $nbph2;
568
}
569

    
570
function ipsec_get_descr($ikeid) {
571
	global $config;
572

    
573
	if (!isset($config['ipsec']['phase1']) ||
574
	    !is_array($config['ipsec']['phase1']))
575
		return '';
576

    
577
	foreach ($config['ipsec']['phase1'] as $p1) {
578
		if ($p1['ikeid'] == $ikeid) {
579
			return $p1['descr'];
580
		}
581
	}
582

    
583
	return '';
584
}
585

    
586
function ipsec_get_phase1($ikeid) {
587
        global $config;
588

    
589
        if (!isset($config['ipsec']['phase1']) ||
590
            !is_array($config['ipsec']['phase1']))
591
                return '';
592

    
593
        $a_phase1 = $config['ipsec']['phase1'];
594
        foreach ($a_phase1 as $p1) {
595
                if ($p1['ikeid'] == $ikeid) {
596
                        return $p1;
597
                }
598
        }
599
        unset($a_phase1);
600
}
601

    
602
function ipsec_fixup_ip($ipaddr) {
603
	if (is_ipaddrv6($ipaddr) || is_subnetv6($ipaddr))
604
		return Net_IPv6::compress(Net_IPv6::uncompress($ipaddr));
605
	else
606
		return $ipaddr;
607
}
608

    
609
function ipsec_find_id(& $ph1ent, $side = "local", $rgmap = array()) {
610
	if ($side == "local") {
611
		$id_type = $ph1ent['myid_type'];
612
		$id_data = $ph1ent['myid_data'];
613

    
614
		$addr = ipsec_get_phase1_src($ph1ent);
615
		if (!$addr)
616
			return array();
617
	} elseif ($side = "peer") {
618
		$id_type = $ph1ent['peerid_type'];
619
		$id_data = $ph1ent['peerid_data'];
620

    
621
		if (isset($ph1ent['mobile']))
622
			$addr = "%any";
623
		else
624
			$addr = $ph1ent['remote-gateway'];
625
	} else
626
		return array();
627

    
628

    
629
	$thisid_type = $id_type;
630
	switch ($thisid_type) {
631
	case 'myaddress':
632
		$thisid_type = 'address';
633
		$thisid_data = $addr;
634
		break;
635
	case 'dyn_dns':
636
		$thisid_type = 'dns';
637
		$thisid_data = $id_data;
638
		break;
639
	case 'peeraddress':
640
		$thisid_type = 'address';
641
		$thisid_data = $rgmap[$ph1ent['remote-gateway']];
642
		break;
643
	case 'address';
644
		$thisid_data = $id_data;
645
		break;
646
	case 'fqdn';
647
		$thisid_data = "{$id_data}";
648
		break;
649
	case 'keyid tag';
650
		$thisid_type = 'keyid';
651
		$thisid_data = "{$thisid_data}";
652
		break;
653
	case 'user_fqdn';
654
		$thisid_type = 'userfqdn';
655
		$thisid_data = "{$id_data}";
656
		break;
657
	case 'asn1dn';
658
		$thisid_data = $id_data;
659
		$thisid_data = "{$id_data}";
660
		break;
661
	}
662
	return array($thisid_type, $thisid_data);
663
}
664

    
665
function ipsec_fixup_network($network) {
666
	if (substr($network, -3) == '|/0')
667
		$result = substr($network, 0, -3);
668
	else {
669
		$tmp = explode('|', $network);
670
		if (isset($tmp[1]))
671
			$result = $tmp[1];
672
		else
673
			$result = $tmp[0];
674
		unset($tmp);
675
	}
676

    
677
	return $result;
678
}
679

    
680
function ipsec_new_reqid() {
681
	global $config;
682

    
683
	if (!is_array($config['ipsec']) || !is_array($config['ipsec']['phase2']))
684
		return;
685

    
686
	$ipsecreqid = lock('ipsecreqids', LOCK_EX);
687
	$keyids = array();
688
	$keyid = 1;
689
	foreach ($config['ipsec']['phase2'] as $ph2)
690
		$keyids[$ph2['reqid']] = $ph2['reqid'];
691

    
692
	for ($i = 1; $i < 16000; $i++) {
693
		if (!isset($keyids[$i])) {
694
			$keyid = $i;
695
			break;
696
		}
697
	}
698
	unlock($ipsecreqid);
699

    
700
	return $keyid;
701
}
702

    
703
?>
(29-29/68)