Project

General

Profile

Download (18.7 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
	}
175

    
176
	return false;
177
}
178

    
179
function ipsec_ikeid_next() {
180

    
181
	$ikeid = 1;
182
	while (ipsec_ikeid_used($ikeid)) {
183
		$ikeid++;
184
	}
185

    
186
	return $ikeid;
187
}
188

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

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

    
214
	return $interfaceip;
215
}
216

    
217
/*
218
 * Return phase1 local address
219
 */
220
function ipsec_get_phase1_dst(& $ph1ent) {
221
	global $g;
222

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

    
236
	return $rg;
237
}
238

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

    
245
	switch ($idinfo['type']) {
246
		case "address":
247
			if ($addrbits) {
248
				if ($mode == "tunnel6") {
249
					return $idinfo['address']."/128";
250
				} else {
251
					return $idinfo['address']."/32";
252
				}
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

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

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

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

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

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

    
352
/*
353
 * Return phase1 association for phase2
354
 */
355
function ipsec_lookup_phase1(& $ph2ent,& $ph1ent) {
356
	global $config;
357

    
358
	if (!is_array($config['ipsec'])) {
359
		return false;
360
	}
361
	if (!is_array($config['ipsec']['phase1'])) {
362
		return false;
363
	}
364
	if (empty($config['ipsec']['phase1'])) {
365
		return false;
366
	}
367

    
368
	foreach ($config['ipsec']['phase1'] as $ph1tmp) {
369
		if ($ph1tmp['ikeid'] == $ph2ent['ikeid']) {
370
			$ph1ent = $ph1tmp;
371
			return $ph1ent;
372
		}
373
	}
374

    
375
	return false;
376
}
377

    
378
/*
379
 * Check phase1 communications status
380
 */
381
function ipsec_phase1_status(&$ipsec_status, $ikeid) {
382

    
383
	foreach ($ipsec_status as $ike) {
384
		if ($ike['id'] == $ikeid) {
385
			if ($ike['status'] == 'established') {
386
				return true;
387
			}
388
		}
389
	}
390

    
391
	return false;
392
}
393

    
394
/*
395
 * Check phase2 communications status
396
 */
397
function ipsec_phase2_status(&$ipsec_status, &$phase2) {
398

    
399
	if (ipsec_lookup_phase1($ph2ent,$ph1ent)) {
400
		return ipsec_phase1_status($ipsec_status, $ph1ent['ikeid']);
401
	}
402

    
403
	return false;
404
}
405

    
406
function ipsec_smp_dump_status() {
407
	global $config, $g, $custom_listtags;
408

    
409
	if (!file_exists("{$g['varrun_path']}/charon.xml")) {
410
		log_error("IPsec daemon not running or has a problem!");
411
		return;
412
	}
413

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

    
422
	@fwrite($fd, $query);
423
	$response = "";
424
	while (!strstr($sread, "</message>")) {
425
		$sread = fgets($fd);
426
		if ($sread === false) {
427
			break;
428
		}
429
		$response .= $sread;
430
	}
431
	fclose($fd);
432

    
433
	if ($sread === false) {
434
		log_error("Error during reading of status from IPsec");
435
		return;
436
	}
437

    
438
	@file_put_contents("{$g['tmp_path']}/smp_status.xml", $response);
439
	unset($response, $sread);
440

    
441
	$custom_listtags = array('ikesa', 'childsa', 'network', 'auth');
442
	$response = parse_xml_config("{$g['tmp_path']}/smp_status.xml", "message");
443
	@unlink("{$g['tmp_path']}/smp_status.xml");
444
	unset($custom_listtags);
445

    
446
	return $response;
447
}
448

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

    
501
	return $spd;
502
}
503

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

    
555
	return $sad;
556
}
557

    
558
/*
559
 * Return dump of mobile user list
560
 */
561
function ipsec_dump_mobile() {
562
	global $g, $custom_listtags;
563

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

    
566
	if (!file_exists("{$g['tmp_path']}/strongswan_leases.xml")) {
567
		log_error(gettext("Unable to find IPsec daemon leases file. Could not display mobile user stats!"));
568
		return array();
569
	}
570

    
571
	/* This is needed for fixing #4130 */
572
	if (filesize("{$g['tmp_path']}/strongswan_leases.xml") < 200) {
573
		return array();
574
	}
575

    
576
	$custom_listtags = array('lease', 'pool');
577
	$response = parse_xml_config("{$g['tmp_path']}/strongswan_leases.xml", "leases");
578
	@unlink("{$g['tmp_path']}/strongswan_leases.xml");
579
	unset($custom_listtags, $_gb);
580

    
581
	return $response;
582
}
583

    
584
function ipsec_mobilekey_sort() {
585
	global $config;
586

    
587
	function mobilekeycmp($a, $b) {
588
		return strcmp($a['ident'][0], $b['ident'][0]);
589
	}
590

    
591
	usort($config['ipsec']['mobilekey'], "mobilekeycmp");
592
}
593

    
594
function ipsec_get_number_of_phase2($ikeid) {
595
	global $config;
596
	$a_phase2 = $config['ipsec']['phase2'];
597

    
598
	$nbph2=0;
599

    
600
	if (is_array($a_phase2) && count($a_phase2)) {
601
		foreach ($a_phase2 as $ph2tmp) {
602
			if ($ph2tmp['ikeid'] == $ikeid) {
603
				$nbph2++;
604
			}
605
		}
606
	}
607

    
608
	return $nbph2;
609
}
610

    
611
function ipsec_get_descr($ikeid) {
612
	global $config;
613

    
614
	if (!isset($config['ipsec']['phase1']) ||
615
	    !is_array($config['ipsec']['phase1'])) {
616
		return '';
617
	}
618

    
619
	foreach ($config['ipsec']['phase1'] as $p1) {
620
		if ($p1['ikeid'] == $ikeid) {
621
			return $p1['descr'];
622
		}
623
	}
624

    
625
	return '';
626
}
627

    
628
function ipsec_get_phase1($ikeid) {
629
		global $config;
630

    
631
		if (!isset($config['ipsec']['phase1']) ||
632
		    !is_array($config['ipsec']['phase1'])) {
633
			return '';
634
		}
635

    
636
		$a_phase1 = $config['ipsec']['phase1'];
637
		foreach ($a_phase1 as $p1) {
638
			if ($p1['ikeid'] == $ikeid) {
639
				return $p1;
640
			}
641
		}
642
		unset($a_phase1);
643
}
644

    
645
function ipsec_fixup_ip($ipaddr) {
646
	if (is_ipaddrv6($ipaddr) || is_subnetv6($ipaddr)) {
647
		return Net_IPv6::compress(Net_IPv6::uncompress($ipaddr));
648
	} else {
649
		return $ipaddr;
650
	}
651
}
652

    
653
function ipsec_find_id(& $ph1ent, $side = "local", $rgmap = array()) {
654
	if ($side == "local") {
655
		$id_type = $ph1ent['myid_type'];
656
		$id_data = $ph1ent['myid_data'];
657

    
658
		$addr = ipsec_get_phase1_src($ph1ent);
659
		if (!$addr) {
660
			return array();
661
		}
662
	} elseif ($side = "peer") {
663
		$id_type = $ph1ent['peerid_type'];
664
		$id_data = $ph1ent['peerid_data'];
665

    
666
		if (isset($ph1ent['mobile'])) {
667
			$addr = "%any";
668
		} else {
669
			$addr = $ph1ent['remote-gateway'];
670
		}
671
	} else {
672
		return array();
673
	}
674

    
675

    
676
	$thisid_type = $id_type;
677
	switch ($thisid_type) {
678
		case 'myaddress':
679
			$thisid_type = 'address';
680
			$thisid_data = $addr;
681
			break;
682
		case 'dyn_dns':
683
			$thisid_type = 'dns';
684
			$thisid_data = $id_data;
685
			break;
686
		case 'peeraddress':
687
			$thisid_type = 'address';
688
			$thisid_data = $rgmap[$ph1ent['remote-gateway']];
689
			break;
690
		case 'address':
691
			$thisid_data = $id_data;
692
			break;
693
		case 'fqdn':
694
			$thisid_data = "{$id_data}";
695
			break;
696
		case 'keyid tag':
697
			$thisid_type = 'keyid';
698
			$thisid_data = "{$thisid_data}";
699
			break;
700
		case 'user_fqdn':
701
			$thisid_type = 'userfqdn';
702
			$thisid_data = "{$id_data}";
703
			break;
704
		case 'asn1dn':
705
			$thisid_data = $id_data;
706
			if ($thisid_data && $thisid_data[0] != '"') {
707
				$thisid_data = "\"{$id_data}\"";
708
			}
709
			break;
710
	}
711
	return array($thisid_type, $thisid_data);
712
}
713

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

    
727
	return $result;
728
}
729

    
730
function ipsec_new_reqid() {
731
	global $config;
732

    
733
	if (!is_array($config['ipsec']) || !is_array($config['ipsec']['phase2'])) {
734
		return;
735
	}
736

    
737
	$ipsecreqid = lock('ipsecreqids', LOCK_EX);
738
	$keyids = array();
739
	$keyid = 1;
740
	foreach ($config['ipsec']['phase2'] as $ph2) {
741
		$keyids[$ph2['reqid']] = $ph2['reqid'];
742
	}
743

    
744
	for ($i = 1; $i < 16000; $i++) {
745
		if (!isset($keyids[$i])) {
746
			$keyid = $i;
747
			break;
748
		}
749
	}
750
	unlock($ipsecreqid);
751

    
752
	return $keyid;
753
}
754

    
755
?>
(29-29/68)