Project

General

Profile

Download (57.8 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
	vpn.inc
4

    
5
	part of pfSense (https://www.pfsense.org)
6
	Copyright (C) 2008 Shrew Soft Inc
7
	Copyright (c) 2004-2016 Electric Sheep Fencing, LLC.
8
	All rights reserved.
9

    
10
	originally part of m0n0wall (http://m0n0.ch/wall)
11
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
12
	All rights reserved.
13

    
14
	Redistribution and use in source and binary forms, with or without
15
	modification, are permitted provided that the following conditions are met:
16

    
17
	1. Redistributions of source code must retain the above copyright notice,
18
	   this list of conditions and the following disclaimer.
19

    
20
	2. Redistributions in binary form must reproduce the above copyright
21
	   notice, this list of conditions and the following disclaimer in
22
	   the documentation and/or other materials provided with the
23
	   distribution.
24

    
25
	3. All advertising materials mentioning features or use of this software
26
	   must display the following acknowledgment:
27
	   "This product includes software developed by the pfSense Project
28
	   for use in the pfSense® software distribution. (http://www.pfsense.org/).
29

    
30
	4. The names "pfSense" and "pfSense Project" must not be used to
31
	   endorse or promote products derived from this software without
32
	   prior written permission. For written permission, please contact
33
	   coreteam@pfsense.org.
34

    
35
	5. Products derived from this software may not be called "pfSense"
36
	   nor may "pfSense" appear in their names without prior written
37
	   permission of the Electric Sheep Fencing, LLC.
38

    
39
	6. Redistributions of any form whatsoever must retain the following
40
	   acknowledgment:
41

    
42
	"This product includes software developed by the pfSense Project
43
	for use in the pfSense software distribution (http://www.pfsense.org/).
44

    
45
	THIS SOFTWARE IS PROVIDED BY THE pfSense PROJECT ``AS IS'' AND ANY
46
	EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47
	IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
48
	PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE pfSense PROJECT OR
49
	ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
50
	SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
51
	NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
52
	LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
53
	HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
54
	STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
55
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
56
	OF THE POSSIBILITY OF SUCH DAMAGE.
57
*/
58

    
59
require_once("ipsec.inc");
60
require_once("filter.inc");
61

    
62
function vpn_update_daemon_loglevel($category, $level) {
63
	global $ipsec_log_cats, $ipsec_log_sevs;
64

    
65
	if (in_array($category, array_keys($ipsec_log_cats), true) && in_array(intval($level), array_keys($ipsec_log_sevs), true)) {
66

    
67
		/* if you're setting to -1, need to add "--" to args */
68
		$argterm = "";
69
		if ($level == "-1") {
70
			$argterm = "--";
71
		}
72

    
73
		mwexec("/usr/local/sbin/ipsec stroke loglevel {$category} {$argterm} {$level}");
74
	}
75
}
76

    
77
function vpn_logging_cfgtxt() {
78
	global $config, $ipsec_log_cats, $ipsec_log_sevs;
79

    
80
	$cfgtext = array();
81
	foreach (array_keys($ipsec_log_cats) as $cat) {
82
		if (is_numeric($config['ipsec']['logging'][$cat]) &&
83
		    in_array(intval($config['ipsec']['logging'][$cat]), array_keys($ipsec_log_sevs), true)) {
84
			$cfgtext[] = "${cat} = {$config['ipsec']['logging'][$cat]}";
85
		}
86
	}
87

    
88
	return $cfgtext;
89
}
90

    
91
/* include all configuration functions */
92
function vpn_ipsec_convert_to_modp($index) {
93

    
94
	$convertion = "";
95
	switch ($index) {
96
		case '1':
97
			$convertion = "modp768";
98
			break;
99
		case '2':
100
			$convertion = "modp1024";
101
			break;
102
		case '5':
103
			$convertion = "modp1536";
104
			break;
105
		case '14':
106
			$convertion = "modp2048";
107
			break;
108
		case '15':
109
			$convertion = "modp3072";
110
			break;
111
		case '16':
112
			$convertion = "modp4096";
113
			break;
114
		case '17':
115
			$convertion = "modp6144";
116
			break;
117
		case '18':
118
			$convertion = "modp8192";
119
			break;
120
		case '19':
121
			$convertion = "ecp256";
122
			break;
123
		case '20':
124
			$convertion = "ecp384";
125
			break;
126
		case '21':
127
			$convertion = "ecp521";
128
			break;
129
		case '22':
130
			$convertion = "modp1024s160";
131
			break;
132
		case '23':
133
			$convertion = "modp2048s224";
134
			break;
135
		case '24':
136
			$convertion = "modp2048s256";
137
			break;
138
		case '28':
139
			$convertion = "ecp256bp";
140
			break;
141
		case '29':
142
			$convertion = "ecp384bp";
143
			break;
144
		case '30':
145
			$convertion = "ecp512bp";
146
			break;
147
	}
148

    
149
	return $convertion;
150
}
151

    
152
function vpn_ipsec_configure($restart = false) {
153
	global $config, $g, $sa, $sn, $p1_ealgos, $p2_ealgos, $ipsec_idhandling;
154

    
155
	/* get the automatic ping_hosts.sh ready */
156
	unlink_if_exists("{$g['vardb_path']}/ipsecpinghosts");
157
	touch("{$g['vardb_path']}/ipsecpinghosts");
158
	$ipsecpinghostsactive = false;
159

    
160
	/* service may have been enabled, disabled, or otherwise changed in a way requiring rule updates */
161
	filter_configure();
162

    
163
	$syscfg = $config['system'];
164
	$ipseccfg = $config['ipsec'];
165
	if (!ipsec_enabled()) {
166
		/* try to stop charon */
167
		mwexec("/usr/local/sbin/ipsec stop");
168
		/* Stop dynamic monitoring */
169
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
170

    
171
		/* wait for process to die */
172
		sleep(2);
173

    
174
		/* IPSEC is off, shutdown enc interface.*/
175
		mwexec("/sbin/ifconfig enc0 down");
176

    
177
		return 0;
178
	}
179

    
180
	$a_phase1 = $config['ipsec']['phase1'];
181
	$a_phase2 = $config['ipsec']['phase2'];
182
	$a_client = $config['ipsec']['client'];
183

    
184
	$certpath = "{$g['varetc_path']}/ipsec/ipsec.d/certs";
185
	$capath = "{$g['varetc_path']}/ipsec/ipsec.d/cacerts";
186
	$keypath = "{$g['varetc_path']}/ipsec/ipsec.d/private";
187
	$crlpath = "{$g['varetc_path']}/ipsec/ipsec.d/crls";
188

    
189
	mwexec("/sbin/ifconfig enc0 up");
190
	if (php_uname('m') != "amd64") {
191
		set_single_sysctl("net.inet.ipsec.directdispatch", "0");
192
	}
193

    
194
	/* needed for config files */
195
	if (!is_dir("{$g['varetc_path']}/ipsec")) {
196
		mkdir("{$g['varetc_path']}/ipsec");
197
	}
198
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d")) {
199
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d");
200
	}
201
	// delete these paths first to ensure old CAs, certs and CRLs aren't left behind. redmine #5238
202
	rmdir_recursive($capath);
203
	rmdir_recursive($keypath);
204
	rmdir_recursive($crlpath);
205
	rmdir_recursive($certpath);
206
	if (!is_dir($capath)) {
207
		mkdir($capath);
208
	}
209
	if (!is_dir($keypath)) {
210
		mkdir($keypath);
211
	}
212
	if (!is_dir($crlpath)) {
213
		mkdir($crlpath);
214
	}
215
	if (!is_dir($certpath)) {
216
		mkdir($certpath);
217
	}
218
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/aacerts")) {
219
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/aacerts");
220
	}
221
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/acerts")) {
222
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/acerts");
223
	}
224
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/ocspcerts")) {
225
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/ocspcerts");
226
	}
227
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/reqs")) {
228
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/reqs");
229
	}
230

    
231
	if (!file_exists("/usr/local/etc/ipsec.d") ||
232
	    !is_link("/usr/local/etc/ipsec.d")) {
233
		conf_mount_rw();
234
		if (file_exists("/usr/local/etc/ipsec.d")) {
235
			rmdir_recursive("/usr/local/etc/ipsec.d");
236
		}
237
		@symlink("{$g['varetc_path']}/ipsec/ipsec.d",
238
		    "/usr/local/etc/ipsec.d");
239
		conf_mount_ro();
240
	}
241
	if (!file_exists("{$g['varetc_path']}/etc/strongswan.d") ||
242
	    !is_link("{$g['varetc_path']}/etc/strongswan.d")) {
243
		conf_mount_rw();
244
		if (is_link("{$g['varetc_path']}/etc/strongswan.d")) {
245
			@unlink("{$g['varetc_path']}/etc/strongswan.d");
246
		} else {
247
			rmdir_recursive("{$g['varetc_path']}/etc/strongswan.d");
248
		}
249
		@symlink("/usr/local/etc/strongswan.d",
250
		    "{$g['varetc_path']}/ipsec/strongswan.d");
251
		conf_mount_ro();
252
	}
253
	if (!file_exists("/usr/local/etc/strongswan.conf") ||
254
	    !is_link("/usr/local/etc/strongswan.conf")) {
255
		conf_mount_rw();
256
		@unlink("/usr/local/etc/strongswan.conf");
257
		@symlink("{$g['varetc_path']}/ipsec/strongswan.conf",
258
		    "/usr/local/etc/strongswan.conf");
259
		conf_mount_ro();
260
	}
261
	if (!file_exists("/usr/local/etc/ipsec.conf") ||
262
	    !is_link("/usr/local/etc/ipsec.conf")) {
263
		conf_mount_rw();
264
		@unlink("/usr/local/etc/ipsec.conf");
265
		@symlink("{$g['varetc_path']}/ipsec/ipsec.conf",
266
		    "/usr/local/etc/ipsec.conf");
267
		conf_mount_ro();
268
	}
269

    
270
	if (platform_booting()) {
271
		echo gettext("Configuring IPsec VPN... ");
272
	}
273

    
274
	/* resolve all local, peer addresses and setup pings */
275
	$ipmap = array();
276
	$rgmap = array();
277
	$filterdns_list = array();
278
	$listeniflist = array();
279
	$aggressive_mode_psk = false;
280
	unset($iflist);
281
	$ifacesuse = array();
282
	$mobile_ipsec_auth = "";
283
	if (is_array($a_phase1) && count($a_phase1)) {
284

    
285
		$ipsecpinghosts = "";
286
		/* step through each phase1 entry */
287
		foreach ($a_phase1 as $ph1ent) {
288
			if (isset($ph1ent['disabled'])) {
289
				continue;
290
			}
291

    
292
			if (strpos($ph1ent['interface'], '_vip')) {
293
				$vpninterface = explode('_vip', $ph1ent['interface']);
294
				$ifacesuse[] = get_real_interface($vpninterface[0]);
295
			} else {
296
				$vpninterface = get_failover_interface($ph1ent['interface']);
297
				if (strpos($vpninterface, '_vip')) {
298
					$vpninterface = explode('_vip', $vpninterface);
299
					$ifacesuse[] = get_real_interface($vpninterface[0]);
300
				} elseif (!empty($vpninterface)) {
301
					$ifacesuse[] = $vpninterface;
302
				}
303
			}
304

    
305
			if ($ph1ent['mode'] == "aggressive" && ($ph1ent['authentication_method'] == "pre_shared_key" || $ph1ent['authentication_method'] == "xauth_psk_server")) {
306
				$aggressive_mode_psk = true;
307
			}
308

    
309
			$ikeid = $ph1ent['ikeid'];
310
			$listeniflist = get_real_interface($a_phase1['interface']);
311

    
312
			$ep = ipsec_get_phase1_src($ph1ent);
313
			if (!is_ipaddr($ep)) {
314
				log_error("IPsec ERROR: Could not find phase 1 source for connection {$ph1ent['descr']}. Omitting from configuration file.");
315
				continue;
316
			}
317

    
318
			if (!in_array($ep, $ipmap)) {
319
				$ipmap[] = $ep;
320
			}
321

    
322
			/* see if this tunnel has a hostname for the remote-gateway. If so,
323
			   try to resolve it now and add it to the list for filterdns */
324

    
325
			if (isset ($ph1ent['mobile'])) {
326
				$mobile_ipsec_auth = $ph1ent['authentication_method'];
327
				continue;
328
			}
329

    
330
			$rg = $ph1ent['remote-gateway'];
331

    
332
			if (!is_ipaddr($rg)) {
333
				$filterdns_list[] = "{$rg}";
334
				add_hostname_to_watch($rg);
335
				if (!platform_booting()) {
336
					$rg = resolve_retry($rg);
337
				}
338
				if (!is_ipaddr($rg)) {
339
					continue;
340
				}
341
			}
342
			if (array_search($rg, $rgmap)) {
343
				log_error("The remote gateway {$rg} already exists on another phase 1 entry");
344
				continue;
345
			}
346
			$rgmap[$ph1ent['remote-gateway']] = $rg;
347

    
348
			if (is_array($a_phase2)) {
349
				/* step through each phase2 entry */
350
				foreach ($a_phase2 as $ph2ent) {
351
					if (isset($ph2ent['disabled'])) {
352
						continue;
353
					}
354

    
355
					if ($ikeid != $ph2ent['ikeid']) {
356
						continue;
357
					}
358

    
359
					/* add an ipsec pinghosts entry */
360
					if ($ph2ent['pinghost']) {
361
						if (!is_array($iflist)) {
362
							$iflist = get_configured_interface_list();
363
						}
364
						$srcip = null;
365
						$local_subnet = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
366
						if (is_ipaddrv6($ph2ent['pinghost'])) {
367
							foreach ($iflist as $ifent => $ifname) {
368
								$interface_ip = get_interface_ipv6($ifent);
369
								if (!is_ipaddrv6($interface_ip)) {
370
									continue;
371
								}
372
								if (ip_in_subnet($interface_ip, $local_subnet)) {
373
									$srcip = $interface_ip;
374
									break;
375
								}
376
							}
377
						} else {
378
							foreach ($iflist as $ifent => $ifname) {
379
								$interface_ip = get_interface_ip($ifent);
380
								if (!is_ipaddrv4($interface_ip)) {
381
									continue;
382
								}
383
								if ($local_subnet == "0.0.0.0/0" || ip_in_subnet($interface_ip, $local_subnet)) {
384
									$srcip = $interface_ip;
385
									break;
386
								}
387
							}
388
						}
389
						/* if no valid src IP was found in configured interfaces, try the vips */
390
						if (is_null($srcip)) {
391
							$viplist = get_configured_vips_list();
392
							foreach ($viplist as $vip) {
393
								if (ip_in_subnet($vip['ipaddr'], $local_subnet)) {
394
									$srcip = $vip['ipaddr'];
395
									break;
396
								}
397
							}
398
						}
399
						$dstip = $ph2ent['pinghost'];
400
						if (is_ipaddrv6($dstip)) {
401
							$family = "inet6";
402
						} else {
403
							$family = "inet";
404
						}
405
						if (is_ipaddr($srcip)) {
406
							$ipsecpinghosts[] = "{$srcip}|{$dstip}|3|||||{$family}|\n";
407
							$ipsecpinghostsactive = true;
408
						}
409
					}
410
				}
411
			}
412
		}
413
		@file_put_contents("{$g['vardb_path']}/ipsecpinghosts", $ipsecpinghosts);
414
		unset($ipsecpinghosts);
415
	}
416
	unset($iflist);
417

    
418
	$accept_unencrypted = "";
419
	if (isset($config['ipsec']['acceptunencryptedmainmode'])) {
420
		$accept_unencrypted = "accept_unencrypted_mainmode_messages = yes";
421
	}
422

    
423
	$stronconf = '';
424
	if (file_exists("{$g['varetc_path']}/ipsec/strongswan.conf")) {
425
		$stronconf = file_get_contents("{$g['varetc_path']}/ipsec/strongswan.conf");
426
	}
427

    
428
	$i_dont_care_about_security_and_use_aggressive_mode_psk = "";
429
	if ($aggressive_mode_psk) {
430
		log_error("WARNING: Setting i_dont_care_about_security_and_use_aggressive_mode_psk option because a phase 1 is configured using aggressive mode with pre-shared keys. This is not a secure configuration.");
431
		if (!empty($stronconf) && strpos($stronconf, 'i_dont_care_about_security_and_use_aggressive_mode_psk') === FALSE) {
432
			$restart = true;
433
		}
434
		$i_dont_care_about_security_and_use_aggressive_mode_psk = "i_dont_care_about_security_and_use_aggressive_mode_psk=yes";
435
	}
436

    
437
	$unity_enabled = isset($config['ipsec']['unityplugin']) ? 'yes' : 'no';
438

    
439
	$makebeforebreak = '';
440
	if (isset($config['ipsec']['makebeforebreak'])) {
441
		$makebeforebreak = 'make_before_break = yes';
442
	}
443

    
444
	if (isset($config['ipsec']['enableinterfacesuse'])) {
445
		if (!empty($ifacesuse)) {
446
			$ifacesuse = 'interfaces_use = ' . implode(',', array_unique($ifacesuse));
447
		} else {
448
			$ifacesuse = '';
449
		}
450
	} else {
451
		$ifacesuse = '';
452
	}
453

    
454
	unset($stronconf);
455

    
456
	$strongswanlog = "";
457
	$ipsecloglevels = vpn_logging_cfgtxt();
458
	if (is_array($ipsecloglevels)) {
459
		foreach ($ipsecloglevels as $loglevel) {
460
			$strongswanlog .= "\t\t\t" . $loglevel . "\n";
461
		}
462
	}
463
	$strongswan = <<<EOD
464

    
465
# Automatically generated config file - DO NOT MODIFY. Changes will be overwritten.
466
starter {
467
	load_warning = no
468
	config_file = {$g['varetc_path']}/ipsec/ipsec.conf
469
}
470

    
471
charon {
472
# number of worker threads in charon
473
	threads = 16
474
	ikesa_table_size = 32
475
	ikesa_table_segments = 4
476
	init_limit_half_open = 1000
477
	install_routes = no
478
	load_modular = yes
479
	{$i_dont_care_about_security_and_use_aggressive_mode_psk}
480
	{$accept_unencrypted}
481
	cisco_unity = {$unity_enabled}
482
	{$ifacesuse}
483
	{$makebeforebreak}
484

    
485
	syslog {
486
		identifier = charon
487
		# log everything under daemon since it ends up in the same place regardless with our syslog.conf
488
		daemon {
489
			ike_name = yes
490
{$strongswanlog}
491
		}
492
		# disable logging under auth so logs aren't duplicated
493
		auth {
494
			default = -1
495
		}
496
	}
497

    
498
	plugins {
499
		# Load defaults
500
		include {$g['varetc_path']}/ipsec/strongswan.d/charon/*.conf
501

    
502
		stroke {
503
			secrets_file = {$g['varetc_path']}/ipsec/ipsec.secrets
504
		}
505

    
506
		unity {
507
			load = {$unity_enabled}
508
		}
509

    
510
EOD;
511

    
512
	/* Find RADIUS servers designated for Mobile IPsec user auth */
513
	$radius_server_txt = "";
514
	$user_sources = explode(',', $config['ipsec']['client']['user_source']);
515
	foreach ($user_sources as $user_source) {
516
		$auth_server = auth_get_authserver($user_source);
517
		$nice_user_source = strtolower(preg_replace('/\s+/', '_', $user_source));
518
		if ($auth_server && $auth_server['type'] === 'radius') {
519
			$radius_server_txt .= <<<EOD
520
				{$nice_user_source} {
521
					address = {$auth_server['host']}
522
					secret = "{$auth_server['radius_secret']}"
523
					auth_port = {$auth_server['radius_auth_port']}
524
					acct_port = {$auth_server['radius_acct_port']}
525
				}
526

    
527
EOD;
528
		}
529
	}
530

    
531
	/* write an eap-radius config section if appropriate */
532
	if (strlen($radius_server_txt) && ($mobile_ipsec_auth === "eap-radius")) {
533
		$strongswan .= <<<EOD
534
		eap-radius {
535
			class_group = yes
536
			eap_start = no
537
			servers {
538
{$radius_server_txt}
539
			}
540
		}
541

    
542
EOD;
543
	}
544

    
545
	if (is_array($a_client) && isset($a_client['enable'])) {
546
		$strongswan .= "\t\tattr {\n";
547

    
548
		$cfgservers = array();
549
		if (!empty($a_client['dns_server1'])) {
550
			$cfgservers[] = $a_client['dns_server1'];
551
		}
552
		if (!empty($a_client['dns_server2'])) {
553
			$cfgservers[] = $a_client['dns_server2'];
554
		}
555
		if (!empty($a_client['dns_server3'])) {
556
			$cfgservers[] = $a_client['dns_server3'];
557
		}
558
		if (!empty($a_client['dns_server4'])) {
559
			$cfgservers[] = $a_client['dns_server4'];
560
		}
561

    
562
		if (!empty($cfgservers)) {
563
			$strongswan .= "\t\t\tdns = " . implode(",", $cfgservers) . "\n";
564
		}
565
		unset($cfgservers);
566
		$cfgservers = array();
567
		if (!empty($a_client['wins_server1'])) {
568
			$cfgservers[] = $a_client['wins_server1'];
569
		}
570
		if (!empty($a_client['wins_server2'])) {
571
			$cfgservers[] = $a_client['wins_server2'];
572
		}
573
		if (!empty($cfgservers)) {
574
			$strongswan .= "\t\t\tnbns = " . implode(",", $cfgservers) . "\n";
575
		}
576
		unset($cfgservers);
577

    
578
		if (isset($a_client['net_list']) && is_array($a_phase2)) {
579
			$net_list = '';
580
			foreach ($a_phase2 as $ph2ent) {
581
				if (isset($ph2ent['disabled'])) {
582
					continue;
583
				}
584

    
585
				if (!isset($ph2ent['mobile'])) {
586
					continue;
587
				}
588

    
589
				$localid = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
590

    
591
				if (!empty($net_list)) {
592
					$net_list .= ",";
593
				}
594
				$net_list .= $localid;
595
			}
596

    
597
			if (!empty($net_list)) {
598
				$strongswan .= "\t\t\tsubnet = {$net_list}\n";
599
				$strongswan .= "\t\t\tsplit-include = {$net_list}\n";
600
				unset($net_list);
601
			}
602
		}
603

    
604
		if (!empty($a_client['dns_domain'])) {
605
			$strongswan .= "\t\t\t# Search domain and default domain\n";
606
			$strongswan .= "\t\t\t28674 = \"{$a_client['dns_domain']}\"\n";
607
			if (empty($a_client['dns_split'])) {
608
				$strongswan .= "\t\t\t28675 = \"{$a_client['dns_domain']}\"";
609
			}
610
			$strongswan .= "\n";
611
		}
612

    
613
		if (!empty($a_client['dns_split'])) {
614
			$strongswan .= "\t\t\t28675 = {$a_client['dns_split']}\n";
615
		}
616

    
617
		if (!empty($a_client['login_banner'])) {
618
			$strongswan .= "\t\t\t28672 = \"{$a_client['login_banner']}\"\n";
619
		}
620

    
621
		if (isset($a_client['save_passwd'])) {
622
			$strongswan .= "\t\t\t28673 = 1\n";
623
		}
624

    
625
		if ($a_client['pfs_group']) {
626
			$strongswan .= "\t\t\t28679 = \"{$a_client['pfs_group']}\"\n";
627
		}
628
		$strongswan .= "\t\t}\n";
629

    
630
		if ($a_client['user_source'] != "none") {
631
			$strongswan .= "\t\txauth-generic {\n";
632
			$strongswan .= "\t\t\tscript = /etc/inc/ipsec.auth-user.php\n";
633
			$strongswan .= "\t\t\tauthcfg = ";
634
			$firstsed = 0;
635
			$authcfgs = explode(",", $a_client['user_source']);
636
			foreach ($authcfgs as $authcfg) {
637
				if ($firstsed > 0) {
638
					$strongswan .= ",";
639
				}
640
				if ($authcfg == "system") {
641
					$authcfg = "Local Database";
642
				}
643
				$strongswan .= $authcfg;
644
				$firstsed = 1;
645
			}
646
			$strongswan .= "\n";
647
			$strongswan .= "\t\t}\n";
648
		}
649
	}
650

    
651
	$strongswan .= "\n\t}\n}\n";
652
	@file_put_contents("{$g['varetc_path']}/ipsec/strongswan.conf", $strongswan);
653
	unset($strongswan);
654

    
655
	/* write out CRL files */
656
	if (is_array($config['crl']) && count($config['crl'])) {
657
		foreach ($config['crl'] as $crl) {
658
			if (!isset($crl['text'])) {
659
				log_error(sprintf(gettext("Warning: Missing CRL data for %s"), $crl['descr']));
660
				continue;
661
			}
662
			$fpath = "{$crlpath}/{$crl['refid']}.crl";
663
			if (!@file_put_contents($fpath, base64_decode($crl['text']))) {
664
				log_error(sprintf(gettext("Error: Cannot write IPsec CRL file for %s"), $crl['descr']));
665
				continue;
666
			}
667
		}
668
	}
669

    
670
	$pskconf = "";
671

    
672
	$vpncas = array();
673
	if (is_array($a_phase1) && count($a_phase1)) {
674
		foreach ($a_phase1 as $ph1ent) {
675

    
676
			if (isset($ph1ent['disabled'])) {
677
				continue;
678
			}
679

    
680
			if (strstr($ph1ent['authentication_method'], 'rsa') ||
681
			    in_array($ph1ent['authentication_method'], array('eap-mschapv2', 'eap-tls', 'eap-radius'))) {
682
				$certline = '';
683

    
684
				$ikeid = $ph1ent['ikeid'];
685
				$cert = lookup_cert($ph1ent['certref']);
686

    
687
				if (!$cert) {
688
					log_error(sprintf(gettext("Error: Invalid phase1 certificate reference for %s"), $ph1ent['name']));
689
					continue;
690
				}
691

    
692
				/* add signing CA cert chain of server cert
693
				 * to the list of CAs to write
694
				 */
695
				$cachain = ca_chain_array($cert);
696
				if ($cachain && is_array($cachain)) {
697
					foreach ($cachain as $cacrt) {
698
						$vpncas[$cacrt['refid']] = $cacrt;
699
					}
700
				}
701

    
702
				@chmod($certpath, 0600);
703

    
704
				$ph1keyfile = "{$keypath}/cert-{$ikeid}.key";
705
				if (!file_put_contents($ph1keyfile, base64_decode($cert['prv']))) {
706
					log_error(sprintf(gettext("Error: Cannot write phase1 key file for %s"), $ph1ent['name']));
707
					continue;
708
				}
709
				@chmod($ph1keyfile, 0600);
710

    
711
				$ph1certfile = "{$certpath}/cert-{$ikeid}.crt";
712
				if (!file_put_contents($ph1certfile, base64_decode($cert['crt']))) {
713
					log_error(sprintf(gettext("Error: Cannot write phase1 certificate file for %s"), $ph1ent['name']));
714
					@unlink($ph1keyfile);
715
					continue;
716
				}
717
				@chmod($ph1certfile, 0600);
718

    
719
				/* XXX" Traffic selectors? */
720
				$pskconf .= " : RSA {$ph1keyfile}\n";
721
			} else {
722
				list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, 'local');
723
				list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, 'peer', $rgmap);
724

    
725
				$myid = trim($myid_data);
726

    
727
				if (empty($peerid_data)) {
728
					continue;
729
				}
730

    
731
				if ($myid_type == 'fqdn' && !empty($myid)) {
732
					$myid = "@{$myid}";
733
				}
734

    
735
				$myid = isset($ph1ent['mobile']) ? trim($myid_data) : "%any";
736

    
737
				$peerid = ($peerid_data != 'allusers') ? trim($peerid_data) : '';
738

    
739
				if ($peerid_type == 'fqdn' && !empty($peerid)) {
740
					$peerid = "@{$peerid}";
741
				}
742

    
743
				if (!empty($ph1ent['pre-shared-key'])) {
744
					$pskconf .= "{$myid} {$peerid} : PSK 0s" . base64_encode(trim($ph1ent['pre-shared-key'])) . "\n";
745
					if (isset($ph1ent['mobile'])) {
746
						$pskconf .= " : PSK 0s" . base64_encode(trim($ph1ent['pre-shared-key'])) . "\n";
747
					}
748
				}
749
			}
750

    
751
			/* if the client authenticates with a cert add the
752
			 * client cert CA chain to the list of CAs to write
753
			 */
754
			if (in_array($ph1ent['authentication_method'],
755
			array('rsasig', 'eap-tls', 'xauth_rsa_server'))) {
756

    
757
				if (!empty($ph1ent['caref']) && !array_key_exists($ph1ent['caref'], $vpncas)) {
758
					$thisca = lookup_ca($ph1ent['caref']);
759
					$vpncas[$ph1ent['caref']] = $thisca;
760

    
761
					/* follow chain up to root */
762
					$cachain = ca_chain_array($thisca);
763
					if ($cachain and is_array($cachain)) {
764
						foreach ($cachain as $cacrt) {
765
							$vpncas[$cacrt['refid']] = $cacrt;
766
						}
767
					}
768
				}
769
			}
770
		}
771
	}
772

    
773
	/* write the required CAs */
774
	foreach ($vpncas as $carefid => $cadata) {
775
		$cacrt = base64_decode($cadata['crt']);
776
		$cacrtattrs = openssl_x509_parse($cacrt);
777
		if (!is_array($cacrtattrs) || !isset($cacrtattrs['hash'])) {
778
			log_error(sprintf(gettext("Error: Invalid certificate hash info for %s"), $cadata['descr']));
779
			continue;
780
		}
781
		$cafilename = "{$capath}/{$cacrtattrs['hash']}.0.crt";
782
		if (!@file_put_contents($cafilename, $cacrt)) {
783
				log_error(sprintf(gettext("Error: Cannot write IPsec CA file for %s"), $cadata['descr']));
784
				continue;
785
		}
786
	}
787

    
788
	/* Add user PSKs */
789
	if (is_array($config['system']) && is_array($config['system']['user'])) {
790
		foreach ($config['system']['user'] as $user) {
791
			if (!empty($user['ipsecpsk'])) {
792
				$pskconf .= "{$myid} {$user['name']} : PSK 0s" . base64_encode($user['ipsecpsk']) . "\n";
793
			}
794
		}
795
		unset($user);
796
	}
797

    
798
	/* add PSKs for mobile clients */
799
	if (is_array($ipseccfg['mobilekey'])) {
800
		foreach ($ipseccfg['mobilekey'] as $key) {
801
			if ($key['ident'] == "allusers") {
802
				$key['ident'] = '%any';
803
			}
804
			if ($key['ident'] == "any") {
805
				$key['ident'] = '%any';
806
			}
807
			if (empty($key['type'])) {
808
				$key['type'] = 'PSK';
809
			}
810
			$pskconf .= "{$myid} {$key['ident']} : {$key['type']} 0s" . base64_encode($key['pre-shared-key']) . "\n";
811
		}
812
		unset($key);
813
	}
814

    
815
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.secrets", $pskconf);
816
	chmod("{$g['varetc_path']}/ipsec/ipsec.secrets", 0600);
817
	unset($pskconf);
818

    
819
	$uniqueids = 'yes';
820
	if (!empty($config['ipsec']['uniqueids'])) {
821
		if (array_key_exists($config['ipsec']['uniqueids'], $ipsec_idhandling)) {
822
			$uniqueids = $config['ipsec']['uniqueids'];
823
		}
824
	}
825
	$natfilterrules = false;
826
	/* begin ipsec.conf */
827
	$ipsecconf = "";
828
	$enablecompression = false;
829
	if (is_array($a_phase1) && count($a_phase1)) {
830

    
831
		$ipsecconf .= "# This file is automatically generated. Do not edit\n";
832
		$ipsecconf .= "config setup\n\tuniqueids = {$uniqueids}\n";
833

    
834
		if (isset($config['ipsec']['strictcrlpolicy'])) {
835
			$ipsecconf .= "\tstrictcrlpolicy = yes \n";
836
		}
837

    
838
		if (!isset($config['ipsec']['noshuntlaninterfaces'])) {
839
			if ($config['interfaces']['lan']) {
840
				$lanip = get_interface_ip("lan");
841
				if (!empty($lanip) && is_ipaddrv4($lanip)) {
842
					$lansn = get_interface_subnet("lan");
843
					$lansa = gen_subnet($lanip, $lansn);
844
					$ipsecconf .= <<<EOD
845

    
846
conn bypasslan
847
	leftsubnet = {$lansa}/{$lansn}
848
	rightsubnet = {$lansa}/{$lansn}
849
	authby = never
850
	type = passthrough
851
	auto = route
852

    
853
EOD;
854
				}
855
			}
856
		}
857

    
858
		foreach ($a_phase1 as $ph1ent) {
859
			if (isset($ph1ent['disabled'])) {
860
				continue;
861
			}
862

    
863
			if ($ph1ent['mode'] == "aggressive") {
864
				$aggressive = "yes";
865
			} else {
866
				$aggressive = "no";
867
			}
868

    
869
			$ep = ipsec_get_phase1_src($ph1ent);
870
			if (!$ep) {
871
				continue;
872
			}
873

    
874
			$ikeid = $ph1ent['ikeid'];
875
			$keyexchange = "ikev1";
876
			$passive = "route";
877
			if (!empty($ph1ent['iketype'])) {
878
				if ($ph1ent['iketype'] == "ikev2") {
879
					$keyexchange = "ikev2";
880
					//$passive = "start";
881
				}
882
			}
883

    
884
			if (isset($ph1ent['mobile'])) {
885
				$right_spec = "%any";
886
				$passive = 'add';
887
			} else {
888
				if (isset($ph1ent['responderonly'])) {
889
					$passive = 'add';
890
				}
891

    
892
				$right_spec = $ph1ent['remote-gateway'];
893
				if (is_ipaddr($right_spec)) {
894
					$sourcehost = $right_spec;
895
				} else {
896
					$sourcehost = $rgmap['remote-gateway'];
897
				}
898

    
899
				if ($ph1ent['protocol'] == 'inet') {
900
					if (strpos($ph1ent['interface'], '_vip')) {
901
						$vpninterface = explode('_vip', $ph1ent['interface']);
902
						$ifacesuse = get_real_interface($vpninterface[0]);
903
						$vpninterface = $vpninterface[0];
904
					} else {
905
						$ifacesuse = get_failover_interface($ph1ent['interface']);
906
						if (strpos($ifacesuse, '_vip')) {
907
							$vpninterface = explode('_vip', $ifacesuse);
908
							$ifacesuse = get_real_interface($vpninterface[0]);
909
							$vpninterface = $vpninterface[0];
910
						} else {
911
							$vpninterface = convert_real_interface_to_friendly_interface_name($ifacesuse);
912
						}
913
					}
914

    
915
					if (!empty($ifacesuse) && interface_has_gateway($vpninterface)) {
916
						$gatewayip = get_interface_gateway($vpninterface);
917
						$interfaceip = get_interface_ip($vpninterface);
918
						$subnet_bits = get_interface_subnet($vpninterface);
919
						$subnet_ip = gen_subnetv4($interfaceip, $subnet_bits);
920
						/* if the remote gateway is in the local subnet, then don't add a route */
921
						if (!ip_in_subnet($sourcehost, "{$subnet_ip}/{$subnet_bits}")) {
922
							if (is_ipaddrv4($gatewayip)) {
923
								// log_error("IPSEC interface is not WAN but {$ifacesuse}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
924
								mwexec("/sbin/route change -host {$sourcehost} {$gatewayip}", true);
925
							}
926
						}
927
					}
928
				} else if ($ph1ent['protocol'] == 'inet6') {
929
					if (strpos($ph1ent['interface'], '_vip')) {
930
						$vpninterface = explode('_vip', $ph1ent['interface']);
931
						$ifacesuse = get_real_interface($vpninterface[0]);
932
						$vpninterface = $vpninterface[0];
933
					} else {
934
						$ifacesuse = get_failover_interface($ph1ent['interface']);
935
						if (strpos($ifacesuse, '_vip')) {
936
							$vpninterface = explode('_vip', $ifacesuse);
937
							$ifacesuse = get_real_interface($vpninterface[0]);
938
							$vpninterface = $vpninterface[0];
939
						} else {
940
							$vpninterface = convert_real_interface_to_friendly_interface_name($ifacesuse);
941
						}
942
					}
943

    
944
					if (!empty($ifacesuse) && interface_has_gateway($vpninterface)) {
945
						$gatewayip = get_interface_gateway_v6($vpninterface);
946
						$interfaceip = get_interface_ipv6($vpninterface);
947
						$subnet_bits = get_interface_subnetv6($vpninterface);
948
						$subnet_ip = gen_subnetv6($interfaceip, $subnet_bits);
949
						/* if the remote gateway is in the local subnet, then don't add a route */
950
						if (!ip_in_subnet($sourcehost, "{$subnet_ip}/{$subnet_bits}")) {
951
							if (is_ipaddrv6($gatewayip)) {
952
								// log_error("IPSEC interface is not WAN but {$ifacesuse}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
953
								mwexec("/sbin/route change -inet6 -host {$sourcehost} {$gatewayip}", true);
954
							}
955
						}
956
					}
957
				}
958
			}
959

    
960
			list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, 'local');
961
			if ($myid_type != 'address' && $myid_type != 'keyid' && $myid_type != 'asn1dn') {
962
				$myid_data = "{$myid_type}:{$myid_data}";
963
			} elseif ($myid_type == "asn1dn" && !empty($myid_data)) {
964
				if ($myid_data[0] == '#') {
965
				/* asn1dn needs double quotes */
966
					$myid_data = "\"{$myid_type}:{$myid_data}\"";
967
				} else {
968
					$myid_data = "\"{$myid_data}\"";
969
				}
970
			}
971
			$leftid = '';
972
			if (!empty($myid_data)) {
973
				$leftid = "leftid = {$myid_data}";
974
			}
975

    
976
			$peerid_spec = '';
977
			if (isset($ph1ent['mobile']) && ($ph1ent['authentication_method'] == "pre_shared_key" || $ph1ent['authentication_method'] == "xauth_psk_server")) {
978
				// Only specify peer ID if we are not dealing with mobile PSK
979
			} else {
980
				list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, 'peer', $rgmap);
981
				if ($peerid_type == 'any') {
982
					$peerid_spec = '';
983
				} elseif ($peerid_type != 'address' && $peerid_type != 'keyid' && $peerid_type != 'asn1dn') {
984
					$peerid_spec = "{$peerid_type}:{$peerid_data}";
985
				} elseif ($peerid_type == "asn1dn") {
986
					/* asn1dn needs double quotes */
987
					if ($peerid_data[0] == '#') {
988
						$peerid_spec = "\"{$peerid_type}:{$peerid_data}\"";
989
					} elseif (!empty($peerid_data)) {
990
						$peerid_spec = "\"{$peerid_data}\"";
991
					}
992
				} else {
993
					$peerid_spec = $peerid_data;
994
				}
995
			}
996

    
997
			if (is_array($ph1ent['encryption-algorithm']) && !empty($ph1ent['encryption-algorithm']['name']) && !empty($ph1ent['hash-algorithm'])) {
998
				$ealgosp1 = '';
999
				$ealg_id = $ph1ent['encryption-algorithm']['name'];
1000
				$ealg_kl = $ph1ent['encryption-algorithm']['keylen'];
1001
				if ($ealg_kl) {
1002
					$ealgosp1 = "ike = {$ealg_id}{$ealg_kl}-{$ph1ent['hash-algorithm']}";
1003
				} else {
1004
					$ealgosp1 = "ike = {$ealg_id}-{$ph1ent['hash-algorithm']}";
1005
				}
1006

    
1007
				$modp = vpn_ipsec_convert_to_modp($ph1ent['dhgroup']);
1008
				if (!empty($modp)) {
1009
					$ealgosp1 .= "-{$modp}";
1010
				}
1011

    
1012
				$ealgosp1 .= "!";
1013
			}
1014

    
1015
			if ($ph1ent['dpd_delay'] && $ph1ent['dpd_maxfail']) {
1016
				if ($passive == "route") {
1017
					$dpdline = "dpdaction = restart";
1018
				} else {
1019
					$dpdline = "dpdaction = clear";
1020
				}
1021
				$dpdline .= "\n\tdpddelay = {$ph1ent['dpd_delay']}s";
1022
				$dpdtimeout = $ph1ent['dpd_delay'] * ($ph1ent['dpd_maxfail'] + 1);
1023
				$dpdline .= "\n\tdpdtimeout = {$dpdtimeout}s";
1024
			} else {
1025
				$dpdline = "dpdaction = none";
1026
			}
1027

    
1028
			$ikelifeline = '';
1029
			if ($ph1ent['lifetime']) {
1030
				$ikelifeline = "ikelifetime = {$ph1ent['lifetime']}s";
1031
			}
1032

    
1033
			$rightsourceip = NULL;
1034
			if (isset($ph1ent['mobile'])) {
1035
				$rightsourceips = array();
1036
				if (!empty($a_client['pool_address'])) {
1037
					$rightsourceips[] = "{$a_client['pool_address']}/{$a_client['pool_netbits']}";
1038
				}
1039
				if (!empty($a_client['pool_address_v6'])) {
1040
					$rightsourceips[] = "{$a_client['pool_address_v6']}/{$a_client['pool_netbits_v6']}";
1041
				}
1042
				if ($ph1ent['authentication_method'] == "eap-radius" && !count($rightsourceips)) {
1043
					$rightsourceips[] = "%radius";
1044
				}
1045
				if (count($rightsourceips)) {
1046
					$rightsourceip = "\trightsourceip = " . implode(',', $rightsourceips) . "\n";
1047
				}
1048
			}
1049

    
1050
			if (!empty($ph1ent['caref'])) {
1051
				$ca = lookup_ca($ph1ent['caref']);
1052
				if ($ca) {
1053
					$casubarr = cert_get_subject_array($ca['crt']);
1054
					$casub = "";
1055
					foreach ($casubarr as $casubfield) {
1056
						if (empty($casub)) {
1057
							$casub = "/";
1058
						}
1059
						$casub .= "{$casubfield['a']}={$casubfield['v']}/";
1060
					}
1061

    
1062
				}
1063
			}
1064

    
1065
			$authentication = "";
1066
			switch ($ph1ent['authentication_method']) {
1067
				case 'eap-mschapv2':
1068
					if (isset($ph1ent['mobile'])) {
1069
						$authentication = "eap_identity=%any\n\t";
1070
						$authentication .= "leftauth=pubkey\n\trightauth=eap-mschapv2";
1071
						if (!empty($ph1ent['certref'])) {
1072
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1073
							$authentication .= "\n\tleftsendcert=always";
1074
						}
1075
					}
1076
					break;
1077
				case 'eap-tls':
1078
					if (isset($ph1ent['mobile'])) {
1079
						$authentication = "eap_identity=%identity\n\t";
1080
						$authentication .= "leftauth=pubkey\n\trightauth=eap-tls";
1081
						if (!empty($ph1ent['certref'])) {
1082
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1083
							$authentication .= "\n\tleftsendcert=always";
1084
						}
1085
					} else {
1086
						$authentication = "leftauth=eap-tls\n\trightauth=eap-tls";
1087
						if (!empty($ph1ent['certref'])) {
1088
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1089
							$authentication .= "\n\tleftsendcert=always";
1090
						}
1091
					}
1092
					if (isset($casub)) {
1093
						$authentication .= "\n\trightca=\"$casub\"";
1094
					}
1095
					break;
1096
				case 'eap-radius':
1097
					if (isset($ph1ent['mobile'])) {
1098
						$authentication = "eap_identity=%identity\n\t";
1099
						$authentication .= "leftauth=pubkey\n\trightauth=eap-radius";
1100
						if (!empty($ph1ent['certref'])) {
1101
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1102
							$authentication .= "\n\tleftsendcert=always";
1103
						}
1104
					} else {
1105
						$authentication = "leftauth=eap-radius\n\trightauth=eap-radius";
1106
						if (!empty($ph1ent['certref'])) {
1107
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1108
							$authentication .= "\n\tleftsendcert=always";
1109
						}
1110
					}
1111
					break;
1112
				case 'xauth_rsa_server':
1113
					$authentication = "leftauth = pubkey\n\trightauth = pubkey";
1114
					$authentication .= "\n\trightauth2 = xauth-generic";
1115
					if (!empty($ph1ent['certref'])) {
1116
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1117
					}
1118
					if (isset($casub)) {
1119
						$authentication .= "\n\trightca=\"$casub\"";
1120
					}
1121
					break;
1122
				case 'xauth_psk_server':
1123
					$authentication = "leftauth = psk\n\trightauth = psk";
1124
					$authentication .= "\n\trightauth2 = xauth-generic";
1125
					break;
1126
				case 'pre_shared_key':
1127
					$authentication = "leftauth = psk\n\trightauth = psk";
1128
					break;
1129
				case 'rsasig':
1130
					$authentication = "leftauth = pubkey\n\trightauth = pubkey";
1131
					if (!empty($ph1ent['certref'])) {
1132
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1133
					}
1134
					if (isset($casub)) {
1135
						$authentication .= "\n\trightca=\"$casub\"";
1136
					}
1137
					break;
1138
				case 'hybrid_rsa_server':
1139
					$authentication = "leftauth = pubkey\n\trightauth = xauth-generic";
1140
					if (!empty($ph1ent['certref'])) {
1141
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
1142
					}
1143
					break;
1144
			}
1145

    
1146
			$left_spec = $ep;
1147

    
1148
			if (isset($ph1ent['reauth_enable'])) {
1149
				$reauth = "reauth = no";
1150
			} else {
1151
				$reauth = "reauth = yes";
1152
			}
1153
			if (isset($ph1ent['rekey_enable'])) {
1154
				$rekey = "rekey = no";
1155
			} else {
1156
				$rekey = "rekey = yes";
1157
			}
1158

    
1159
			if ($ph1ent['nat_traversal'] == 'off') {
1160
				$forceencaps = 'forceencaps = no';
1161
			} else if ($ph1ent['nat_traversal'] == 'force') {
1162
				$forceencaps = 'forceencaps = yes';
1163
			} else {
1164
				$forceencaps = 'forceencaps = no';
1165
			}
1166

    
1167
			if ($ph1ent['mobike'] == 'on') {
1168
				$mobike = 'mobike = yes';
1169
			} else {
1170
				$mobike = 'mobike = no';
1171
			}
1172

    
1173
			$ipseclifetime = 0;
1174
			$rightsubnet_spec = array();
1175
			$leftsubnet_spec = array();
1176
			$reqids = array();
1177
			$ealgoAHsp2arr = array();
1178
			$ealgoESPsp2arr = array();
1179
		if (is_array($a_phase2) && count($a_phase2)) {
1180
			foreach ($a_phase2 as $ph2ent) {
1181
				if ($ikeid != $ph2ent['ikeid']) {
1182
					continue;
1183
				}
1184

    
1185
				if (isset($ph2ent['disabled'])) {
1186
					continue;
1187
				}
1188

    
1189
				if (isset($ph2ent['mobile']) && !isset($a_client['enable'])) {
1190
					continue;
1191
				}
1192

    
1193
				if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
1194
					$tunneltype = "type = tunnel";
1195

    
1196
					$localid_type = $ph2ent['localid']['type'];
1197
					$leftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['localid'], false, $ph2ent['mode']);
1198

    
1199
					/* Do not print localid in some cases, such as a pure-psk or psk/xauth single phase2 mobile tunnel */
1200
					if (($localid_type == "none" || $localid_type == "mobile") &&
1201
					    isset($ph1ent['mobile']) && (ipsec_get_number_of_phase2($ikeid) == 1)) {
1202
						$left_spec = '%any';
1203
					} else {
1204
						if ($localid_type != "address") {
1205
							$localid_type = "subnet";
1206
						}
1207
						// Don't let an empty subnet into config, it can cause parse errors. Ticket #2201.
1208
						if (!is_ipaddr($leftsubnet_data) && !is_subnet($leftsubnet_data) && ($leftsubnet_data != "0.0.0.0/0")) {
1209
							log_error("Invalid IPsec Phase 2 \"{$ph2ent['descr']}\" - {$ph2ent['localid']['type']} has no subnet.");
1210
							continue;
1211
						}
1212
						if (!empty($ph2ent['natlocalid'])) {
1213
							$natleftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['natlocalid'], false, $ph2ent['mode']);
1214
							if ($ph2ent['natlocalid']['type'] != "address") {
1215
								if (is_subnet($natleftsubnet_data)) {
1216
									$leftsubnet_data = "{$natleftsubnet_data}|{$leftsubnet_data}";
1217
								}
1218
							} else {
1219
								if (is_ipaddr($natleftsubnet_data)) {
1220
									$leftsubnet_data = "{$natleftsubnet_data}|{$leftsubnet_data}";
1221
								}
1222
							}
1223
							$natfilterrules = true;
1224
						}
1225
					}
1226

    
1227
					$leftsubnet_spec[] = $leftsubnet_data;
1228

    
1229
					if (!isset($ph2ent['mobile'])) {
1230
						$tmpsubnet = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']);
1231
						$rightsubnet_spec[] = $tmpsubnet;
1232
					} else if (!empty($a_client['pool_address'])) {
1233
						$rightsubnet_spec[] = "{$a_client['pool_address']}/{$a_client['pool_netbits']}";
1234
					}
1235
				} else {
1236
					$tunneltype = "type = transport";
1237

    
1238
					if ((($ph1ent['authentication_method'] == "xauth_psk_server") ||
1239
					     ($ph1ent['authentication_method'] == "pre_shared_key")) &&
1240
					    isset($ph1ent['mobile'])) {
1241
						$left_spec = "%any";
1242
					} else {
1243
						$tmpsubnet = ipsec_get_phase1_src($ph1ent);
1244
						$leftsubnet_spec[] = $tmpsubnet;
1245
					}
1246

    
1247
					if (!isset($ph2ent['mobile'])) {
1248
						$rightsubnet_spec[] = $right_spec;
1249
					}
1250
				}
1251

    
1252
				if (isset($a_client['pfs_group']) && isset($ph2ent['mobile'])) {
1253
					$ph2ent['pfsgroup'] = $a_client['pfs_group'];
1254
				}
1255

    
1256
				if ($ph2ent['protocol'] == 'esp') {
1257
					if (is_array($ph2ent['encryption-algorithm-option'])) {
1258
						foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
1259
							$ealg_id = $ealg['name'];
1260
							$ealg_kl = $ealg['keylen'];
1261

    
1262
							if (!empty($ealg_kl) && $ealg_kl == "auto") {
1263
								if (empty($p2_ealgos) || !is_array($p2_ealgos)) {
1264
									require("ipsec.inc");
1265
								}
1266
								$key_hi = $p2_ealgos[$ealg_id]['keysel']['hi'];
1267
								$key_lo = $p2_ealgos[$ealg_id]['keysel']['lo'];
1268
								$key_step = $p2_ealgos[$ealg_id]['keysel']['step'];
1269
								/* XXX: in some cases where include ordering is suspect these variables
1270
								 * are somehow 0 and we enter this loop forever and timeout after 900
1271
								 * seconds wrecking bootup */
1272
								if ($key_hi != 0 and $key_lo != 0 and $key_step != 0) {
1273
									for ($keylen = $key_hi; $keylen >= $key_lo; $keylen -= $key_step) {
1274
										if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
1275
											foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
1276
												$halgo = str_replace('hmac_', '', $halgo);
1277
												$tmpealgo = "{$ealg_id}{$keylen}-{$halgo}";
1278
												$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1279
												if (!empty($modp)) {
1280
													$tmpealgo .= "-{$modp}";
1281
												}
1282
												$ealgoESPsp2arr[] = $tmpealgo;
1283
											}
1284
										} else {
1285
											$tmpealgo = "{$ealg_id}{$keylen}";
1286
											$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1287
											if (!empty($modp)) {
1288
												$tmpealgo .= "-{$modp}";
1289
											}
1290
											$ealgoESPsp2arr[] = $tmpealgo;
1291
										}
1292
									}
1293
								}
1294
							} else {
1295
								if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
1296
									foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
1297
										$halgo = str_replace('hmac_', '', $halgo);
1298
										$tmpealgo = "{$ealg_id}{$ealg_kl}-{$halgo}";
1299
										$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1300
										if (!empty($modp)) {
1301
											$tmpealgo .= "-{$modp}";
1302
										}
1303
										$ealgoESPsp2arr[] = $tmpealgo;
1304
									}
1305
								} else {
1306
									$tmpealgo = "{$ealg_id}{$ealg_kl}";
1307
									$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1308
									if (!empty($modp)) {
1309
										$tmpealgo .= "-{$modp}";
1310
									}
1311
									$ealgoESPsp2arr[] = $tmpealgo;
1312
								}
1313
							}
1314
						}
1315
					}
1316
				} else if ($ph2ent['protocol'] == 'ah') {
1317
					if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
1318
						$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1319
						foreach ($ph2ent['hash-algorithm-option'] as $tmpAHalgo) {
1320
							$tmpAHalgo = str_replace('hmac_', '', $tmpAHalgo);
1321
							if (!empty($modp)) {
1322
								$tmpAHalgo = "-{$modp}";
1323
							}
1324
							$ealgoAHsp2arr[] = $tmpAHalgo;
1325
						}
1326
					}
1327
				}
1328

    
1329
				$reqids[] = $ph2ent['reqid'];
1330

    
1331
				if (!empty($ph2ent['lifetime'])) {
1332
					if ($ipseclifetime == 0 || intval($ipseclifetime) > intval($ph2ent['lifetime'])) {
1333
						$ipseclifetime = intval($ph2ent['lifetime']);
1334
					}
1335
				}
1336

    
1337
			}
1338
		}
1339

    
1340
			$ipsecconnect =<<<EOD
1341
	fragmentation = yes
1342
	keyexchange = {$keyexchange}
1343
	{$reauth}
1344
	{$forceencaps}
1345
	{$mobike}
1346
	{$rekey}
1347
	installpolicy = yes
1348
	{$tunneltype}
1349
	{$dpdline}
1350
	auto = {$passive}
1351
	left = {$left_spec}
1352
	right = {$right_spec}
1353
	{$leftid}
1354

    
1355
EOD;
1356

    
1357
			if (isset($config['ipsec']['compression'])) {
1358
				$ipsecconnect .= "\tcompress = yes\n";
1359
				$enablecompression = true;
1360
			}
1361
			if (!empty($ikelifeline)) {
1362
				$ipsecconnect .= "\t{$ikelifeline}\n";
1363
			}
1364
			if ($ipseclifetime > 0) {
1365
				$ipsecconnect .= "\tlifetime = {$ipseclifetime}s\n";
1366
			}
1367
			if (!empty($rightsourceip)) {
1368
				$ipsecconnect .= "{$rightsourceip}";
1369
			}
1370
			if (!empty($ealgosp1)) {
1371
				$ipsecconnect .= "\t{$ealgosp1}\n";
1372
			}
1373
			if (!empty($ealgoAHsp2arr)) {
1374
				$ipsecconnect .= "\tah = " . join(',', $ealgoAHsp2arr) . "!\n";
1375
			}
1376
			if (!empty($ealgoESPsp2arr)) {
1377
				$ipsecconnect .= "\tesp = " . join(',', $ealgoESPsp2arr) . "!\n";
1378
			}
1379
			if (!empty($authentication)) {
1380
				$ipsecconnect .= "\t{$authentication}\n";
1381
			}
1382
			if (!empty($peerid_spec)) {
1383
				$ipsecconnect .= "\trightid = {$peerid_spec}\n";
1384
			}
1385
			if ($keyexchange == 'ikev1') {
1386
				$ipsecconnect .= "\taggressive = {$aggressive}\n";
1387
			}
1388

    
1389
			if (!isset($ph1ent['mobile']) && $keyexchange == 'ikev1') {
1390
				if (!empty($rightsubnet_spec)) {
1391
					$ipsecfin = '';
1392
					foreach ($rightsubnet_spec as $idx => $rsubnet) {
1393
						$ipsecfin .= "\nconn con{$ph1ent['ikeid']}00{$idx}\n";
1394
						//if (!empty($reqids[$idx])) {
1395
						//	$ipsecfin .= "\treqid = " . $reqids[$idx] . "\n";
1396
						//}
1397
						$ipsecfin .= $ipsecconnect;
1398
						$ipsecfin .= "\trightsubnet = {$rsubnet}\n";
1399
						$ipsecfin .= "\tleftsubnet = " . $leftsubnet_spec[$idx] . "\n";
1400
					}
1401
				} else {
1402
					log_error("No phase2 specifications for tunnel with REQID = {$ikeid}");
1403
				}
1404
			} else {
1405
				$ipsecfin = "\nconn con{$ph1ent['ikeid']}\n";
1406
				//if (!empty($reqids[$idx])) {
1407
				//	$ipsecfin .= "\treqid = " . $reqids[0] . "\n";
1408
				//}
1409
				$ipsecfin .= $ipsecconnect;
1410
				if (!isset($ph1ent['mobile']) && !empty($rightsubnet_spec)) {
1411
					$tempsubnets = array();
1412
					foreach ($rightsubnet_spec as $rightsubnet) {
1413
						$tempsubnets[$rightsubnet] = $rightsubnet;
1414
					}
1415
					$ipsecfin .= "\trightsubnet = " . join(",", $tempsubnets) . "\n";
1416
					unset($tempsubnets, $rightsubnet);
1417
				}
1418
				if (!empty($leftsubnet_spec)) {
1419
					$tempsubnets = array();
1420
					foreach ($leftsubnet_spec as $leftsubnet) {
1421
						$tempsubnets[$leftsubnet] = $leftsubnet;
1422
					}
1423
					$ipsecfin .= "\tleftsubnet = " . join(",", $tempsubnets) . "\n";
1424
					unset($tempsubnets, $leftsubnet);
1425
				}
1426
			}
1427
			$ipsecconf .= $ipsecfin;
1428
			unset($ipsecfin);
1429
		}
1430
	}
1431

    
1432
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.conf", $ipsecconf);
1433
	unset($ipsecconf);
1434
	/* end ipsec.conf */
1435

    
1436
	if ($enablecompression === true) {
1437
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 1);
1438
	} else {
1439
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 0);
1440
	}
1441

    
1442
	/* manage process */
1443
	if ($restart === true) {
1444
		mwexec("/usr/local/sbin/ipsec restart", false);
1445
	} else {
1446
		if (isvalidpid("{$g['varrun_path']}/starter.charon.pid")) {
1447
			/* Update configuration changes */
1448
			/* Read secrets */
1449
			mwexec("/usr/local/sbin/ipsec rereadall", false);
1450
			mwexec("/usr/local/sbin/ipsec reload", false);
1451
		} else {
1452
			mwexec("/usr/local/sbin/ipsec start", false);
1453
		}
1454
	}
1455

    
1456
	// run ping_hosts.sh once if it's enabled to avoid wait for minicron
1457
	if ($ipsecpinghostsactive == true) {
1458
		mwexec_bg("/usr/local/bin/ping_hosts.sh");
1459
	}
1460

    
1461
	if ($natfilterrules == true) {
1462
		filter_configure();
1463
	}
1464
	/* start filterdns, if necessary */
1465
	if (count($filterdns_list) > 0) {
1466
		$interval = 60;
1467
		if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval'])) {
1468
			$interval = $ipseccfg['dns-interval'];
1469
		}
1470

    
1471
		$hostnames = "";
1472
		array_unique($filterdns_list);
1473
		foreach ($filterdns_list as $hostname) {
1474
			$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload ipsecdns\"'\n";
1475
		}
1476
		file_put_contents("{$g['varetc_path']}/ipsec/filterdns-ipsec.hosts", $hostnames);
1477
		unset($hostnames);
1478

    
1479
		if (isvalidpid("{$g['varrun_path']}/filterdns-ipsec.pid")) {
1480
			sigkillbypid("{$g['varrun_path']}/filterdns-ipsec.pid", "HUP");
1481
		} else {
1482
			mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/ipsec/filterdns-ipsec.hosts -d 1");
1483
		}
1484
	} else {
1485
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
1486
		@unlink("{$g['varrun_path']}/filterdns-ipsec.pid");
1487
	}
1488

    
1489
	if (platform_booting()) {
1490
		echo "done\n";
1491
	}
1492

    
1493
	return count($filterdns_list);
1494
}
1495

    
1496
/*
1497
 * Forcefully restart IPsec
1498
 * This is required for when dynamic interfaces reload
1499
 * For all other occasions the normal vpn_ipsec_configure()
1500
 * will gracefully reload the settings without restarting
1501
 */
1502
function vpn_ipsec_force_reload($interface = "") {
1503
	global $g, $config;
1504

    
1505
	if (!ipsec_enabled()) {
1506
		return;
1507
	}
1508

    
1509
	$ipseccfg = $config['ipsec'];
1510

    
1511
	if (!empty($interface) && is_array($ipseccfg['phase1'])) {
1512
		$found = false;
1513
		foreach ($ipseccfg['phase1'] as $ipsec) {
1514
			if (!isset($ipsec['disabled']) && ($ipsec['interface'] == $interface)) {
1515
				$found = true;
1516
				break;
1517
			}
1518
		}
1519
		if (!$found) {
1520
			log_error(sprintf(gettext("Ignoring IPsec reload since there are no tunnels on interface %s"), $interface));
1521
			return;
1522
		}
1523
	}
1524

    
1525
	/* If we get this far then we need to take action. */
1526
	log_error(gettext("Forcefully reloading IPsec"));
1527
	vpn_ipsec_configure();
1528
}
1529

    
1530
/* master setup for vpn (mpd) */
1531
function vpn_setup() {
1532
	/* start pppoe server */
1533
	vpn_pppoes_configure();
1534

    
1535
	/* setup l2tp */
1536
	vpn_l2tp_configure();
1537
}
1538

    
1539
function vpn_netgraph_support() {
1540
	$iflist = get_configured_interface_list();
1541
	foreach ($iflist as $iface) {
1542
		$realif = get_real_interface($iface);
1543
		/* Get support for netgraph(4) from the nic */
1544
		$ifinfo = pfSense_get_interface_addresses($realif);
1545
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge"))) {
1546
			pfSense_ngctl_attach(".", $realif);
1547
		}
1548
	}
1549
}
1550

    
1551
function vpn_pppoes_configure() {
1552
	global $config;
1553

    
1554
	if (is_array($config['pppoes']['pppoe'])) {
1555
		foreach ($config['pppoes']['pppoe'] as $pppoe) {
1556
			vpn_pppoe_configure($pppoe);
1557
		}
1558
	}
1559
}
1560

    
1561
function vpn_pppoe_configure(&$pppoecfg) {
1562
	global $config, $g;
1563

    
1564
	$syscfg = $config['system'];
1565

    
1566
	/* create directory if it does not exist */
1567
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn")) {
1568
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1569
	}
1570

    
1571
	if (platform_booting()) {
1572
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off")) {
1573
			return 0;
1574
		}
1575

    
1576
		echo gettext("Configuring PPPoE Server service... ");
1577
	} else {
1578
		/* kill mpd */
1579
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1580

    
1581
		/* wait for process to die */
1582
		sleep(2);
1583

    
1584
	}
1585

    
1586
	switch ($pppoecfg['mode']) {
1587

    
1588
		case 'server':
1589

    
1590
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1591

    
1592
			if ($pppoecfg['paporchap'] == "chap") {
1593
				$paporchap = "set link enable chap";
1594
			} else {
1595
				$paporchap = "set link enable pap";
1596
			}
1597

    
1598
			/* write mpd.conf */
1599
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1600
			if (!$fd) {
1601
				printf(gettext("Error: cannot open mpd.conf in vpn_pppoe_configure().") . "\n");
1602
				return 1;
1603
			}
1604
			$mpdconf = "\n\n";
1605
			$mpdconf .= "poes:\n";
1606

    
1607
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1608
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1609
			}
1610

    
1611
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1612

    
1613
				$clientip = ip_after($pppoecfg['remoteip'], $i);
1614

    
1615
				if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1616
					$issue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1617
				} else {
1618
					$issue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1619
				}
1620

    
1621
				$mpdconf .=<<<EOD
1622

    
1623
poes{$pppoecfg['pppoeid']}{$i}:
1624
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1625
	{$issue_ip_type}
1626
	load pppoe_standard
1627

    
1628
EOD;
1629
			}
1630
			if (is_numeric($pppoecfg['n_pppoe_maxlogin']) && ($pppoecfg['n_pppoe_maxlogin'] > 0)) {
1631
				$pppoemaxlogins = $pppoecfg['n_pppoe_maxlogin'];
1632
			} else {
1633
				$pppoemaxlogins = 1;
1634
			}
1635

    
1636
			$mpdconf .=<<<EOD
1637

    
1638
pppoe_standard:
1639
	set bundle no multilink
1640
	set bundle enable compression
1641
	set auth max-logins {$pppoemaxlogins}
1642
	set iface up-script /usr/local/sbin/vpn-linkup
1643
	set iface down-script /usr/local/sbin/vpn-linkdown
1644
	set iface idle 0
1645
	set iface disable on-demand
1646
	set iface disable proxy-arp
1647
	set iface enable tcpmssfix
1648
	set iface mtu 1500
1649
	set link no pap chap
1650
	{$paporchap}
1651
	set link keep-alive 60 180
1652
	set ipcp yes vjcomp
1653
	set ipcp no vjcomp
1654
	set link max-redial -1
1655
	set link mtu 1492
1656
	set link mru 1492
1657
	set ccp yes mpp-e40
1658
	set ccp yes mpp-e128
1659
	set ccp yes mpp-stateless
1660
	set link latency 1
1661
	#set ipcp dns 10.10.1.3
1662
	#set bundle accept encryption
1663

    
1664
EOD;
1665

    
1666
			if (!empty($pppoecfg['dns1'])) {
1667
				$mpdconf .= "	set ipcp dns " . $pppoecfg['dns1'];
1668
				if (!empty($pppoecfg['dns2'])) {
1669
					$mpdconf .= " " . $pppoecfg['dns2'];
1670
				}
1671
				$mpdconf .= "\n";
1672
			} elseif (isset ($config['dnsmasq']['enable'])) {
1673
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1674
				if ($syscfg['dnsserver'][0]) {
1675
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1676
				}
1677
				$mpdconf .= "\n";
1678
			} elseif (isset ($config['unbound']['enable'])) {
1679
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1680
				if ($syscfg['dnsserver'][0]) {
1681
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1682
				}
1683
				$mpdconf .= "\n";
1684
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1685
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1686
			}
1687

    
1688
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1689
				$radiusport = "";
1690
				$radiusacctport = "";
1691
				if (isset($pppoecfg['radius']['server']['port'])) {
1692
					$radiusport = $pppoecfg['radius']['server']['port'];
1693
				}
1694
				if (isset($pppoecfg['radius']['server']['acctport'])) {
1695
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1696
				}
1697
				$mpdconf .=<<<EOD
1698
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
1699
	set radius retries 3
1700
	set radius timeout 10
1701
	set auth enable radius-auth
1702

    
1703
EOD;
1704

    
1705
				if (isset ($pppoecfg['radius']['accounting'])) {
1706
					$mpdconf .=<<<EOD
1707
	set auth enable radius-acct
1708

    
1709
EOD;
1710
				}
1711
				if (isset($pppoecfg['radius']['nasip'])) {
1712
					$mpdconf .= "\tset radius me {$pppoecfg['radius']['nasip']}\n";
1713
				}
1714
			}
1715

    
1716
			fwrite($fd, $mpdconf);
1717
			fclose($fd);
1718
			unset($mpdconf);
1719

    
1720
			/* write mpd.links */
1721
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.links", "w");
1722
			if (!$fd) {
1723
				printf(gettext("Error: cannot open mpd.links in vpn_pppoe_configure().") . "\n");
1724
				return 1;
1725
			}
1726

    
1727
			$mpdlinks = "";
1728

    
1729
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1730
				$mpdlinks .=<<<EOD
1731

    
1732
poes{$pppoecfg['pppoeid']}{$i}:
1733
	set phys type pppoe
1734
	set pppoe iface {$pppoe_interface}
1735
	set pppoe service "*"
1736
	set pppoe disable originate
1737
	set pppoe enable incoming
1738

    
1739
EOD;
1740
			}
1741

    
1742
			fwrite($fd, $mpdlinks);
1743
			fclose($fd);
1744
			unset($mpdlinks);
1745

    
1746
			if ($pppoecfg['username']) {
1747
				/* write mpd.secret */
1748
				$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
1749
				if (!$fd) {
1750
					printf(gettext("Error: cannot open mpd.secret in vpn_pppoe_configure().") . "\n");
1751
					return 1;
1752
				}
1753

    
1754
				$mpdsecret = "\n\n";
1755

    
1756
				if (!empty($pppoecfg['username'])) {
1757
					$item = explode(" ", $pppoecfg['username']);
1758
					foreach ($item as $userdata) {
1759
						$data = explode(":", $userdata);
1760
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1761
					}
1762
				}
1763

    
1764
				fwrite($fd, $mpdsecret);
1765
				fclose($fd);
1766
				unset($mpdsecret);
1767
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1768
			}
1769

    
1770
			/* Check if previous instance is still up */
1771
			while (file_exists("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid") && isvalidpid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid")) {
1772
				killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1773
			}
1774

    
1775
			/* Get support for netgraph(4) from the nic */
1776
			pfSense_ngctl_attach(".", $pppoe_interface);
1777
			/* fire up mpd */
1778
			mwexec("/usr/local/sbin/mpd4 -b -d {$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn -p {$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid -s poes poes");
1779

    
1780
			break;
1781
	}
1782

    
1783
	if (platform_booting()) {
1784
		echo gettext("done") . "\n";
1785
	}
1786

    
1787
	return 0;
1788
}
1789

    
1790
function vpn_l2tp_configure() {
1791
	global $config, $g;
1792

    
1793
	$syscfg = $config['system'];
1794
	$l2tpcfg = $config['l2tp'];
1795

    
1796
	/* create directory if it does not exist */
1797
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn")) {
1798
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1799
	}
1800

    
1801
	if (platform_booting()) {
1802
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off")) {
1803
			return 0;
1804
		}
1805

    
1806
		echo gettext("Configuring l2tp VPN service... ");
1807
	} else {
1808
		/* kill mpd */
1809
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1810

    
1811
		/* wait for process to die */
1812
		sleep(8);
1813

    
1814
	}
1815

    
1816
	/* make sure l2tp-vpn directory exists */
1817
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn")) {
1818
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1819
	}
1820

    
1821
	switch ($l2tpcfg['mode']) {
1822

    
1823
		case 'server':
1824
			$l2tp_listen="";
1825
			$ipaddr = get_interface_ip(get_failover_interface($l2tpcfg['interface']));
1826
			if (is_ipaddrv4($ipaddr)) {
1827
				$l2tp_listen="set l2tp self $ipaddr";
1828
			}
1829

    
1830
			switch ($l2tpcfg['paporchap']) {
1831
				case 'chap':
1832
					$paporchap = "set link enable chap";
1833
					break;
1834
				case 'chap-msv2':
1835
					$paporchap = "set link enable chap-msv2";
1836
					break;
1837
				default:
1838
					$paporchap = "set link enable pap";
1839
					break;
1840
			}
1841

    
1842
			/* write mpd.conf */
1843
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1844
			if (!$fd) {
1845
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
1846
				return 1;
1847
			}
1848
			$mpdconf = "\n\n";
1849
			$mpdconf .=<<<EOD
1850
l2tps:
1851

    
1852
EOD;
1853

    
1854
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1855
				$mpdconf .= "	load l2tp{$i}\n";
1856
			}
1857

    
1858
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1859

    
1860
				$clientip = ip_after($l2tpcfg['remoteip'], $i);
1861

    
1862
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1863
					$issue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1864
				} else {
1865
					$issue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1866
				}
1867

    
1868
				$mpdconf .=<<<EOD
1869

    
1870
l2tp{$i}:
1871
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1872
	{$issue_ip_type}
1873
	load l2tp_standard
1874

    
1875
EOD;
1876
			}
1877

    
1878
			$mpdconf .=<<<EOD
1879

    
1880
l2tp_standard:
1881
	set bundle disable multilink
1882
	set bundle enable compression
1883
	set bundle yes crypt-reqd
1884
	set ipcp yes vjcomp
1885
	# set ipcp ranges 131.188.69.161/32 131.188.69.170/28
1886
	set ccp yes mppc
1887
	set iface disable on-demand
1888
	set iface enable proxy-arp
1889
	set iface up-script /usr/local/sbin/vpn-linkup
1890
	set iface down-script /usr/local/sbin/vpn-linkdown
1891
	set link yes acfcomp protocomp
1892
	set link no pap chap
1893
	{$paporchap}
1894
	{$l2tp_listen}
1895
	set link keep-alive 10 180
1896

    
1897
EOD;
1898

    
1899
			if (is_ipaddr($l2tpcfg['wins'])) {
1900
				$mpdconf .= "	set ipcp nbns {$l2tpcfg['wins']}\n";
1901
			}
1902
			if (is_ipaddr($l2tpcfg['dns1'])) {
1903
				$mpdconf .= "	set ipcp dns " . $l2tpcfg['dns1'];
1904
				if (is_ipaddr($l2tpcfg['dns2'])) {
1905
					$mpdconf .= " " . $l2tpcfg['dns2'];
1906
				}
1907
				$mpdconf .= "\n";
1908
			} elseif (isset ($config['dnsmasq']['enable'])) {
1909
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1910
				if ($syscfg['dnsserver'][0]) {
1911
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1912
				}
1913
				$mpdconf .= "\n";
1914
			} elseif (isset ($config['unbound']['enable'])) {
1915
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1916
				if ($syscfg['dnsserver'][0]) {
1917
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1918
				}
1919
				$mpdconf .= "\n";
1920
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1921
				$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1922
			}
1923

    
1924
			if (isset ($l2tpcfg['radius']['enable'])) {
1925
				$mpdconf .=<<<EOD
1926
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1927
	set radius retries 3
1928
	set radius timeout 10
1929
	set auth enable radius-auth
1930

    
1931
EOD;
1932

    
1933
				if (isset ($l2tpcfg['radius']['accounting'])) {
1934
					$mpdconf .=<<<EOD
1935
	set auth enable radius-acct
1936

    
1937
EOD;
1938
				}
1939
			}
1940

    
1941
			fwrite($fd, $mpdconf);
1942
			fclose($fd);
1943
			unset($mpdconf);
1944

    
1945
			/* write mpd.links */
1946
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.links", "w");
1947
			if (!$fd) {
1948
				printf(gettext("Error: cannot open mpd.links in vpn_l2tp_configure().") . "\n");
1949
				return 1;
1950
			}
1951

    
1952
			$mpdlinks = "";
1953

    
1954
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1955
				$mpdlinks .=<<<EOD
1956

    
1957
l2tp{$i}:
1958
	set link type l2tp
1959
	set l2tp enable incoming
1960
	set l2tp disable originate
1961

    
1962
EOD;
1963
				if (!empty($l2tpcfg['secret'])) {
1964
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
1965
				}
1966
			}
1967

    
1968
			fwrite($fd, $mpdlinks);
1969
			fclose($fd);
1970
			unset($mpdlinks);
1971

    
1972
			/* write mpd.secret */
1973
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.secret", "w");
1974
			if (!$fd) {
1975
				printf(gettext("Error: cannot open mpd.secret in vpn_l2tp_configure().") . "\n");
1976
				return 1;
1977
			}
1978

    
1979
			$mpdsecret = "\n\n";
1980

    
1981
			if (is_array($l2tpcfg['user'])) {
1982
				foreach ($l2tpcfg['user'] as $user) {
1983
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1984
				}
1985
			}
1986

    
1987
			fwrite($fd, $mpdsecret);
1988
			fclose($fd);
1989
			unset($mpdsecret);
1990
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
1991

    
1992
			vpn_netgraph_support();
1993

    
1994
			/* fire up mpd */
1995
			mwexec("/usr/local/sbin/mpd4 -b -d {$g['varetc_path']}/l2tp-vpn -p {$g['varrun_path']}/l2tp-vpn.pid -s l2tps l2tps");
1996

    
1997
			break;
1998

    
1999
		case 'redir':
2000
			break;
2001
	}
2002

    
2003
	if (platform_booting()) {
2004
		echo "done\n";
2005
	}
2006

    
2007
	return 0;
2008
}
2009

    
2010
?>
(57-57/65)