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
	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 (strpos($ph1ent['interface'], '_vip')) {
194
				$if = $ph1ent['interface'];
195
			} else {
196
				$if = get_failover_interface($ph1ent['interface']);
197
			}
198
			if ($ph1ent['protocol'] == "inet6") {
199
				$interfaceip = get_interface_ipv6($if);
200
			} else {
201
				$interfaceip = get_interface_ip($if);
202
			}
203
		} else {
204
			$interfaceip=$ph1ent['interface'];
205
		}
206
	} else {
207
		$if = "wan";
208
		if ($ph1ent['protocol'] == "inet6")
209
			$interfaceip = get_interface_ipv6($if);
210
		else
211
			$interfaceip = get_interface_ip($if);
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
	$rg = $ph1ent['remote-gateway'];
226
	if (!is_ipaddr($rg)) {
227
		if(! platform_booting())
228
			return resolve_retry($rg);
229
	}
230
	if(!is_ipaddr($rg))
231
		return false;
232

    
233
	return $rg;
234
}
235

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

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

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

    
278
/*
279
 * Return phase2 idinfo in address/netmask format
280
 */
281
function ipsec_idinfo_to_subnet(& $idinfo,$addrbits = false) {
282
	global $config;
283

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

    
317
/*
318
 *  Return phase2 idinfo in text format
319
 */
320
function ipsec_idinfo_to_text(& $idinfo) {
321
	global $config;
322

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

    
345
/*
346
 * Return phase1 association for phase2
347
 */
348
function ipsec_lookup_phase1(& $ph2ent,& $ph1ent) {
349
	global $config;
350

    
351
	if (!is_array($config['ipsec']))
352
		return false;
353
	if (!is_array($config['ipsec']['phase1']))
354
		return false;
355
	if (empty($config['ipsec']['phase1']))
356
		return false;
357

    
358
	foreach ($config['ipsec']['phase1'] as $ph1tmp) {
359
	    if ($ph1tmp['ikeid'] == $ph2ent['ikeid']) {
360
		$ph1ent = $ph1tmp;
361
		return $ph1ent;
362
	    }
363
	}
364

    
365
	return false;
366
}
367

    
368
/*
369
 * Check phase1 communications status
370
 */
371
function ipsec_phase1_status(&$ipsec_status, $ikeid) {
372

    
373
	foreach ($ipsec_status as $ike) {
374
		if ($ike['id'] == $ikeid) {
375
			if ($ike['status'] == 'established')
376
				return true;
377
		}
378
	}
379

    
380
	return false;
381
}
382

    
383
/*
384
 * Check phase2 communications status
385
 */
386
function ipsec_phase2_status(&$ipsec_status, &$phase2) {
387

    
388
	if (ipsec_lookup_phase1($ph2ent,$ph1ent))
389
		return ipsec_phase1_status($ipsec_status, $ph1ent['ikeid']);
390

    
391
	return false;
392
}
393

    
394
function ipsec_smp_dump_status() {
395
	global $config, $g, $custom_listtags;
396

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

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

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

    
424
	if ($sread === false) {
425
		log_error("Error during reading of status from IPsec");
426
		return;
427
	}
428

    
429
	@file_put_contents("{$g['tmp_path']}/smp_status.xml", $response);
430
	unset($response, $sread);
431

    
432
	$custom_listtags = array('ikesa', 'childsa', 'network', 'auth');
433
	$response = parse_xml_config("{$g['tmp_path']}/smp_status.xml", "message");
434
	@unlink("{$g['tmp_path']}/smp_status.xml");
435
	unset($custom_listtags);
436

    
437
	return $response;
438
}
439

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

    
488
	return $spd;
489
}
490

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

    
542
	return $sad;
543
}
544

    
545
/*
546
 * Return dump of mobile user list
547
 */
548
function ipsec_dump_mobile() {
549
	global $g, $custom_listtags;
550

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

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

    
558
	/* This is needed for fixing #4130 */
559
	if (filesize("{$g['tmp_path']}/strongswan_leases.xml") < 200)
560
		return array();
561

    
562
	$custom_listtags = array('lease', 'pool');
563
	$response = parse_xml_config("{$g['tmp_path']}/strongswan_leases.xml", "leases");
564
	@unlink("{$g['tmp_path']}/strongswan_leases.xml");
565
	unset($custom_listtags, $_gb);
566

    
567
	return $response;
568
}
569

    
570
function ipsec_mobilekey_sort() {
571
	global $config;
572

    
573
	function mobilekeycmp($a, $b) {
574
		return strcmp($a['ident'][0], $b['ident'][0]);
575
	}
576

    
577
	usort($config['ipsec']['mobilekey'], "mobilekeycmp");
578
}
579

    
580
function ipsec_get_number_of_phase2($ikeid) {
581
	global $config;
582
    	$a_phase2 = $config['ipsec']['phase2'];
583

    
584
	$nbph2=0;
585

    
586
    	if (is_array($a_phase2) && count($a_phase2)) {
587
        	foreach ($a_phase2 as $ph2tmp) {
588
            		if ($ph2tmp['ikeid'] == $ikeid) {
589
				$nbph2++;
590
			}
591
		}
592
	}
593

    
594
	return $nbph2;
595
}
596

    
597
function ipsec_get_descr($ikeid) {
598
	global $config;
599

    
600
	if (!isset($config['ipsec']['phase1']) ||
601
	    !is_array($config['ipsec']['phase1']))
602
		return '';
603

    
604
	foreach ($config['ipsec']['phase1'] as $p1) {
605
		if ($p1['ikeid'] == $ikeid) {
606
			return $p1['descr'];
607
		}
608
	}
609

    
610
	return '';
611
}
612

    
613
function ipsec_get_phase1($ikeid) {
614
        global $config;
615

    
616
        if (!isset($config['ipsec']['phase1']) ||
617
            !is_array($config['ipsec']['phase1']))
618
                return '';
619

    
620
        $a_phase1 = $config['ipsec']['phase1'];
621
        foreach ($a_phase1 as $p1) {
622
                if ($p1['ikeid'] == $ikeid) {
623
                        return $p1;
624
                }
625
        }
626
        unset($a_phase1);
627
}
628

    
629
function ipsec_fixup_ip($ipaddr) {
630
	if (is_ipaddrv6($ipaddr) || is_subnetv6($ipaddr))
631
		return Net_IPv6::compress(Net_IPv6::uncompress($ipaddr));
632
	else
633
		return $ipaddr;
634
}
635

    
636
function ipsec_find_id(& $ph1ent, $side = "local", $rgmap = array()) {
637
	if ($side == "local") {
638
		$id_type = $ph1ent['myid_type'];
639
		$id_data = $ph1ent['myid_data'];
640

    
641
		$addr = ipsec_get_phase1_src($ph1ent);
642
		if (!$addr)
643
			return array();
644
	} elseif ($side == "peer") {
645
		$id_type = $ph1ent['peerid_type'];
646
		$id_data = $ph1ent['peerid_data'];
647

    
648
		if (isset($ph1ent['mobile']))
649
			$addr = "%any";
650
		else
651
			$addr = $ph1ent['remote-gateway'];
652
	} else {
653
		return array();
654
	}
655

    
656

    
657
	$thisid_type = $id_type;
658
	switch ($thisid_type) {
659
	case "myaddress":
660
		$thisid_type = "address";
661
		$thisid_data = $addr;
662
		break;
663

    
664
	case "dyn_dns":
665
		$thisid_type = "address";
666
		$thisid_data = resolve_retry($id_data);
667
		break;
668

    
669
	case "peeraddress":
670
		$thisid_type = "address";
671
		$thisid_data = $rgmap[$ph1ent['remote-gateway']];
672
		break;
673

    
674
	case "address";
675
		$thisid_data = $id_data;
676
		break;
677

    
678
	case "fqdn";
679
	case "keyid tag";
680
	case "user_fqdn";
681
		$thisid_data = $id_data;
682
		break;
683
	case "asn1dn";
684
		$thisid_data = $id_data;
685
		if( $thisid_data && $thisid_data[0] != '"')
686
			$thisid_data = "\"{$thisid_data}\"";
687
		break;
688
	}
689
	return array($thisid_type, $thisid_data);
690
}
691

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

    
704
	return $result;
705
}
706

    
707
function ipsec_new_reqid() {
708
	global $config;
709

    
710
	if (!is_array($config['ipsec']) || !is_array($config['ipsec']['phase2']))
711
		return;
712

    
713
	$ipsecreqid = lock('ipsecreqids', LOCK_EX);
714
	$keyids = array();
715
	$keyid = 1;
716
	foreach ($config['ipsec']['phase2'] as $ph2)
717
		$keyids[$ph2['reqid']] = $ph2['reqid'];
718

    
719
	for ($i = 1; $i < 16000; $i++) {
720
		if (!isset($keyids[$i])) {
721
			$keyid = $i;
722
			break;
723
		}
724
	}
725
	unlock($ipsecreqid);
726

    
727
	return $keyid;
728
}
729

    
730
?>
(29-29/68)