Project

General

Profile

Download (20.9 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
 * ipsec.inc
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6
 * Copyright (c) 2008 Shrew Soft Inc.
7
 * Copyright (c) 2007-2018 Rubicon Communications, LLC (Netgate)
8
 * All rights reserved.
9
 *
10
 * Licensed under the Apache License, Version 2.0 (the "License");
11
 * you may not use this file except in compliance with the License.
12
 * You may obtain a copy of the License at
13
 *
14
 * http://www.apache.org/licenses/LICENSE-2.0
15
 *
16
 * Unless required by applicable law or agreed to in writing, software
17
 * distributed under the License is distributed on an "AS IS" BASIS,
18
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19
 * See the License for the specific language governing permissions and
20
 * limitations under the License.
21
 */
22

    
23
/* IPsec defines */
24
global $ipsec_loglevels;
25
$ipsec_loglevels = array(
26
	"dmn" => gettext("Daemon"),
27
	"mgr" => gettext("SA Manager"),
28
	"ike" => gettext("IKE SA"),
29
	"chd" => gettext("IKE Child SA"),
30
	"job" => gettext("Job Processing"),
31
	"cfg" => gettext("Configuration backend"),
32
	"knl" => gettext("Kernel Interface"),
33
	"net" => gettext("Networking"),
34
	"asn" => gettext("ASN encoding"),
35
	"enc" => gettext("Message encoding"),
36
	"imc" => gettext("Integrity checker"),
37
	"imv" => gettext("Integrity Verifier"),
38
	"pts" => gettext("Platform Trust Service"),
39
	"tls" => gettext("TLS handler"),
40
	"esp" => gettext("IPsec traffic"),
41
	"lib" => gettext("StrongSwan Lib")
42
);
43

    
44
global $ipsec_log_sevs;
45
$ipsec_log_sevs = array(
46
	'-1' => gettext('Silent'),
47
	'0' => gettext('Audit'),
48
	'1' => gettext('Control'),
49
	'2' => gettext('Diag'),
50
	'3' => gettext('Raw'),
51
	'4' => gettext('Highest')
52
);
53

    
54
global $ipsec_log_cats;
55
$ipsec_log_cats = array(
56
	"dmn" => gettext("Daemon"),
57
	"mgr" => gettext("SA Manager"),
58
	"ike" => gettext("IKE SA"),
59
	"chd" => gettext("IKE Child SA"),
60
	"job" => gettext("Job Processing"),
61
	"cfg" => gettext("Configuration backend"),
62
	"knl" => gettext("Kernel Interface"),
63
	"net" => gettext("Networking"),
64
	"asn" => gettext("ASN encoding"),
65
	"enc" => gettext("Message encoding"),
66
	"imc" => gettext("Integrity checker"),
67
	"imv" => gettext("Integrity Verifier"),
68
	"pts" => gettext("Platform Trust Service"),
69
	"tls" => gettext("TLS handler"),
70
	"esp" => gettext("IPsec traffic"),
71
	"lib" => gettext("StrongSwan Lib")
72
);
73

    
74
global $my_identifier_list;
75
$my_identifier_list = array(
76
	'myaddress' => array('desc' => gettext('My IP address'), 'mobile' => true),
77
	'address' => array('desc' => gettext('IP address'), 'mobile' => true),
78
	'fqdn' => array('desc' => gettext('Distinguished name'), 'mobile' => true),
79
	'user_fqdn' => array('desc' => gettext('User distinguished name'), 'mobile' => true),
80
	'asn1dn' => array('desc' => gettext('ASN.1 distinguished Name'), 'mobile' => true),
81
	'keyid tag' => array('desc' => gettext('KeyID tag'), 'mobile' => true),
82
	'dyn_dns' => array('desc' => gettext('Dynamic DNS'), 'mobile' => true)
83
);
84

    
85
global $peer_identifier_list;
86
$peer_identifier_list = array(
87
	'any' => array('desc' => gettext('Any'), 'mobile' => true),
88
	'peeraddress' => array('desc' => gettext('Peer IP address'), 'mobile' => false),
89
	'address' => array('desc' => gettext('IP address'), 'mobile' => false),
90
	'fqdn' => array('desc' => gettext('Distinguished name'), 'mobile' => true),
91
	'user_fqdn' => array('desc' => gettext('User distinguished name'), 'mobile' => true),
92
	'asn1dn' => array('desc' => gettext('ASN.1 distinguished Name'), 'mobile' => true),
93
	'keyid tag' => array('desc' =>gettext('KeyID tag'), 'mobile' => true)
94
);
95

    
96
global $ipsec_idhandling;
97
$ipsec_idhandling = array(
98
	'yes' => 'YES', 'no' => 'NO', 'never' => 'NEVER', 'keep' => 'KEEP'
99
);
100

    
101
global $p1_ealgos;
102
$p1_ealgos = array(
103
	'aes' => array('name' => 'AES', 'keysel' => array('lo' => 128, 'hi' => 256, 'step' => 64)),
104
	'aes128gcm' => array('name' => 'AES128-GCM', 'keysel' => array('lo' => 64, 'hi' => 128, 'step' => 32)),
105
	'aes192gcm' => array('name' => 'AES192-GCM', 'keysel' => array('lo' => 64, 'hi' => 128, 'step' => 32)),
106
	'aes256gcm' => array('name' => 'AES256-GCM', 'keysel' => array('lo' => 64, 'hi' => 128, 'step' => 32)),
107
	'blowfish' => array('name' => 'Blowfish', 'keysel' => array('lo' => 128, 'hi' => 256, 'step' => 64)),
108
	'3des' => array('name' => '3DES'),
109
	'cast128' => array('name' => 'CAST128')
110
);
111

    
112
global $p2_ealgos;
113
$p2_ealgos = array(
114
	'aes' => array('name' => 'AES', 'keysel' => array('lo' => 128, 'hi' => 256, 'step' => 64)),
115
	'aes128gcm' => array('name' => 'AES128-GCM', 'keysel' => array('lo' => 64, 'hi' => 128, 'step' => 32)),
116
	'aes192gcm' => array('name' => 'AES192-GCM', 'keysel' => array('lo' => 64, 'hi' => 128, 'step' => 32)),
117
	'aes256gcm' => array('name' => 'AES256-GCM', 'keysel' => array('lo' => 64, 'hi' => 128, 'step' => 32)),
118
	'blowfish' => array('name' => 'Blowfish', 'keysel' => array('lo' => 128, 'hi' => 256, 'step' => 64)),
119
	'3des' => array('name' => '3DES'),
120
	'cast128' => array('name' => 'CAST128')
121
);
122

    
123
global $p1_halgos;
124
$p1_halgos = array(
125
	'md5' => 'MD5',
126
	'sha1' => 'SHA1',
127
	'sha256' => 'SHA256',
128
	'sha384' => 'SHA384',
129
	'sha512' => 'SHA512',
130
	'aesxcbc' => 'AES-XCBC'
131
);
132

    
133
global $p1_dhgroups;
134
$p1_dhgroups = array(
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
	19 => '19 (nist ecp256)',
144
	20 => '20 (nist ecp384)',
145
	21 => '21 (nist ecp521)',
146
	22 => '22 (1024(sub 160) bit)',
147
	23 => '23 (2048(sub 224) bit)',
148
	24 => '24 (2048(sub 256) bit)',
149
	28 => '28 (brainpool ecp256)',
150
	29 => '29 (brainpool ecp384)',
151
	30 => '30 (brainpool ecp512)'
152
);
153

    
154
global $p2_halgos;
155
$p2_halgos = array(
156
	'hmac_md5' => 'MD5',
157
	'hmac_sha1' => 'SHA1',
158
	'hmac_sha256' => 'SHA256',
159
	'hmac_sha384' => 'SHA384',
160
	'hmac_sha512' => 'SHA512',
161
	'aesxcbc' => 'AES-XCBC'
162
);
163

    
164
global $p1_authentication_methods;
165
$p1_authentication_methods = array(
166
	'hybrid_rsa_server' => array('name' => gettext('Hybrid RSA + Xauth'), 'mobile' => true),
167
	'xauth_rsa_server' => array('name' => gettext('Mutual RSA + Xauth'), 'mobile' => true),
168
	'xauth_psk_server' => array('name' => gettext('Mutual PSK + Xauth'), 'mobile' => true),
169
	'eap-tls' => array('name' => gettext('EAP-TLS'), 'mobile' => true),
170
	'eap-radius' => array('name' => gettext('EAP-RADIUS'), 'mobile' => true),
171
	'eap-mschapv2' => array('name' => gettext('EAP-MSChapv2'), 'mobile' => true),
172
	'rsasig' => array('name' => gettext('Mutual RSA'), 'mobile' => false),
173
	'pre_shared_key' => array('name' => gettext('Mutual PSK'), 'mobile' => false)
174
);
175

    
176
global $ipsec_preshared_key_type;
177
$ipsec_preshared_key_type = array(
178
	'PSK' => 'PSK',
179
	'EAP' => 'EAP'
180
);
181

    
182
global $p2_modes;
183
$p2_modes = array(
184
	'tunnel' => gettext('Tunnel IPv4'),
185
	'tunnel6' => gettext('Tunnel IPv6'),
186
	'transport' => gettext('Transport')
187
);
188

    
189
global $p2_protos;
190
$p2_protos = array(
191
	'esp' => 'ESP',
192
	'ah' => 'AH'
193
);
194

    
195
global $p2_pfskeygroups;
196
$p2_pfskeygroups = array(
197
	0 => gettext('off'),
198
	1  => gettext('1 (768 bit)'),
199
	2  => gettext('2 (1024 bit)'),
200
	5  => gettext('5 (1536 bit)'),
201
	14 => gettext('14 (2048 bit)'),
202
	15 => gettext('15 (3072 bit)'),
203
	16 => gettext('16 (4096 bit)'),
204
	17 => gettext('17 (6144 bit)'),
205
	18 => gettext('18 (8192 bit)'),
206
	19 => gettext('19 (nist ecp256)'),
207
	20 => gettext('20 (nist ecp384)'),
208
	21 => gettext('21 (nist ecp521)'),
209
	22 => gettext('22 (1024(sub 160) bit)'),
210
	23 => gettext('23 (2048(sub 224) bit)'),
211
	24 => gettext('24 (2048(sub 256) bit)'),
212
	28 => gettext('28 (brainpool ecp256)'),
213
	29 => gettext('29 (brainpool ecp384)'),
214
	30 => gettext('30 (brainpool ecp512)')
215
);
216

    
217
function ipsec_enabled() {
218
	global $config;
219

    
220
	if (!isset($config['ipsec']) || !is_array($config['ipsec'])) {
221
		return false;
222
	}
223

    
224
	/* Check if we have at least one phase 1 entry. */
225
	if (!isset($config['ipsec']['phase1']) ||
226
	    !is_array($config['ipsec']['phase1']) ||
227
	    empty($config['ipsec']['phase1'])) {
228
		return false;
229
	}
230
	/* Check if at least one phase 1 entry is enabled. */
231
	foreach ($config['ipsec']['phase1'] as $phase1) {
232
		if (!isset($phase1['disabled'])) {
233
			return true;
234
		}
235
	}
236

    
237
	return false;
238
}
239

    
240
/*
241
 * ikeid management functions
242
 */
243

    
244
function ipsec_ikeid_used($ikeid) {
245
	global $config;
246

    
247
	foreach ($config['ipsec']['phase1'] as $ph1ent) {
248
		if ($ikeid == $ph1ent['ikeid']) {
249
			return true;
250
		}
251
	}
252

    
253
	return false;
254
}
255

    
256
function ipsec_ikeid_next() {
257

    
258
	$ikeid = 1;
259
	while (ipsec_ikeid_used($ikeid)) {
260
		$ikeid++;
261
	}
262

    
263
	return $ikeid;
264
}
265

    
266
/*
267
 * Return phase1 local address
268
 */
269
function ipsec_get_phase1_src(& $ph1ent) {
270

    
271
	if ($ph1ent['interface']) {
272
		if (substr($ph1ent['interface'], 0, 4) == "_vip") {
273
			$if = $ph1ent['interface'];
274
		} else {
275
			$if = get_failover_interface($ph1ent['interface']);
276
		}
277
	} else {
278
		$if = "wan";
279
	}
280
	$ip6 = get_interface_ipv6($if);
281
	$ip4 = get_interface_ip($if);
282
	if ($ph1ent['protocol'] == "inet6") {
283
		$interfaceip = $ip6;
284
	} elseif ($ph1ent['protocol'] == "inet") {
285
		$interfaceip = $ip4;
286
	} elseif ($ph1ent['protocol'] == "both") {
287
		$ifips = array();
288
		if (!empty($ip4)) {
289
			$ifips[] = $ip4;
290
		}
291
		if (!empty($ip6)) {
292
			$ifips[] = $ip6;
293
		}
294
		$interfaceip = implode(',', $ifips);
295
	}
296

    
297
	return $interfaceip;
298
}
299

    
300
/*
301
 * Return phase1 local address
302
 */
303
function ipsec_get_phase1_dst(& $ph1ent) {
304
	global $g;
305

    
306
	if (empty($ph1ent['remote-gateway'])) {
307
		return false;
308
	}
309
	$rg = $ph1ent['remote-gateway'];
310
	if (!is_ipaddr($rg)) {
311
		if (!platform_booting()) {
312
			return resolve_retry($rg);
313
		}
314
	}
315
	if (!is_ipaddr($rg)) {
316
		return false;
317
	}
318

    
319
	return $rg;
320
}
321

    
322
/*
323
 * Return phase2 idinfo in cidr format
324
 */
325
function ipsec_idinfo_to_cidr(& $idinfo, $addrbits = false, $mode = "") {
326
	global $config;
327

    
328
	switch ($idinfo['type']) {
329
		case "address":
330
			if ($addrbits) {
331
				if ($mode == "tunnel6") {
332
					return $idinfo['address']."/128";
333
				} else {
334
					return $idinfo['address']."/32";
335
				}
336
			} else {
337
				return $idinfo['address'];
338
			}
339
			break; /* NOTREACHED */
340
		case "network":
341
			return "{$idinfo['address']}/{$idinfo['netbits']}";
342
			break; /* NOTREACHED */
343
		case "none":
344
		case "mobile":
345
			return '0.0.0.0/0';
346
			break; /* NOTREACHED */
347
		default:
348
			if (empty($mode) && !empty($idinfo['mode'])) {
349
				$mode = $idinfo['mode'];
350
			}
351

    
352
			if ($mode == "tunnel6") {
353
				$address = get_interface_ipv6($idinfo['type']);
354
				$netbits = get_interface_subnetv6($idinfo['type']);
355
				$address = gen_subnetv6($address, $netbits);
356
				return "{$address}/{$netbits}";
357
			} else {
358
				$address = get_interface_ip($idinfo['type']);
359
				$netbits = get_interface_subnet($idinfo['type']);
360
				$address = gen_subnet($address, $netbits);
361
				return "{$address}/{$netbits}";
362
			}
363
			break; /* NOTREACHED */
364
	}
365
}
366

    
367
/*
368
 * Return phase2 idinfo in address/netmask format
369
 */
370
function ipsec_idinfo_to_subnet(& $idinfo, $addrbits = false) {
371
	global $config;
372

    
373
	switch ($idinfo['type']) {
374
		case "address":
375
			if ($addrbits) {
376
				if ($idinfo['mode'] == "tunnel6") {
377
					return $idinfo['address']."/128";
378
				} else {
379
					return $idinfo['address']."/255.255.255.255";
380
				}
381
			} else {
382
				return $idinfo['address'];
383
			}
384
			break; /* NOTREACHED */
385
		case "none":
386
		case "network":
387
			return $idinfo['address']."/".gen_subnet_mask($idinfo['netbits']);
388
			break; /* NOTREACHED */
389
		case "mobile":
390
			return "0.0.0.0/0";
391
			break; /* NOTREACHED */
392
		default:
393
			if ($idinfo['mode'] == "tunnel6") {
394
				$address = get_interface_ipv6($idinfo['type']);
395
				$netbits = get_interface_subnetv6($idinfo['type']);
396
				$address = gen_subnetv6($address, $netbits);
397
				return $address."/".$netbits;
398
			} else {
399
				$address = get_interface_ip($idinfo['type']);
400
				$netbits = get_interface_subnet($idinfo['type']);
401
				$address = gen_subnet($address, $netbits);
402
				return $address."/".$netbits;
403
			}
404
			break; /* NOTREACHED */
405
	}
406
}
407

    
408
/*
409
 *  Return phase2 idinfo in text format
410
 */
411
function ipsec_idinfo_to_text(& $idinfo) {
412
	global $config;
413

    
414
	switch ($idinfo['type']) {
415
		case "address":
416
			return $idinfo['address'];
417
			break; /* NOTREACHED */
418
		case "network":
419
			return $idinfo['address']."/".$idinfo['netbits'];
420
			break; /* NOTREACHED */
421
		case "mobile":
422
			return gettext("Mobile Client");
423
			break; /* NOTREACHED */
424
		case "none":
425
			return gettext("None");
426
			break; /* NOTREACHED */
427
		default:
428
			if (!empty($config['interfaces'][$idinfo['type']])) {
429
				return convert_friendly_interface_to_friendly_descr($idinfo['type']);
430
			} else {
431
				return strtoupper($idinfo['type']);
432
			}
433
			break; /* NOTREACHED */
434
	}
435
}
436

    
437
/*
438
 * Return phase1 association for phase2
439
 */
440
function ipsec_lookup_phase1(& $ph2ent, & $ph1ent) {
441
	global $config;
442

    
443
	if (!is_array($config['ipsec'])) {
444
		return false;
445
	}
446
	if (!is_array($config['ipsec']['phase1'])) {
447
		return false;
448
	}
449
	if (empty($config['ipsec']['phase1'])) {
450
		return false;
451
	}
452

    
453
	foreach ($config['ipsec']['phase1'] as $ph1tmp) {
454
		if ($ph1tmp['ikeid'] == $ph2ent['ikeid']) {
455
			$ph1ent = $ph1tmp;
456
			return $ph1ent;
457
		}
458
	}
459

    
460
	return false;
461
}
462

    
463
/*
464
 * Check phase1 communications status
465
 */
466
function ipsec_phase1_status(&$ipsec_status, $ikeid) {
467

    
468
	foreach ($ipsec_status as $ike) {
469
		if ($ike['id'] == $ikeid) {
470
			if ($ike['status'] == 'established') {
471
				return true;
472
			}
473
		}
474
	}
475

    
476
	return false;
477
}
478

    
479
/*
480
 * Check phase2 communications status
481
 */
482
function ipsec_phase2_status(&$ipsec_status, &$phase2) {
483

    
484
	if (ipsec_lookup_phase1($ph2ent, $ph1ent)) {
485
		return ipsec_phase1_status($ipsec_status, $ph1ent['ikeid']);
486
	}
487

    
488
	return false;
489
}
490

    
491
/*
492
 * Wrapper to call pfSense_ipsec_list_sa() when IPsec is enabled
493
 */
494
function ipsec_list_sa() {
495

    
496
	if (ipsec_enabled()) {
497
		return pfSense_ipsec_list_sa();
498
	}
499

    
500
	return array();
501
}
502

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

    
554
	return $spd;
555
}
556

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

    
607
	return $sad;
608
}
609

    
610
/*
611
 * Return dump of mobile user list
612
 */
613
function ipsec_dump_mobile() {
614
	global $g, $config;
615

    
616
	if(!isset($config['ipsec']['client']['enable'])) {
617
		return array();
618
	}
619

    
620
	$_gb = exec("/usr/local/sbin/ipsec leases 2>/dev/null", $output, $rc);
621

    
622
	if ($rc != 0) {
623
		log_error(gettext("Unable to find IPsec daemon leases file. Could not display mobile user stats!"));
624
		return array();
625
	}
626

    
627
	$response = array();
628
	$id = -1;
629

    
630
	/* Leases in pool '10.7.200.0/24', usage: 1/254, 1 online */
631
	$lease_regex='/^Leases *in *pool *\'(?P<name>.+)\', *usage: *(?P<usage>\d+)\/(?P<size>\d+), *(?P<online>\d+) *online/';
632
	/* 10.7.200.1   online   'jimp' */
633
	$pool_regex='/\s*(?P<host>[\d\.]+)\s+(?P<status>online|offline)\s+\'(?P<id>.*)\'/';
634
	/* no matching leases found */
635
	$nopool_regex='/no *matching *leases *found/';
636

    
637
	$lease=false;
638
	foreach ($output as $line) {
639
		if (preg_match($lease_regex, $line, $matches)) {
640
			$id++;
641
			$response['pool'][$id] = array(
642
			    'name'   => $matches['name'],
643
			    'usage'  => $matches['usage'],
644
			    'size'   => $matches['size'],
645
			    'online' => $matches['online'],
646
			);
647
			$lease=true;
648
		} else if ($lease) {
649
			if (preg_match($nopool_regex, $line)) {
650
				$response['pool'][$id]['lease'][] = array();
651
				$lease=false;
652
			} else if (preg_match($pool_regex, $line, $matches)) {
653
				$response['pool'][$id]['lease'][] = array(
654
				    'host'   => $matches['host'],
655
				    'status' => $matches['status'],
656
				    'id'     => $matches['id']
657
				);
658
			}
659
		}
660
	}
661

    
662
	unset($_gb, $lease, $output, $rc, $id, $lease_regex, $pool_regex,
663
	    $nopool_regex);
664

    
665
	return $response;
666
}
667

    
668
function ipsec_mobilekey_sort() {
669
	global $config;
670

    
671
	function mobilekeycmp($a, $b) {
672
		return strcmp($a['ident'][0], $b['ident'][0]);
673
	}
674

    
675
	usort($config['ipsec']['mobilekey'], "mobilekeycmp");
676
}
677

    
678
function ipsec_get_number_of_phase2($ikeid) {
679
	global $config;
680
	$a_phase2 = $config['ipsec']['phase2'];
681

    
682
	$nbph2 = 0;
683

    
684
	if (is_array($a_phase2) && count($a_phase2)) {
685
		foreach ($a_phase2 as $ph2tmp) {
686
			if ($ph2tmp['ikeid'] == $ikeid) {
687
				$nbph2++;
688
			}
689
		}
690
	}
691

    
692
	return $nbph2;
693
}
694

    
695
function ipsec_get_descr($ikeid) {
696
	global $config;
697

    
698
	if (!isset($config['ipsec']['phase1']) ||
699
	    !is_array($config['ipsec']['phase1'])) {
700
		return '';
701
	}
702

    
703
	foreach ($config['ipsec']['phase1'] as $p1) {
704
		if ($p1['ikeid'] == $ikeid) {
705
			return $p1['descr'];
706
		}
707
	}
708

    
709
	return '';
710
}
711

    
712
function ipsec_get_phase1($ikeid) {
713
		global $config;
714

    
715
		if (!isset($config['ipsec']['phase1']) ||
716
		    !is_array($config['ipsec']['phase1'])) {
717
			return '';
718
		}
719

    
720
		$a_phase1 = $config['ipsec']['phase1'];
721
		foreach ($a_phase1 as $p1) {
722
			if ($p1['ikeid'] == $ikeid) {
723
				return $p1;
724
			}
725
		}
726
		unset($a_phase1);
727
}
728

    
729
function ipsec_fixup_ip($ipaddr) {
730
	if (is_ipaddrv6($ipaddr) || is_subnetv6($ipaddr)) {
731
		return text_to_compressed_ip6($ipaddr);
732
	} else {
733
		return $ipaddr;
734
	}
735
}
736

    
737
function ipsec_find_id(& $ph1ent, $side = "local", $rgmap = array()) {
738
	if ($side == "local") {
739
		$id_type = $ph1ent['myid_type'];
740
		$id_data = $ph1ent['myid_data'];
741

    
742
		$addr = ipsec_get_phase1_src($ph1ent);
743
		if (!$addr) {
744
			return array();
745
		}
746
		/* When automatically guessing, use the first address. */
747
		$addr = explode(',', $addr);
748
		$addr = $addr[0];
749
	} elseif ($side == "peer") {
750
		$id_type = $ph1ent['peerid_type'];
751
		$id_data = $ph1ent['peerid_data'];
752

    
753
		if (isset($ph1ent['mobile'])) {
754
			$addr = "%any";
755
		} else {
756
			$addr = $ph1ent['remote-gateway'];
757
		}
758
	} else {
759
		return array();
760
	}
761

    
762

    
763
	$thisid_type = $id_type;
764
	switch ($thisid_type) {
765
		case 'myaddress':
766
			$thisid_type = 'address';
767
			$thisid_data = $addr;
768
			break;
769
		case 'dyn_dns':
770
			$thisid_type = 'dns';
771
			$thisid_data = $id_data;
772
			break;
773
		case 'peeraddress':
774
			$thisid_type = 'address';
775
			$thisid_data = $rgmap[$ph1ent['remote-gateway']];
776
			break;
777
		case 'address':
778
			$thisid_data = $id_data;
779
			break;
780
		case 'fqdn':
781
			$thisid_data = "{$id_data}";
782
			break;
783
		case 'keyid tag':
784
			$thisid_type = 'keyid';
785
			$thisid_data = "{$id_data}";
786
			break;
787
		case 'user_fqdn':
788
			$thisid_type = 'userfqdn';
789
			$thisid_data = "{$id_data}";
790
			break;
791
		case 'asn1dn':
792
			$thisid_data = $id_data;
793
			break;
794
	}
795
	return array($thisid_type, $thisid_data);
796
}
797

    
798
function ipsec_fixup_network($network) {
799
	if (substr($network, -3) == '|/0') {
800
		$result = substr($network, 0, -3);
801
	} else {
802
		$tmp = explode('|', $network);
803
		if (isset($tmp[1])) {
804
			$result = $tmp[1];
805
		} else {
806
			$result = $tmp[0];
807
		}
808
		unset($tmp);
809
	}
810

    
811
	return $result;
812
}
813

    
814
function ipsec_new_reqid() {
815
	global $config;
816

    
817
	if (!is_array($config['ipsec']) || !is_array($config['ipsec']['phase2'])) {
818
		return;
819
	}
820

    
821
	$ipsecreqid = lock('ipsecreqids', LOCK_EX);
822
	$keyids = array();
823
	$keyid = 1;
824
	foreach ($config['ipsec']['phase2'] as $ph2) {
825
		$keyids[$ph2['reqid']] = $ph2['reqid'];
826
	}
827

    
828
	for ($i = 1; $i < 16000; $i++) {
829
		if (!isset($keyids[$i])) {
830
			$keyid = $i;
831
			break;
832
		}
833
	}
834
	unlock($ipsecreqid);
835

    
836
	return $keyid;
837
}
838

    
839
function ipsec_get_loglevels() {
840
	global $config, $ipsec_log_cats;
841
	$def_loglevel = '1';
842

    
843
	$levels = array();
844

    
845
	foreach (array_keys($ipsec_log_cats) as $cat) {
846
		if (isset($config['ipsec']['logging'][$cat])) {
847
			$levels[$cat] = $config['ipsec']['logging'][$cat];
848
		} elseif (in_array($cat, array('ike', 'chd', 'cfg'))) {
849
			$levels[$cat] = "2";
850
		} else {
851
			$levels[$cat] = $def_loglevel;
852
		}
853
	}
854
	return $levels;
855
}
856
?>
(26-26/60)