Projet

Général

Profil

Télécharger (19,5 ko) Statistiques
| Branche: | Tag: | Révision:

univnautes / etc / inc / ipsec.inc @ b0cbebeb

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:	/usr/local/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", "app" => "Not daemon", "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
	'aes128gcm' => array( 'name' => 'AES128-GCM', 'keysel' => array( 'lo' => 64, 'hi' => 128, 'step' => 32 ) ),
64
	'aes192gcm' => array( 'name' => 'AES192-GCM', 'keysel' => array( 'lo' => 64, 'hi' => 128, 'step' => 32 ) ),
65
	'aes256gcm' => array( 'name' => 'AES256-GCM', 'keysel' => array( 'lo' => 64, 'hi' => 128, 'step' => 32 ) ),
66
	'blowfish' => array( 'name' => 'Blowfish', 'keysel' => array( 'lo' => 128, 'hi' => 256, 'step' => 64 ) ),
67
	'3des' => array( 'name' => '3DES' ),
68
	'cast128' => array( 'name' => 'CAST128' ),
69
	'des' => array( 'name' => 'DES' ));
70

    
71
$p2_ealgos = array(
72
	'aes' => array( 'name' => 'AES', 'keysel' => array( 'lo' => 128, 'hi' => 256, 'step' => 64 ) ),
73
	'aes128gcm' => array( 'name' => 'AES128-GCM', 'keysel' => array( 'lo' => 64, 'hi' => 128, 'step' => 32 ) ),
74
	'aes192gcm' => array( 'name' => 'AES192-GCM', 'keysel' => array( 'lo' => 64, 'hi' => 128, 'step' => 32 ) ),
75
	'aes256gcm' => array( 'name' => 'AES256-GCM', 'keysel' => array( 'lo' => 64, 'hi' => 128, 'step' => 32 ) ),
76
	'blowfish' => array( 'name' => 'Blowfish', 'keysel' => array( 'lo' => 128, 'hi' => 256, 'step' => 64 ) ),
77
	'3des' => array( 'name' => '3DES' ),
78
	'cast128' => array( 'name' => 'CAST128' ),
79
	'des' => array( 'name' => 'DES' ));
80

    
81
$p1_halgos = array(
82
	'md5' => 'MD5',
83
	'sha1' => 'SHA1',
84
	'sha256' => 'SHA256',
85
	'sha384' => 'SHA384',
86
	'sha512' => 'SHA512',
87
	'aesxcbc' => 'AES-XCBC'
88
);
89

    
90
$p1_dhgroups = array(
91
	1  => '1 (768 bit)',
92
	2  => '2 (1024 bit)',
93
	5  => '5 (1536 bit)',
94
	14 => '14 (2048 bit)',
95
	15 => '15 (3072 bit)',
96
	16 => '16 (4096 bit)',
97
	17 => '17 (6144 bit)',
98
	18 => '18 (8192 bit)',
99
	22 => '22 (1024(sub 160) bit)',
100
	23 => '23 (2048(sub 224) bit)',
101
	24 => '24 (2048(sub 256) bit)'
102
);
103

    
104
$p2_halgos = array(
105
	'hmac_md5' => 'MD5',
106
	'hmac_sha1' => 'SHA1',
107
	'hmac_sha256' => 'SHA256',
108
	'hmac_sha384' => 'SHA384',
109
	'hmac_sha512' => 'SHA512',
110
	'aesxcbc' => 'AES-XCBC'
111
);
112

    
113
$p1_authentication_methods = array(
114
	'hybrid_rsa_server' => array( 'name' => 'Hybrid RSA + Xauth', 'mobile' => true ),
115
	'xauth_rsa_server' => array( 'name' => 'Mutual RSA + Xauth', 'mobile' => true ),
116
	'xauth_psk_server' => array( 'name' => 'Mutual PSK + Xauth', 'mobile' => true ),
117
	'rsasig' => array( 'name' => 'Mutual RSA', 'mobile' => false ),
118
	'pre_shared_key' => array( 'name' => 'Mutual PSK', 'mobile' => false ) );
119

    
120
$p2_modes = array(
121
	'tunnel' => 'Tunnel IPv4',
122
	'tunnel6' => 'Tunnel IPv6',
123
	'transport' => 'Transport');
124

    
125
$p2_protos = array(
126
	'esp' => 'ESP',
127
	'ah' => 'AH');
128

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

    
141
/*
142
 * ikeid management functions
143
 */
144

    
145
function ipsec_ikeid_used($ikeid) {
146
	global $config;
147

    
148
	foreach ($config['ipsec']['phase1'] as $ph1ent)
149
		if( $ikeid == $ph1ent['ikeid'] )
150
			return true;
151

    
152
	return false;
153
}
154

    
155
function ipsec_ikeid_next() {
156

    
157
	$ikeid = 1;
158
	while(ipsec_ikeid_used($ikeid))
159
		$ikeid++;
160

    
161
	return $ikeid;
162
}
163

    
164
/*
165
 * Return phase1 local address
166
 */
167
function ipsec_get_phase1_src(& $ph1ent) {
168

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

    
189
	return $interfaceip;
190
}
191

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

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

    
208
	return $rg;
209
}
210

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

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

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

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

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

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

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

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

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

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

    
340
	return false;
341
}
342

    
343
/*
344
 * Check phase1 communications status
345
 */
346
function ipsec_phase1_status(& $ph1ent) {
347

    
348
	$loc_ip = get_ipsec_tunnel_src($ph1ent);
349
	$rmt_ip = $ph1ent['remote-gateway'];
350

    
351
	if (ipsec_lookup_ipsakmp_sa($loc_ip,$rmt_ip))
352
		return true;
353

    
354
	return false;
355
}
356

    
357
/*
358
 * Check phase2 communications status
359
 */
360
function ipsec_phase2_status(& $spd,& $sad,& $ph1ent,& $ph2ent) {
361

    
362
	$loc_ip = ipsec_get_phase1_src($ph1ent);
363
	$rmt_ip = ipsec_get_phase1_dst($ph1ent);
364

    
365
	$loc_id = ipsec_idinfo_to_cidr($ph2ent['localid'],true,$ph2ent['mode']);
366
	if (!empty($ph2ent['natlocalid']))
367
		$natloc_id = ipsec_idinfo_to_cidr($ph2ent['natlocalid'],true,$ph2ent['mode']);
368
	$rmt_id = ipsec_idinfo_to_cidr($ph2ent['remoteid'],true,$ph2ent['mode']);
369

    
370
	/* check for established SA in both directions */
371
	if( ipsec_lookup_ipsec_sa($spd,$sad,"out",$loc_ip,$rmt_ip,$loc_id,$rmt_id)) {
372
		if (empty($ph2ent['natlocalid']) && ipsec_lookup_ipsec_sa($spd,$sad,"in",$rmt_ip,$loc_ip,$rmt_id,$loc_id))
373
			return true;
374
		else if (!empty($ph2ent['natlocalid']) && ipsec_lookup_ipsec_sa($spd,$sad,"out",$loc_ip,$rmt_ip,$loc_id,$rmt_id))
375
			return true;
376
	}
377

    
378
	return false;
379
}
380

    
381
/*
382
 * Return ISAKMP SA details
383
 */
384
function ipsec_lookup_isakmp_sa($in_srcip,$in_dstip) {
385
	/* TODO : use racconctl to lookup iskamp SA */
386
	return NULL;
387
}
388

    
389
/*
390
 * Return IPsec SA details
391
 */
392
function ipsec_lookup_ipsec_sa(& $spd,& $sad,$dir,$in_srcip,$in_dstip,$in_srcid,$in_dstid) {
393

    
394
	/* match the phase1/2 to an SP */
395
	$in_srcip = ipsec_fixup_ip($in_srcip);
396
	$in_dstip = ipsec_fixup_ip($in_dstip);
397
	$in_srcid = ipsec_fixup_ip($in_srcid);
398
	$in_dstid = ipsec_fixup_ip($in_dstid);
399

    
400
	foreach($spd as $sp) {
401

    
402
		/* match direction */
403

    
404
		if($dir != $sp['dir'])
405
			continue;
406

    
407
		/* match IPs */
408

    
409
		if($in_srcip != ipsec_fixup_ip($sp['src']))
410
			continue;
411
		if($in_dstip != ipsec_fixup_ip($sp['dst']))
412
			continue;
413

    
414
		/* add netbits for address IDs */
415

    
416
		$sp_srcid = $sp['srcid'];
417
		$sp_dstid = $sp['dstid'];
418

    
419
		if (!strstr($sp_srcid,"/")) {
420
			if (is_ipaddrv4($sp_srcid))
421
				$sp_srcid .= '/32';
422
			elseif (is_ipaddrv6($sp_srcid))
423
				$sp_srcid .= '/128';
424
		}
425
		if (!strstr($sp_dstid,"/")) {
426
			if (is_ipaddrv4($sp_dstid))
427
				$sp_dstid .= '/32';
428
			elseif (is_ipaddrv6($sp_dstid))
429
				$sp_dstid .= '/128';
430
		}
431

    
432
		/* match IDs */
433

    
434
		if($in_srcid != ipsec_fixup_ip($sp_srcid))
435
			continue;
436
		if($in_dstid != ipsec_fixup_ip($sp_dstid))
437
			continue;
438

    
439
		/* match the SP to a unique SA by reqid */
440

    
441
		foreach($sad as $sa) {
442

    
443
			/* match REQIDs */
444

    
445
			if($sa[reqid] != $sp[reqid])
446
				continue;
447

    
448
			/* sanitize for NAT-T ports */
449

    
450
			$sa_srcip = $sa['src'];
451
			$sa_dstip = $sa['dst'];
452

    
453
			if (strstr($sa_srcip,"["))
454
				$sa_srcip = substr($sa_srcip,0,strcspn($sa_srcip,"["));
455
			if (strstr($sa_dstip,"["))
456
				$sa_dstip = substr($sa_dstip,0,strcspn($sa_dstip,"["));
457

    
458
			/* match IPs */
459

    
460
			if($in_srcip != ipsec_fixup_ip($sa_srcip))
461
				continue;
462
			if($in_dstip != ipsec_fixup_ip($sa_dstip))
463
				continue;
464

    
465
			return $sa;
466
		}
467
	}
468

    
469
	return NULL;
470
}
471

    
472
function ipsec_smp_dump_status() {
473
	global $config, $g, $custom_listtags;
474

    
475
	if (!file_exists("{$g['varrun_path']}/charon.xml")) {
476
		log_error("IPSec daemon seems to have issues or not running!");
477
		return;
478
	}
479

    
480
	$fd = @fsockopen("unix://{$g['varrun_path']}/charon.xml");
481
	if (!$fd) {
482
		log_error("Could not read status from ipsec");
483
		return;
484
	}
485
	$query = '<?xml version="1.0"?><message xmlns="http://www.strongswan.org/smp/1.0" type="request" id="1">';
486
	$query .= '<query><ikesalist/></query></message>';
487

    
488
	@fwrite($fd, $query);
489
	$response = "";
490
	while (!strstr($sread, "</message>")) {
491
		$sread = fgets($fd);
492
		$response .= $sread;
493
	}
494
	fclose($fd);
495

    
496
	@file_put_contents("{$g['tmp_path']}/smp_status.xml", $response);
497
	unset($response, $sread);
498

    
499
	$custom_listtags = array('ikesa', 'childsa', 'network');
500
	$response = parse_xml_config("{$g['tmp_path']}/smp_status.xml", "message");
501
	@unlink("{$g['tmp_path']}/smp_status.xml");
502
	unset($custom_listtags);
503

    
504
	return $response;
505
}
506

    
507
/*
508
 * Return dump of SPD table
509
 */
510
function ipsec_dump_spd()
511
{
512
	$fd = @popen("/usr/local/sbin/setkey -DP", "r");
513
	$spd = array();
514
	if ($fd) {
515
		while (!feof($fd)) {
516
			$line = chop(fgets($fd));
517
			if (!$line)
518
				continue;
519
			if ($line == "No SPD entries.")
520
				break;
521
			if ($line[0] != "\t") {
522
				if (is_array($cursp))
523
					$spd[] = $cursp;
524
				$cursp = array();
525
				$linea = explode(" ", $line);
526
				$cursp['srcid'] = substr($linea[0], 0, strpos($linea[0], "["));
527
				$cursp['dstid'] = substr($linea[1], 0, strpos($linea[1], "["));
528
				$i = 0;
529
			} else if (is_array($cursp)) {
530
				$linea = explode(" ", trim($line));
531
				switch($i)
532
				{
533
					case 1:
534
						if ($linea[1] == "none")	/* don't show default anti-lockout rule */
535
							unset($cursp);
536
						else
537
							$cursp['dir'] = $linea[0];
538
						break;
539
					case 2:
540
						$upperspec = explode("/", $linea[0]);
541
						$cursp['proto'] = $upperspec[0];
542
						list($cursp['src'], $cursp['dst']) = explode("-", $upperspec[2]);
543
						$cursp['reqid'] =  substr($upperspec[3], strpos($upperspec[3], "#")+1);
544
						break;
545
				}
546
			}
547
			$i++;
548
		}
549
		if (is_array($cursp) && count($cursp))
550
			$spd[] = $cursp;
551
		pclose($fd);
552
	}
553

    
554
	return $spd;
555
}
556

    
557
/*
558
 * Return dump of SAD table
559
 */
560
function ipsec_dump_sad()
561
{
562
	$fd = @popen("/usr/local/sbin/setkey -D", "r");
563
	$sad = array();
564
	if ($fd) {
565
		while (!feof($fd)) {
566
			$line = chop(fgets($fd));
567
			if (!$line || $line[0] == " ")
568
				continue;
569
			if ($line == "No SAD entries.")
570
				break;
571
			if ($line[0] != "\t")
572
			{
573
				if (is_array($cursa))
574
					$sad[] = $cursa;
575
				$cursa = array();
576
				list($cursa['src'],$cursa['dst']) = explode(" ", $line);
577
				$i = 0;
578
			}
579
			else
580
			{
581
				$linea = explode(" ", trim($line));
582
				switch ($i) {
583
					case 1:
584
						$cursa['proto'] = $linea[0];
585
						$cursa['spi'] = substr($linea[2], strpos($linea[2], "x")+1, -1);
586
						$reqid = substr($linea[3], strpos($linea[3], "=")+1);
587
						$cursa['reqid'] = substr($reqid, 0, strcspn($reqid,"("));
588
						break;
589
					case 2:
590
						$cursa['ealgo'] = $linea[1];
591
						break;
592
					case 3:
593
						$cursa['aalgo'] = $linea[1];
594
						break;
595
					case 8:
596
						$sadata = explode("(", $linea[1]);
597
						$cursa['data'] = $sadata[0] . " B";
598
						break;
599
				}
600
			}
601
			$i++;
602
		}
603
		if (is_array($cursa) && count($cursa))
604
			$sad[] = $cursa;
605
		pclose($fd);
606
	}
607

    
608
	return $sad;
609
}
610

    
611
/*
612
 * Return dump of mobile user list
613
 */
614
function ipsec_dump_mobile() {
615
	$command = "/usr/local/sbin/racoonctl show-users";
616
	$fd = @popen($command, "r");
617
	$mobile = array();
618
	if ($fd) {
619
		while (!feof($fd)) {
620
			$user = array();
621
			$line = chop(fgets($fd));
622
			if (!$line)
623
				continue;
624
			if ($line == "User|Source|Destination|CreatedOn|SPI")
625
				continue;
626

    
627
			// jim|192.168.20.243:4500|192.168.20.5:24146|2012-05-25 09:54:39|989d10e1e2d4eca4:7243830d5fd2afe7
628
			$linea = explode("|", trim($line));
629
			$user['username'] = $linea[0];
630
			$user['local'] = $linea[1];
631
			$user['remote'] = $linea[2];
632
			$user['logintime'] = $linea[3];
633
			$user['spi'] = $linea[4];
634
			if (!empty($user['username']))
635
				$mobile[] = $user;
636
		}
637
		pclose($fd);
638
	}
639

    
640
	return $mobile;
641
}
642

    
643
function ipsec_mobilekey_sort() {
644
	global $config;
645

    
646
	function mobilekeycmp($a, $b) {
647
		return strcmp($a['ident'][0], $b['ident'][0]);
648
	}
649

    
650
	usort($config['ipsec']['mobilekey'], "mobilekeycmp");
651
}
652

    
653
function ipsec_get_number_of_phase2($ikeid) {
654
	global $config;
655
    	$a_phase2 = $config['ipsec']['phase2'];
656

    
657
	$nbph2=0;
658

    
659
    	if (is_array($a_phase2) && count($a_phase2)) {
660
        	foreach ($a_phase2 as $ph2tmp) {
661
            		if ($ph2tmp['ikeid'] == $ikeid) {
662
				$nbph2++;
663
			}
664
		}
665
	}
666

    
667
	return $nbph2;
668
}
669

    
670
function ipsec_get_descr($ikeid) {
671
	global $config;
672

    
673
	if (!isset($config['ipsec']['phase1']) ||
674
	    !is_array($config['ipsec']['phase1']))
675
		return "";
676

    
677
	$descr = '';
678
	$a_phase1 = $config['ipsec']['phase1'];
679
	foreach ($a_phase1 as $p1) {
680
		if ($p1['ikeid'] == $ikeid) {
681
			$descr = $p1['descr'];
682
			break;
683
		}
684
	}
685
	unset($a_phase1);
686

    
687
	return $descr;
688
}
689

    
690
function ipsec_get_descr_by_peerconfig($peerconfig) {
691
	return ipsec_get_descr(substr($peerconfig, strrpos($peerconfig, '-') + 1));
692
}
693

    
694
function ipsec_disconnect_mobile($username) {
695
	if (empty($username))
696
		return false;
697
	exec("/usr/local/sbin/racoonctl logout-user " . escapeshellarg($username));
698
}
699

    
700
function ipsec_fixup_ip($ipaddr) {
701
	if (is_ipaddrv6($ipaddr) || is_subnetv6($ipaddr))
702
		return Net_IPv6::compress(Net_IPv6::uncompress($ipaddr));
703
	else
704
		return $ipaddr;
705
}
706

    
707
function ipsec_find_id(& $ph1ent, $side = "local", $rgmap = array()) {
708
	if ($side == "local") {
709
		$id_type = $ph1ent['myid_type'];
710
		$id_data = $ph1ent['myid_data'];
711

    
712
		$addr = ipsec_get_phase1_src($ph1ent);
713
		if (!$addr)
714
			return array();
715
	} elseif ($side = "peer") {
716
		$id_type = $ph1ent['peerid_type'];
717
		$id_data = $ph1ent['peerid_data'];
718

    
719
		if (isset($ph1ent['mobile']))
720
			$addr = "%any";
721
		else
722
			$addr = $ph1ent['remote-gateway'];
723
	} else {
724
		return array();
725
	}
726

    
727

    
728
	$thisid_type = $id_type;
729
	switch ($thisid_type) {
730
	case "myaddress":
731
		$thisid_type = "address";
732
		$thisid_data = $addr;
733
		break;
734

    
735
	case "dyn_dns":
736
		$thisid_type = "address";
737
		$thisid_data = resolve_retry($id_data);
738
		break;
739

    
740
	case "peeraddress":
741
		$thisid_type = "address";
742
		$thisid_data = $rgmap[$ph1ent['remote-gateway']];
743
		break;
744

    
745
	case "address";
746
		$thisid_data = $id_data;
747
		break;
748

    
749
	case "fqdn";
750
	case "keyid tag";
751
	case "user_fqdn";
752
	case "asn1dn";
753
		$thisid_data = $id_data;
754
		if( $thisid_data )
755
			$thisid_data = "{$thisid_data}";
756
		break;
757
	}
758
	return array($thisid_type, $thisid_data);
759
}
760
?>
(29-29/68)