Project

General

Profile

Download (18.5 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
	22 => '22 (1024(sub 160) bit)',
109
	23 => '23 (2048(sub 224) bit)',
110
	24 => '24 (2048(sub 256) bit)'
111
);
112

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

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

    
133
global $ipsec_preshared_key_type;
134
$ipsec_preshared_key_type = array(
135
	'PSK' => 'PSK',
136
	'EAP' => 'EAP'
137
	);
138

    
139
global $p2_modes;
140
$p2_modes = array(
141
	'tunnel' => 'Tunnel IPv4',
142
	'tunnel6' => 'Tunnel IPv6',
143
	'transport' => 'Transport');
144

    
145
global $p2_protos;
146
$p2_protos = array(
147
	'esp' => 'ESP',
148
	'ah' => 'AH');
149

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

    
163
/*
164
 * ikeid management functions
165
 */
166

    
167
function ipsec_ikeid_used($ikeid) {
168
	global $config;
169

    
170
	foreach ($config['ipsec']['phase1'] as $ph1ent)
171
		if( $ikeid == $ph1ent['ikeid'] )
172
			return true;
173

    
174
	return false;
175
}
176

    
177
function ipsec_ikeid_next() {
178

    
179
	$ikeid = 1;
180
	while(ipsec_ikeid_used($ikeid))
181
		$ikeid++;
182

    
183
	return $ikeid;
184
}
185

    
186
/*
187
 * Return phase1 local address
188
 */
189
function ipsec_get_phase1_src(& $ph1ent) {
190

    
191
	if ($ph1ent['interface']) {
192
		if (!is_ipaddr($ph1ent['interface'])) {
193
			if ($ph1ent['protocol'] == "inet6") { 
194
				$interfaceip = get_interface_ipv6($ph1ent['interface']);
195
			} else {
196
				$interfaceip = get_interface_ip($ph1ent['interface']);
197
			}
198
		} else {
199
			$interfaceip=$ph1ent['interface'];
200
		}
201
	} else {
202
		$if = "wan";
203
		if ($ph1ent['protocol'] == "inet6")
204
			$interfaceip = get_interface_ipv6($if);
205
		else
206
			$interfaceip = get_interface_ip($if);
207
	}
208

    
209
	return $interfaceip;
210
}
211

    
212
/*
213
 * Return phase1 local address
214
 */
215
function ipsec_get_phase1_dst(& $ph1ent) {
216
	global $g;
217

    
218
	if (empty($ph1ent['remote-gateway']))
219
		return false;
220
	$rg = $ph1ent['remote-gateway'];
221
	if (!is_ipaddr($rg)) {
222
		if(! platform_booting())
223
			return resolve_retry($rg);
224
	}
225
	if(!is_ipaddr($rg))
226
		return false;
227

    
228
	return $rg;
229
}
230

    
231
/*
232
 * Return phase2 idinfo in cidr format
233
 */
234
function ipsec_idinfo_to_cidr(& $idinfo, $addrbits = false, $mode = "") {
235
	global $config;
236

    
237
	switch ($idinfo['type']) {
238
		case "address":
239
			if ($addrbits) {
240
				if ($mode == "tunnel6")
241
					return $idinfo['address']."/128";
242
				else
243
					return $idinfo['address']."/32";
244
			} else
245
				return $idinfo['address'];
246
			break; /* NOTREACHED */
247
		case "network":
248
			return "{$idinfo['address']}/{$idinfo['netbits']}";
249
			break; /* NOTREACHED */
250
		case "none":
251
		case "mobile":
252
			return '0.0.0.0/0';
253
			break; /* NOTREACHED */
254
		default:
255
			if (empty($mode) && !empty($idinfo['mode']))
256
				$mode = $idinfo['mode'];
257

    
258
			if ($mode == "tunnel6") {
259
				$address = get_interface_ipv6($idinfo['type']);
260
				$netbits = get_interface_subnetv6($idinfo['type']);
261
				$address = gen_subnetv6($address,$netbits);
262
				return "{$address}/{$netbits}";
263
			} else {
264
				$address = get_interface_ip($idinfo['type']);
265
				$netbits = get_interface_subnet($idinfo['type']);
266
				$address = gen_subnet($address,$netbits);
267
				return "{$address}/{$netbits}";
268
			}
269
			break; /* NOTREACHED */
270
	}
271
}
272

    
273
/*
274
 * Return phase2 idinfo in address/netmask format
275
 */
276
function ipsec_idinfo_to_subnet(& $idinfo,$addrbits = false) {
277
	global $config;
278

    
279
	switch ($idinfo['type']) {
280
		case "address":
281
			if ($addrbits) {
282
				if ($idinfo['mode'] == "tunnel6")
283
					return $idinfo['address']."/128";
284
				else
285
					return $idinfo['address']."/255.255.255.255";
286
			} else
287
				return $idinfo['address'];
288
			break; /* NOTREACHED */
289
		case "none":
290
		case "network":
291
			return $idinfo['address']."/".gen_subnet_mask($idinfo['netbits']);
292
			break; /* NOTREACHED */
293
		case "mobile":
294
			return "0.0.0.0/0";
295
			break; /* NOTREACHED */
296
		default:
297
			if ($idinfo['mode'] == "tunnel6") {
298
				$address = get_interface_ipv6($idinfo['type']);
299
				$netbits = get_interface_subnetv6($idinfo['type']);
300
				$address = gen_subnetv6($address,$netbits);
301
				return $address."/".$netbits;
302
			} else {
303
				$address = get_interface_ip($idinfo['type']);
304
				$netbits = get_interface_subnet($idinfo['type']);
305
				$address = gen_subnet($address,$netbits);
306
				return $address."/".$netbits;
307
			}
308
			break; /* NOTREACHED */
309
	}
310
}
311

    
312
/*
313
 *  Return phase2 idinfo in text format
314
 */
315
function ipsec_idinfo_to_text(& $idinfo) {
316
	global $config;
317

    
318
	switch ($idinfo['type']) {
319
        case "address":
320
		return $idinfo['address'];
321
		break; /* NOTREACHED */
322
        case "network":
323
		return $idinfo['address']."/".$idinfo['netbits'];
324
		break; /* NOTREACHED */
325
	case "mobile":
326
		return gettext("Mobile Client");
327
		break; /* NOTREACHED */
328
	case "none":
329
		return gettext("None");
330
		break; /* NOTREACHED */
331
        default:
332
		if (!empty($config['interfaces'][$idinfo['type']]))
333
			return convert_friendly_interface_to_friendly_descr($idinfo['type']);
334
		else
335
			return strtoupper($idinfo['type']);
336
		break; /* NOTREACHED */
337
	}
338
}
339

    
340
/*
341
 * Return phase1 association for phase2
342
 */
343
function ipsec_lookup_phase1(& $ph2ent,& $ph1ent) {
344
	global $config;
345

    
346
	if (!is_array($config['ipsec']))
347
		return false;
348
	if (!is_array($config['ipsec']['phase1']))
349
		return false;
350
	if (empty($config['ipsec']['phase1']))
351
		return false;
352

    
353
	foreach ($config['ipsec']['phase1'] as $ph1tmp) {
354
	    if ($ph1tmp['ikeid'] == $ph2ent['ikeid']) {
355
		$ph1ent = $ph1tmp;
356
		return $ph1ent;
357
	    }
358
	}
359

    
360
	return false;
361
}
362

    
363
/*
364
 * Check phase1 communications status
365
 */
366
function ipsec_phase1_status(&$ipsec_status, $ikeid) {
367

    
368
	foreach ($ipsec_status as $ike) {
369
		if ($ike['id'] == $ikeid) {
370
			if ($ike['status'] == 'established')
371
				return true;
372
		}
373
	}
374

    
375
	return false;
376
}
377

    
378
/*
379
 * Check phase2 communications status
380
 */
381
function ipsec_phase2_status(&$ipsec_status, &$phase2) {
382

    
383
	if (ipsec_lookup_phase1($ph2ent,$ph1ent))
384
		return ipsec_phase1_status($ipsec_status, $ph1ent['ikeid']);
385

    
386
	return false;
387
}
388

    
389
function ipsec_smp_dump_status() {
390
	global $config, $g, $custom_listtags;
391

    
392
	if (!file_exists("{$g['varrun_path']}/charon.xml")) {
393
		log_error("IPsec daemon not running or has a problem!");
394
		return;
395
	}
396

    
397
	$fd = @fsockopen("unix://{$g['varrun_path']}/charon.xml");
398
	if (!$fd) {
399
		log_error("Could not read status from IPsec");
400
		return;
401
	}
402
	$query = '<?xml version="1.0"?><message xmlns="http://www.strongswan.org/smp/1.0" type="request" id="1">';
403
	$query .= '<query><ikesalist/></query></message>';
404

    
405
	@fwrite($fd, $query);
406
	$response = "";
407
	while (!strstr($sread, "</message>")) {
408
		$sread = fgets($fd);
409
		if ($sread === false)
410
			break;
411
		$response .= $sread;
412
	}
413
	fclose($fd);
414

    
415
	if ($sread === false) {
416
		log_error("Error during reading of status from IPsec");
417
		return;
418
	}
419

    
420
	@file_put_contents("{$g['tmp_path']}/smp_status.xml", $response);
421
	unset($response, $sread);
422

    
423
	$custom_listtags = array('ikesa', 'childsa', 'network', 'auth');
424
	$response = parse_xml_config("{$g['tmp_path']}/smp_status.xml", "message");
425
	@unlink("{$g['tmp_path']}/smp_status.xml");
426
	unset($custom_listtags);
427

    
428
	return $response;
429
}
430

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

    
479
	return $spd;
480
}
481

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

    
533
	return $sad;
534
}
535

    
536
/*
537
 * Return dump of mobile user list
538
 */
539
function ipsec_dump_mobile() {
540
	global $g, $custom_listtags;
541

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

    
544
	if (!file_exists("{$g['tmp_path']}/strongswan_leases.xml")) {
545
		log_error(gettext("Unable to find IPsec daemon leases file. Could not display mobile user stats!"));
546
		return array();
547
	}
548

    
549
	/* This is needed for fixing #4130 */
550
	if (filesize("{$g['tmp_path']}/strongswan_leases.xml") < 200)
551
		return array();
552

    
553
	$custom_listtags = array('lease', 'pool');
554
	$response = parse_xml_config("{$g['tmp_path']}/strongswan_leases.xml", "leases");
555
	@unlink("{$g['tmp_path']}/strongswan_leases.xml");
556
	unset($custom_listtags, $_gb);
557

    
558
	return $response;
559
}
560

    
561
function ipsec_mobilekey_sort() {
562
	global $config;
563

    
564
	function mobilekeycmp($a, $b) {
565
		return strcmp($a['ident'][0], $b['ident'][0]);
566
	}
567

    
568
	usort($config['ipsec']['mobilekey'], "mobilekeycmp");
569
}
570

    
571
function ipsec_get_number_of_phase2($ikeid) {
572
	global $config;
573
    	$a_phase2 = $config['ipsec']['phase2'];
574

    
575
	$nbph2=0;
576

    
577
    	if (is_array($a_phase2) && count($a_phase2)) {
578
        	foreach ($a_phase2 as $ph2tmp) {
579
            		if ($ph2tmp['ikeid'] == $ikeid) {
580
				$nbph2++;
581
			}
582
		}
583
	}
584

    
585
	return $nbph2;
586
}
587

    
588
function ipsec_get_descr($ikeid) {
589
	global $config;
590

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

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

    
601
	return '';
602
}
603

    
604
function ipsec_get_phase1($ikeid) {
605
        global $config;
606

    
607
        if (!isset($config['ipsec']['phase1']) ||
608
            !is_array($config['ipsec']['phase1']))
609
                return '';
610

    
611
        $a_phase1 = $config['ipsec']['phase1'];
612
        foreach ($a_phase1 as $p1) {
613
                if ($p1['ikeid'] == $ikeid) {
614
                        return $p1;
615
                }
616
        }
617
        unset($a_phase1);
618
}
619

    
620
function ipsec_fixup_ip($ipaddr) {
621
	if (is_ipaddrv6($ipaddr) || is_subnetv6($ipaddr))
622
		return Net_IPv6::compress(Net_IPv6::uncompress($ipaddr));
623
	else
624
		return $ipaddr;
625
}
626

    
627
function ipsec_find_id(& $ph1ent, $side = "local", $rgmap = array()) {
628
	if ($side == "local") {
629
		$id_type = $ph1ent['myid_type'];
630
		$id_data = $ph1ent['myid_data'];
631

    
632
		$addr = ipsec_get_phase1_src($ph1ent);
633
		if (!$addr)
634
			return array();
635
	} elseif ($side = "peer") {
636
		$id_type = $ph1ent['peerid_type'];
637
		$id_data = $ph1ent['peerid_data'];
638

    
639
		if (isset($ph1ent['mobile']))
640
			$addr = "%any";
641
		else
642
			$addr = $ph1ent['remote-gateway'];
643
	} else
644
		return array();
645

    
646

    
647
	$thisid_type = $id_type;
648
	switch ($thisid_type) {
649
	case 'myaddress':
650
		$thisid_type = 'address';
651
		$thisid_data = $addr;
652
		break;
653
	case 'dyn_dns':
654
		$thisid_type = 'dns';
655
		$thisid_data = $id_data;
656
		break;
657
	case 'peeraddress':
658
		$thisid_type = 'address';
659
		$thisid_data = $rgmap[$ph1ent['remote-gateway']];
660
		break;
661
	case 'address':
662
		$thisid_data = $id_data;
663
		break;
664
	case 'fqdn':
665
		$thisid_data = "{$id_data}";
666
		break;
667
	case 'keyid tag':
668
		$thisid_type = 'keyid';
669
		$thisid_data = "{$thisid_data}";
670
		break;
671
	case 'user_fqdn':
672
		$thisid_type = 'userfqdn';
673
		$thisid_data = "{$id_data}";
674
		break;
675
	case 'asn1dn':
676
		$thisid_data = $id_data;
677
		if ($thisid_data && $thisid_data[0] != '"')
678
			$thisid_data = "\"{$id_data}\"";
679
		break;
680
	}
681
	return array($thisid_type, $thisid_data);
682
}
683

    
684
function ipsec_fixup_network($network) {
685
	if (substr($network, -3) == '|/0')
686
		$result = substr($network, 0, -3);
687
	else {
688
		$tmp = explode('|', $network);
689
		if (isset($tmp[1]))
690
			$result = $tmp[1];
691
		else
692
			$result = $tmp[0];
693
		unset($tmp);
694
	}
695

    
696
	return $result;
697
}
698

    
699
function ipsec_new_reqid() {
700
	global $config;
701

    
702
	if (!is_array($config['ipsec']) || !is_array($config['ipsec']['phase2']))
703
		return;
704

    
705
	$ipsecreqid = lock('ipsecreqids', LOCK_EX);
706
	$keyids = array();
707
	$keyid = 1;
708
	foreach ($config['ipsec']['phase2'] as $ph2)
709
		$keyids[$ph2['reqid']] = $ph2['reqid'];
710

    
711
	for ($i = 1; $i < 16000; $i++) {
712
		if (!isset($keyids[$i])) {
713
			$keyid = $i;
714
			break;
715
		}
716
	}
717
	unlock($ipsecreqid);
718

    
719
	return $keyid;
720
}
721

    
722
?>
(29-29/68)