Project

General

Profile

Download (56.7 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2

    
3
/*
4
	vpn.inc
5
	Copyright (C) 2004 Scott Ullrich
6
	Copyright (C) 2008 Shrew Soft Inc
7
	Copyright (C) 2008 Ermal Lu�i
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 the
22
	   documentation and/or other materials provided with the distribution.
23

    
24
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
25
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
26
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
28
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33
	POSSIBILITY OF SUCH DAMAGE.
34
*/
35

    
36
/*
37
	pfSense_BUILDER_BINARIES:	/sbin/ifconfig
38
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/ipsec	/usr/local/libexec/ipsec/charon /usr/local/libexec/ipsec/starter
39
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/filterdns	/usr/local/sbin/mpd4
40
	pfSense_MODULE:	vpn
41
*/
42

    
43
require_once("ipsec.inc");
44

    
45
function vpn_ipsec_configure_loglevels($forconfig = false)
46
{
47
	global $config, $ipsec_loglevels;
48

    
49
	$cfgtext = array();
50
	foreach ($ipsec_loglevels as $lkey => $ldescr) {
51
		if (!isset($config['ipsec']["ipsec_{$lkey}"]) && !$forconfig) {
52
			mwexec("/usr/local/sbin/ipsec stroke loglevel {$lkey} -- -1", false);
53
		} else if (is_numeric($config['ipsec']["ipsec_{$lkey}"]) &&
54
		    intval($config['ipsec']["ipsec_{$lkey}"]) >= 0 && intval($config['ipsec']["ipsec_{$lkey}"]) <= 5) {
55
			$forconfig ? $cfgtext[] = "${lkey} " . (intval($config['ipsec']["ipsec_{$lkey}"]) - 1) :
56
				mwexec("/usr/local/sbin/ipsec stroke loglevel {$lkey} " . (intval($config['ipsec']["ipsec_{$lkey}"]) - 1) , false);
57
		}
58
	}
59
	if ($forconfig) {
60
		return implode(',', $cfgtext);
61
	}
62
}
63

    
64
/* include all configuration functions */
65
function vpn_ipsec_convert_to_modp($index)
66
{
67

    
68
	$convertion = "";
69
	switch ($index) {
70
		case '1':
71
			$convertion = "modp768";
72
			break;
73
		case '2':
74
			$convertion = "modp1024";
75
			break;
76
		case '5':
77
			$convertion = "modp1536";
78
			break;
79
		case '14':
80
			$convertion = "modp2048";
81
			break;
82
		case '15':
83
			$convertion = "modp3072";
84
			break;
85
		case '16':
86
			$convertion = "modp4096";
87
			break;
88
		case '17':
89
			$convertion = "modp6144";
90
			break;
91
		case '18':
92
			$convertion = "modp8192";
93
			break;
94
		case '19':
95
			$convertion = "ecp256";
96
			break;
97
		case '20':
98
			$convertion = "ecp384";
99
			break;
100
		case '21':
101
			$convertion = "ecp512";
102
			break;
103
	}
104

    
105
	return $convertion;
106
}
107

    
108
function vpn_ipsec_configure($restart = false)
109
{
110
	global $config, $g, $sa, $sn, $p1_ealgos, $p2_ealgos, $ipsec_idhandling;
111

    
112
	if ($g['platform'] == 'jail') {
113
		return;
114
	}
115

    
116
	/* get the automatic ping_hosts.sh ready */
117
	unlink_if_exists("{$g['vardb_path']}/ipsecpinghosts");
118
	touch("{$g['vardb_path']}/ipsecpinghosts");
119
	
120
	/* service may have been enabled, disabled, or otherwise changed in a way requiring rule updates */
121
	filter_configure();
122

    
123
	$syscfg = $config['system'];
124
	$ipseccfg = $config['ipsec'];
125
	if (!isset($ipseccfg['enable'])) {
126
		/* try to stop charon */
127
		mwexec("/usr/local/sbin/ipsec stop");
128
		/* Stop dynamic monitoring */
129
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
130

    
131
		/* wait for process to die */
132
		sleep(2);
133

    
134
		/* disallow IPSEC, it is off */
135
		mwexec("/sbin/ifconfig enc0 down");
136
		set_single_sysctl("net.inet.ip.ipsec_in_use", "0");
137

    
138
		return 0;
139
	}
140

    
141
	$a_phase1 = $config['ipsec']['phase1'];
142
	$a_phase2 = $config['ipsec']['phase2'];
143
	$a_client = $config['ipsec']['client'];
144

    
145
	$certpath = "{$g['varetc_path']}/ipsec/ipsec.d/certs";
146
	$capath = "{$g['varetc_path']}/ipsec/ipsec.d/cacerts";
147
	$keypath = "{$g['varetc_path']}/ipsec/ipsec.d/private";
148

    
149
	mwexec("/sbin/ifconfig enc0 up");
150
	set_single_sysctl("net.inet.ip.ipsec_in_use", "1");
151
	/* needed for config files */
152
	if (!is_dir("{$g['varetc_path']}/ipsec")) {
153
		mkdir("{$g['varetc_path']}/ipsec");
154
	}
155
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d")) {
156
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d");
157
	}
158
	if (!is_dir($capath)) {
159
		mkdir($capath);
160
	}
161
	if (!is_dir($keypath)) {
162
		mkdir($keypath);
163
	}
164
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/crls")) {
165
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/crls");
166
	}
167
	if (!is_dir($certpath)) {
168
		mkdir($certpath);
169
	}
170
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/aacerts")) {
171
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/aacerts");
172
	}
173
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/acerts")) {
174
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/acerts");
175
	}
176
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/ocspcerts")) {
177
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/ocspcerts");
178
	}
179
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/reqs")) {
180
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/reqs");
181
	}
182

    
183

    
184
	if (platform_booting()) {
185
		echo gettext("Configuring IPsec VPN... ");
186
	}
187

    
188
	/* fastforwarding is not compatible with ipsec tunnels */
189
	set_single_sysctl("net.inet.ip.fastforwarding", "0");
190

    
191
	/* resolve all local, peer addresses and setup pings */
192
	$ipmap = array();
193
	$rgmap = array();
194
	$filterdns_list = array();
195
	$listeniflist = array();
196
	$aggressive_mode_psk = false;
197
	unset($iflist);
198
	$ifacesuse = array();
199
	if (is_array($a_phase1) && count($a_phase1)) {
200

    
201
		$ipsecpinghosts = "";
202
		/* step through each phase1 entry */
203
		foreach ($a_phase1 as $ph1ent) {
204
			if (isset($ph1ent['disabled'])) {
205
				continue;
206
			}
207

    
208
			if (strpos($ph1ent['interface'], '_vip')) {
209
				$vpninterface = explode('_vip', $ph1ent['interface']);
210
				$ifacesuse[] = get_real_interface($vpninterface[0]);
211
			} else {
212
				$vpninterface = get_failover_interface($ph1ent['interface']);
213
				if (strpos($vpninterface, '_vip')) {
214
					$vpninterface = explode('_vip', $vpninterface);
215
					$ifacesuse[] = get_real_interface($vpninterface[0]);
216
				} elseif (!empty($vpninterface)) {
217
					$ifacesuse[] = $vpninterface;
218
				}
219
			}
220

    
221
			if ($ph1ent['mode'] == "aggressive" && ($ph1ent['authentication_method'] == "pre_shared_key" || $ph1ent['authentication_method'] == "xauth_psk_server")) {
222
				$aggressive_mode_psk = true;
223
			}
224

    
225
			$ikeid = $ph1ent['ikeid'];
226
			$listeniflist = get_real_interface($a_phase1['interface']);
227

    
228
			$ep = ipsec_get_phase1_src($ph1ent);
229
			if (!is_ipaddr($ep)) {
230
				log_error("IPsec ERROR: Could not find phase 1 source for connection {$ph1ent['descr']}. Omitting from configuration file.");
231
				continue;
232
			}
233

    
234
			if (!in_array($ep,$ipmap)) {
235
				$ipmap[] = $ep;
236
			}
237

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

    
241
			if (isset ($ph1ent['mobile'])) {
242
				continue;
243
			}
244

    
245
			$rg = $ph1ent['remote-gateway'];
246

    
247
			if (!is_ipaddr($rg)) {
248
				$filterdns_list[] = "{$rg}";
249
				add_hostname_to_watch($rg);
250
				if (!platform_booting()) {
251
					$rg = resolve_retry($rg);
252
				}
253
				if (!is_ipaddr($rg)) {
254
					continue;
255
				}
256
			}
257
			if (array_search($rg, $rgmap)) {
258
				log_error("The remote gateway {$rg} already exists on another phase 1 entry");
259
				continue;
260
			}
261
			$rgmap[$ph1ent['remote-gateway']] = $rg;
262

    
263
			if (is_array($a_phase2)) {
264
				/* step through each phase2 entry */
265
				foreach ($a_phase2 as $ph2ent) {
266
					if (isset($ph2ent['disabled'])) {
267
						continue;
268
					}
269

    
270
					if ($ikeid != $ph2ent['ikeid']) {
271
						continue;
272
					}
273

    
274
					/* add an ipsec pinghosts entry */
275
					if ($ph2ent['pinghost']) {
276
						if (!is_array($iflist)) {
277
							$iflist = get_configured_interface_list();
278
						}
279
						$srcip = null;
280
						$local_subnet = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
281
						if (is_ipaddrv6($ph2ent['pinghost'])) {
282
							foreach ($iflist as $ifent => $ifname) {
283
								$interface_ip = get_interface_ipv6($ifent);
284
								if (!is_ipaddrv6($interface_ip)) {
285
									continue;
286
								}
287
								if (ip_in_subnet($interface_ip, $local_subnet)) {
288
									$srcip = $interface_ip;
289
									break;
290
								}
291
							}
292
						} else {
293
							foreach ($iflist as $ifent => $ifname) {
294
								$interface_ip = get_interface_ip($ifent);
295
								if (!is_ipaddrv4($interface_ip)) {
296
									continue;
297
								}
298
								if ($local_subnet == "0.0.0.0/0" || ip_in_subnet($interface_ip, $local_subnet)) {
299
									$srcip = $interface_ip;
300
									break;
301
								}
302
							}
303
						}
304
						/* if no valid src IP was found in configured interfaces, try the vips */
305
						if (is_null($srcip)) {
306
							$viplist = get_configured_vips_list();
307
							foreach ($viplist as $vip) {
308
								if (ip_in_subnet($vip['ipaddr'], $local_subnet)) {
309
									$srcip = $vip['ipaddr'];
310
									break;
311
								}
312
							}
313
						}
314
						$dstip = $ph2ent['pinghost'];
315
						if (is_ipaddrv6($dstip)) {
316
							$family = "inet6";
317
						} else {
318
							$family = "inet";
319
						}
320
						if (is_ipaddr($srcip)) {
321
							$ipsecpinghosts[] = "{$srcip}|{$dstip}|3|||||{$family}|\n";
322
						}
323
					}
324
				}
325
			}
326
		}
327
		@file_put_contents("{$g['vardb_path']}/ipsecpinghosts", $ipsecpinghosts);
328
		unset($ipsecpinghosts);
329
	}
330
	unset($iflist);
331

    
332
	$accept_unencrypted = "";
333
	if (isset($config['ipsec']['acceptunencryptedmainmode'])) {
334
		$accept_unencrypted = "accept_unencrypted_mainmode_messages = yes";
335
	}
336

    
337
	$stronconf = '';
338
	if (file_exists("{$g['varetc_path']}/ipsec/strongswan.conf")) {
339
		$stronconf = file_get_contents("{$g['varetc_path']}/ipsec/strongswan.conf");
340
	}
341

    
342
	$i_dont_care_about_security_and_use_aggressive_mode_psk = "";
343
	if ($aggressive_mode_psk) {
344
		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.");
345
		if (!empty($stronconf) && strpos($stronconf, 'i_dont_care_about_security_and_use_aggressive_mode_psk') === FALSE) {
346
			$restart = true;
347
		}
348
		$i_dont_care_about_security_and_use_aggressive_mode_psk = "i_dont_care_about_security_and_use_aggressive_mode_psk=yes";
349
	}
350

    
351
	$unity_enabled = 'yes';
352
	if (isset($config['ipsec']['unityplugin'])) {
353
		$unity_enabled = 'no';
354
		if (file_exists("/usr/local/lib/ipsec/plugins/libstrongswan-unity.so")) {
355
			conf_mount_rw();
356
			mwexec("mv /usr/local/lib/ipsec/plugins/libstrongswan-unity.so /usr/local/lib/ipsec/plugins/libstrongswan-unity.MOVED");
357
			conf_mount_ro();
358
		}
359
	} else if (file_exists("/usr/local/lib/ipsec/plugins/libstrongswan-unity.MOVED")) {
360
		conf_mount_rw();
361
		mwexec("mv /usr/local/lib/ipsec/plugins/libstrongswan-unity.MOVED /usr/local/lib/ipsec/plugins/libstrongswan-unity.so");
362
		conf_mount_ro();
363
	}
364

    
365
	$makebeforebreak = '';
366
	if (isset($config['ipsec']['makebeforebreak'])) {
367
		$makebeforebreak = 'make_before_break = yes';
368
	}
369

    
370
	if (isset($config['ipsec']['enableinterfacesuse'])) {
371
		if (!empty($ifacesuse)) {
372
			$ifacesuse = 'interfaces_use = ' . implode(',', array_unique($ifacesuse));
373
		} else {
374
			$ifacesuse = '';
375
		}
376
	} else {
377
		$ifacesuse = '';
378
	}
379

    
380
	unset($stronconf);
381

    
382
	$strongswan = <<<EOD
383

    
384
# Automatically generated config file - DO NOT MODIFY. Changes will be overwritten.
385
starter {
386
load_warning = no
387
}
388

    
389
charon {
390
# number of worker threads in charon
391
threads = 16
392
ikesa_table_size = 32
393
ikesa_table_segments = 4
394
init_limit_half_open = 1000
395
install_routes = no
396
{$i_dont_care_about_security_and_use_aggressive_mode_psk}
397
{$accept_unencrypted}
398
cisco_unity = {$unity_enabled}
399
{$ifacesuse}
400
{$makebeforebreak}
401

    
402
# And two loggers using syslog. The subsections define the facility to log
403
# to, currently one of: daemon, auth.
404
syslog {
405
	identifier = charon
406
	# default level to the LOG_DAEMON facility
407
	daemon {
408
		ike_name = yes
409
	}
410
	# very minimalistic IKE auditing logs to LOG_AUTHPRIV
411
	auth {
412
		default = -1
413
		ike = 1
414
		ike_name = yes
415
	}
416
}
417

    
418
EOD;
419

    
420
	$strongswan .= "\tplugins {\n";
421

    
422
	$a_servers = auth_get_authserver_list();
423
	foreach ($a_servers as $id => $pconfig) {
424
		if ($id == $config['ipsec']['client']['user_source'] && $pconfig['type'] == "radius") {
425
			$strongswan .= <<<EOD
426
		eap-radius {
427
			class_group = yes
428
			eap_start = no
429
			servers {
430
				primary {
431
					address = {$pconfig['host']}
432
					secret = {$pconfig['radius_secret']}
433
					auth_port = {$pconfig['radius_auth_port']}
434
					acct_port = {$pconfig['radius_acct_port']}
435
				}
436
			}
437
		}
438

    
439
EOD;
440
			break;
441
		}
442
	}
443

    
444
	if (is_array($a_client) && isset($a_client['enable'])) {
445
		$strongswan .= "\t\tattr {\n";
446
		if ($a_client['pool_address'] && $a_client['pool_netbits']) {
447
			$strongswan .= "\t\t\tsubnet = {$a_client['pool_address']}/{$a_client['pool_netbits']}\n";
448
		}
449

    
450
		$cfgservers = array();
451
		if (!empty($a_client['dns_server1'])) {
452
			$cfgservers[] = $a_client['dns_server1'];
453
		}
454
		if (!empty($a_client['dns_server2'])) {
455
			$cfgservers[] = $a_client['dns_server2'];
456
		}
457
		if (!empty($a_client['dns_server3'])) {
458
			$cfgservers[] = $a_client['dns_server3'];
459
		}
460
		if (!empty($a_client['dns_server4'])) {
461
			$cfgservers[] = $a_client['dns_server4'];
462
		}
463

    
464
		if (!empty($cfgservers)) {
465
			$strongswan .= "\t\t\tdns = " . implode(",", $cfgservers) . "\n";
466
		}
467
		unset($cfgservers);
468
		$cfgservers = array();
469
		if (!empty($a_client['wins_server1'])) {
470
			$cfgservers[] = $a_client['wins_server1'];
471
		}
472
		if (!empty($a_client['wins_server2'])) {
473
			$cfgservers[] = $a_client['wins_server2'];
474
		}
475
		if (!empty($cfgservers)) {
476
			$strongswan .= "\t\t\tnbns = " . implode(",", $cfgservers) . "\n";
477
		}
478
		unset($cfgservers);
479

    
480
		if (isset($a_client['net_list']) && is_array($a_phase2)) {
481
			$net_list = '';
482
			foreach ($a_phase2 as $ph2ent) {
483
				if (isset($ph2ent['disabled'])) {
484
					continue;
485
				}
486

    
487
				if (!isset($ph2ent['mobile'])) {
488
					continue;
489
				}
490

    
491
				$localid = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
492

    
493
				if (!empty($net_list)) {
494
					$net_list .= ",";
495
				}
496
				$net_list .= $localid;
497
			}
498

    
499
			if (!empty($net_list)) {
500
				$strongswan .= "\t\t\tsplit-include = {$net_list}\n";
501
				unset($net_list);
502
			}
503
		}
504

    
505
		if (!empty($a_client['dns_domain'])) {
506
			$strongswan .= "\t\t\t# Search domain and default domain\n";
507
			$strongswan .= "\t\t\t28674 = \"{$a_client['dns_domain']}\"\n";
508
			if (empty($a_client['dns_split'])) {
509
				$strongswan .= "\t\t\t28675 = \"{$a_client['dns_domain']}\"";
510
			}
511
			$strongswan .= "\n";
512
		}
513

    
514
		if (!empty($a_client['dns_split'])) {
515
			$strongswan .= "\t\t\t28675 = {$a_client['dns_split']}\n";
516
		}
517

    
518
		if (!empty($a_client['login_banner'])) {
519
			$strongswan .= "\t\t\t28672 = \"{$a_client['login_banner']}\"\n";
520
		}
521

    
522
		if (isset($a_client['save_passwd'])) {
523
			$strongswan .= "\t\t\t28673 = 1\n";
524
		}
525

    
526
		if ($a_client['pfs_group']) {
527
			$strongswan .= "\t\t\t28679 = \"{$a_client['pfs_group']}\"\n";
528
		}
529
		$strongswan .= "\t\t}\n";
530

    
531
		if ($a_client['user_source'] != "none") {
532
			$strongswan .= "\t\txauth-generic {\n";
533
			$strongswan .= "\t\t\tscript = /etc/inc/ipsec.auth-user.php\n";
534
			$strongswan .= "\t\t\tauthcfg = ";
535
			$firstsed = 0;
536
			$authcfgs = explode(",", $a_client['user_source']);
537
			foreach ($authcfgs as $authcfg) {
538
				if ($firstsed > 0) {
539
					$strongswan .= ",";
540
				}
541
				if ($authcfg == "system") {
542
					$authcfg = "Local Database";
543
				}
544
				$strongswan .= $authcfg;
545
				$firstsed = 1;
546
			}
547
			$strongswan .= "\n";
548
			$strongswan .= "\t\t}\n";
549
		}
550
	}
551

    
552
	$strongswan .= "\t}\n}\n";
553
	@file_put_contents("{$g['varetc_path']}/ipsec/strongswan.conf", $strongswan);
554
	unset($strongswan);
555

    
556
	/* generate CA certificates files */
557
	if (is_array($config['ca']) && count($config['ca'])) {
558
		foreach ($config['ca'] as $ca) {
559
			if (!isset($ca['crt'])) {
560
				log_error(sprintf(gettext("Error: Invalid certificate info for %s"), $ca['descr']));
561
				continue;
562
			}
563
			$cert = base64_decode($ca['crt']);
564
			$x509cert = openssl_x509_parse(openssl_x509_read($cert));
565
			if (!is_array($x509cert) || !isset($x509cert['hash'])) {
566
				log_error(sprintf(gettext("Error: Invalid certificate hash info for %s"), $ca['descr']));
567
				continue;
568
			}
569
			$fname = "{$capath}/{$x509cert['hash']}.0.crt";
570
			if (!@file_put_contents($fname, $cert)) {
571
				log_error(sprintf(gettext("Error: Cannot write IPsec CA file for %s"), $ca['descr']));
572
				continue;
573
			}
574
			unset($cert);
575
		}
576
	}
577

    
578
	$pskconf = "";
579

    
580
	if (is_array($a_phase1) && count($a_phase1)) {
581
		foreach ($a_phase1 as $ph1ent) {
582

    
583
			if (isset($ph1ent['disabled'])) {
584
				continue;
585
			}
586

    
587
			if (strstr($ph1ent['authentication_method'], 'rsa') ||
588
			    in_array($ph1ent['authentication_method'], array('eap-mschapv2', 'eap-tls', 'eap-radius'))) {
589
				$certline = '';
590

    
591
				$ikeid = $ph1ent['ikeid'];
592
				$cert = lookup_cert($ph1ent['certref']);
593

    
594
				if (!$cert) {
595
					log_error(sprintf(gettext("Error: Invalid phase1 certificate reference for %s"), $ph1ent['name']));
596
					continue;
597
				}
598

    
599
				@chmod($certpath, 0600);
600

    
601
				$ph1keyfile = "{$keypath}/cert-{$ikeid}.key";
602
				if (!file_put_contents($ph1keyfile, base64_decode($cert['prv']))) {
603
					log_error(sprintf(gettext("Error: Cannot write phase1 key file for %s"), $ph1ent['name']));
604
					continue;
605
				}
606
				@chmod($ph1keyfile, 0600);
607

    
608
				$ph1certfile = "{$certpath}/cert-{$ikeid}.crt";
609
				if (!file_put_contents($ph1certfile, base64_decode($cert['crt']))) {
610
					log_error(sprintf(gettext("Error: Cannot write phase1 certificate file for %s"), $ph1ent['name']));
611
					@unlink($ph1keyfile);
612
					continue;
613
				}
614
				@chmod($ph1certfile, 0600);
615

    
616
				/* XXX" Traffic selectors? */
617
				$pskconf .= " : RSA {$ph1keyfile}\n";
618
			} else {
619
				list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, 'local');
620
				list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, 'peer', $rgmap);
621

    
622
				if (empty($peerid_data)) {
623
					continue;
624
				}
625

    
626
				$myid = isset($ph1ent['mobile']) ? trim($myid_data) : "%any";
627
				$peerid = ($peerid_data != 'allusers') ? trim($peerid_data) : '';
628
				if (!empty($ph1ent['pre-shared-key'])) {
629
					if ($myid_type == 'fqdn' && !empty($myid_data)) {
630
						$pskconf .= "@{$myid} {$peerid} : PSK 0s" . base64_encode(trim($ph1ent['pre-shared-key'])) . "\n";
631
					} else {
632
						$pskconf .= "{$myid} {$peerid} : PSK 0s" . base64_encode(trim($ph1ent['pre-shared-key'])) . "\n";
633
					}
634
				}
635
			}
636
		}
637
	}
638

    
639
	/* Add user PSKs */
640
	if (is_array($config['system']) && is_array($config['system']['user'])) {
641
		foreach ($config['system']['user'] as $user) {
642
			if (!empty($user['ipsecpsk'])) {
643
				$pskconf .= "%any {$user['name']} : PSK 0s" . base64_encode($user['ipsecpsk']) . "\n";
644
			}
645
		}
646
		unset($user);
647
	}
648

    
649
	/* add PSKs for mobile clients */
650
	if (is_array($ipseccfg['mobilekey'])) {
651
		foreach ($ipseccfg['mobilekey'] as $key) {
652
			if ($key['ident'] == "allusers") {
653
				$key['ident'] = '%any';
654
			}
655
			if (empty($key['type'])) {
656
				$key['type'] = 'PSK';
657
			}
658
			$pskconf .= "%any {$key['ident']} : {$key['type']} 0s" . base64_encode($key['pre-shared-key']) . "\n";
659
		}
660
		unset($key);
661
	}
662

    
663
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.secrets", $pskconf);
664
	chmod("{$g['varetc_path']}/ipsec/ipsec.secrets", 0600);
665
	unset($pskconf);
666

    
667
	$uniqueids = 'yes';
668
	if (!empty($config['ipsec']['uniqueids'])) {
669
		if (array_key_exists($config['ipsec']['uniqueids'], $ipsec_idhandling))
670
			$uniqueids = $config['ipsec']['uniqueids'];
671
	}
672
	$natfilterrules = false;
673
	/* begin ipsec.conf */
674
	$ipsecconf = "";
675
	$enablecompression = false;
676
	if (is_array($a_phase1) && count($a_phase1))  {
677

    
678
		$ipsecconf .= "# This file is automatically generated. Do not edit\n";
679
		$ipsecconf .= "config setup\n\tuniqueids = {$uniqueids}\n";
680
		$ipsecconf .= "\tcharondebug=\"" . vpn_ipsec_configure_loglevels(true) . "\"\n";
681

    
682
		if (!isset($config['ipsec']['noshuntlaninterfaces'])) {
683
			if ($config['interfaces']['lan']) {
684
				$lanip = get_interface_ip("lan");
685
				if (!empty($lanip) && is_ipaddrv4($lanip)) {
686
					$lansn = get_interface_subnet("lan");
687
					$lansa = gen_subnet($lanip, $lansn);
688
					$ipsecconf .= <<<EOD
689

    
690
conn bypasslan
691
	leftsubnet = {$lanip}/32
692
	rightsubnet = {$lansa}/{$lansn}
693
	authby = never
694
	type = passthrough
695
	auto = route
696

    
697
EOD;
698
				}
699
			}
700
		}
701

    
702
		foreach ($a_phase1 as $ph1ent) {
703
			if (isset($ph1ent['disabled'])) {
704
				continue;
705
			}
706

    
707
			if ($ph1ent['mode'] == "aggressive") {
708
				$aggressive = "yes";
709
			} else {
710
				$aggressive = "no";
711
			}
712

    
713
			$ep = ipsec_get_phase1_src($ph1ent);
714
			if (!$ep) {
715
				continue;
716
			}
717

    
718
			$ikeid = $ph1ent['ikeid'];
719
			$keyexchange = "ikev1";
720
			$passive = "route";
721
			if (!empty($ph1ent['iketype'])) {
722
				if ($ph1ent['iketype'] == "ikev2") {
723
					$keyexchange = "ikev2";
724
					//$passive = "start";
725
				} else if ($ph1ent['iketype'] == "auto") {
726
					$keyexchange = "ike";
727
				}
728
			}
729

    
730
			if (isset($ph1ent['mobile'])) {
731
				$right_spec = "%any";
732
				$passive = 'add';
733
			} else {
734
				if (isset($ph1ent['responderonly'])) {
735
					$passive = 'add';
736
				}
737

    
738
				$right_spec = $ph1ent['remote-gateway'];
739
				if (is_ipaddr($right_spec)) {
740
					$sourcehost = $right_spec;
741
				} else {
742
					$sourcehost = $rgmap['remote-gateway'];
743
				}
744

    
745
				if ($ph1ent['protocol'] == 'inet') {
746
					if (strpos($ph1ent['interface'], '_vip')) {
747
						$vpninterface = explode('_vip', $ph1ent['interface']);
748
						$ifacesuse = get_real_interface($vpninterface[0]);
749
						$vpninterface = $vpninterface[0];
750
					} else {
751
						$ifacesuse = get_failover_interface($ph1ent['interface']);
752
						if (strpos($ifacesuse, '_vip')) {
753
							$vpninterface = explode('_vip', $ifacesuse);
754
							$ifacesuse = get_real_interface($vpninterface[0]);
755
							$vpninterface = $vpninterface[0];
756
						} else {
757
							$vpninterface = convert_real_interface_to_friendly_interface_name($ifacesuse);
758
						}
759
					}
760

    
761
					if (!empty($ifacesuse) && interface_has_gateway($vpninterface)) {
762
						$gatewayip = get_interface_gateway($vpninterface);
763
						$interfaceip = get_interface_ip($vpninterface);
764
						$subnet_bits = get_interface_subnet($vpninterface);
765
						$subnet_ip = gen_subnetv4($interfaceip, $subnet_bits);
766
						/* if the remote gateway is in the local subnet, then don't add a route */
767
						if (!ip_in_subnet($sourcehost, "{$subnet_ip}/{$subnet_bits}")) {
768
							if (is_ipaddrv4($gatewayip)) {
769
								// log_error("IPSEC interface is not WAN but {$ifacesuse}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
770
								mwexec("/sbin/route change -host {$sourcehost} {$gatewayip}", true);
771
							}
772
						}
773
					}
774
				} else if ($ph1ent['protocol'] == 'inet6') {
775
					if (strpos($ph1ent['interface'], '_vip')) {
776
						$vpninterface = explode('_vip', $ph1ent['interface']);
777
						$ifacesuse = get_real_interface($vpninterface[0]);
778
						$vpninterface = $vpninterface[0];
779
					} else {
780
						$ifacesuse = get_failover_interface($ph1ent['interface']);
781
						if (strpos($ifacesuse, '_vip')) {
782
							$vpninterface = explode('_vip', $ifacesuse);
783
							$ifacesuse = get_real_interface($vpninterface[0]);
784
							$vpninterface = $vpninterface[0];
785
						} else {
786
							$vpninterface = convert_real_interface_to_friendly_interface_name($ifacesuse);
787
						}
788
					}
789

    
790
					if (!empty($ifacesuse) && interface_has_gateway($vpninterface)) {
791
						$gatewayip = get_interface_gateway_v6($vpninterface);
792
						$interfaceip = get_interface_ipv6($vpninterface);
793
						$subnet_bits = get_interface_subnetv6($vpninterface);
794
						$subnet_ip = gen_subnetv6($interfaceip, $subnet_bits);
795
						/* if the remote gateway is in the local subnet, then don't add a route */
796
						if (!ip_in_subnet($sourcehost, "{$subnet_ip}/{$subnet_bits}")) {
797
							if (is_ipaddrv6($gatewayip)) {
798
								// log_error("IPSEC interface is not WAN but {$ifacesuse}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
799
								mwexec("/sbin/route change -inet6 -host {$sourcehost} {$gatewayip}", true);
800
							}
801
						}
802
					}
803
				}
804
			}
805

    
806
			list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, 'local');
807
			if ($myid_type != 'address') {
808
				$myid_data = "{$myid_type}:{$myid_data}";
809
			}
810

    
811
			/* Only specify peer ID if we are not dealing with a mobile PSK-only tunnel */
812
			$peerid_spec = '';
813
			if (!isset($ph1ent['mobile'])) {
814
				list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, 'peer', $rgmap);
815
				if ($peerid_type != 'address') {
816
					$peerid_spec = "{$peerid_type}:{$peerid_data}";
817
				} else {
818
					$peerid_spec = $peerid_data;
819
				}
820
			}
821

    
822
			if (is_array($ph1ent['encryption-algorithm']) && !empty($ph1ent['encryption-algorithm']['name']) && !empty($ph1ent['hash-algorithm'])) {
823
				$ealgosp1 = '';
824
				$ealg_id = $ph1ent['encryption-algorithm']['name'];
825
				$ealg_kl = $ph1ent['encryption-algorithm']['keylen'];
826
				if ($ealg_kl) {
827
					$ealgosp1 = "ike = {$ealg_id}{$ealg_kl}-{$ph1ent['hash-algorithm']}";
828
				} else {
829
					$ealgosp1 = "ike = {$ealg_id}-{$ph1ent['hash-algorithm']}";
830
				}
831

    
832
				$modp = vpn_ipsec_convert_to_modp($ph1ent['dhgroup']);
833
				if (!empty($modp)) {
834
					$ealgosp1 .= "-{$modp}";
835
				}
836

    
837
				$ealgosp1 .= "!";
838
			}
839

    
840
			if ($ph1ent['dpd_delay'] && $ph1ent['dpd_maxfail']) {
841
				if ($passive == "route") {
842
					$dpdline = "dpdaction = restart";
843
				} else {
844
					$dpdline = "dpdaction = clear";
845
				}
846
				$dpdline .= "\n\tdpddelay = {$ph1ent['dpd_delay']}s";
847
				$dpdtimeout = $ph1ent['dpd_delay'] * ($ph1ent['dpd_maxfail'] + 1);
848
				$dpdline .= "\n\tdpdtimeout = {$dpdtimeout}s";
849
			} else {
850
				$dpdline = "dpdaction = none";
851
			}
852

    
853
			$ikelifeline = '';
854
			if ($ph1ent['lifetime']) {
855
				$ikelifeline = "ikelifetime = {$ph1ent['lifetime']}s";
856
			}
857

    
858
			$rightsourceip = NULL;
859
			if (isset($ph1ent['mobile']) && !empty($a_client['pool_address'])) {
860
				$rightsourceip = "\trightsourceip = {$a_client['pool_address']}/{$a_client['pool_netbits']}\n";
861
			}
862

    
863
			$authentication = "";
864
			switch ($ph1ent['authentication_method']) {
865
				case 'eap-mschapv2':
866
					if (isset($ph1ent['mobile'])) {
867
						$authentication = "eap_identity=%any\n\t";
868
						$authentication .= "leftauth=pubkey\n\trightauth=eap-mschapv2";
869
						if (!empty($ph1ent['certref'])) {
870
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
871
						}
872
					}
873
					break;
874
				case 'eap-tls':
875
					if (isset($ph1ent['mobile'])) {
876
						$authentication = "eap_identity=%identity\n\t";
877
						$authentication .= "leftauth=pubkey\n\trightauth=eap-tls";
878
						if (!empty($ph1ent['certref'])) {
879
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
880
						}
881
					} else {
882
						$authentication = "leftauth=eap-tls\n\trightauth=eap-tls";
883
						if (!empty($ph1ent['certref'])) {
884
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
885
						}
886
					}
887
					break;
888
				case 'eap-radius':
889
					if (isset($ph1ent['mobile'])) {
890
						$authentication = "eap_identity=%identity\n\t";
891
						$authentication .= "leftauth=pubkey\n\trightauth=eap-radius";
892
						if (!empty($ph1ent['certref']))
893
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
894
					} else {
895
						$authentication = "leftauth=eap-radius\n\trightauth=eap-radius";
896
						if (!empty($ph1ent['certref'])) {
897
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
898
						}
899
					}
900
					break;
901
				case 'xauth_rsa_server':
902
					$authentication = "leftauth = pubkey\n\trightauth = pubkey";
903
					$authentication .= "\n\trightauth2 = xauth-generic";
904
					if (!empty($ph1ent['certref'])) {
905
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
906
					}
907
					break;
908
				case 'xauth_psk_server':
909
					$authentication = "leftauth = psk\n\trightauth = psk";
910
					$authentication .= "\n\trightauth2 = xauth-generic";
911
					break;
912
				case 'pre_shared_key':
913
					$authentication = "leftauth = psk\n\trightauth = psk";
914
					break;
915
				case 'rsasig':
916
					$authentication = "leftauth = pubkey\n\trightauth = pubkey";
917
					if (!empty($ph1ent['certref'])) {
918
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
919
					}
920
					break;
921
				case 'hybrid_rsa_server':
922
					$authentication = "leftauth = xauth-generic\n\trightauth = pubkey";
923
					$authentication .= "\n\trightauth2 = xauth";
924
					if (!empty($ph1ent['certref'])) {
925
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
926
					}
927
					break;
928
			}
929

    
930
			$left_spec = $ep;
931

    
932
			if (isset($ph1ent['reauth_enable'])) {
933
				$reauth = "reauth = no";
934
			} else {
935
				$reauth = "reauth = yes";
936
			}
937
			if (isset($ph1ent['rekey_enable'])) {
938
				$rekey = "rekey = no";
939
			} else {
940
				$rekey = "rekey = yes";
941
			}
942

    
943
			if ($ph1ent['nat_traversal'] == 'off') {
944
				$forceencaps = 'forceencaps = no';
945
			} else if ($ph1ent['nat_traversal'] == 'force') {
946
				$forceencaps = 'forceencaps = yes';
947
			} else {
948
				$forceencaps = 'forceencaps = no';
949
			}
950

    
951
			if ($ph1ent['mobike'] == 'on') {
952
				$mobike = 'mobike = yes';
953
			} else {
954
				$mobike = 'mobike = no';
955
			}
956

    
957
			$ipseclifetime = 0;
958
			$rightsubnet_spec = array();
959
			$leftsubnet_spec = array();
960
			$reqids = array();
961
			$ealgoAHsp2arr = array();
962
			$ealgoESPsp2arr = array();
963
		if (is_array($a_phase2) && count($a_phase2)) {
964
			foreach ($a_phase2 as $ph2ent) {
965
				if ($ikeid != $ph2ent['ikeid']) {
966
					continue;
967
				}
968

    
969
				if (isset($ph2ent['disabled'])) {
970
					continue;
971
				}
972

    
973
				if (isset($ph2ent['mobile']) && !isset($a_client['enable'])) {
974
					continue;
975
				}
976

    
977
				if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
978
					$tunneltype = "type = tunnel";
979

    
980
					$localid_type = $ph2ent['localid']['type'];
981
					$leftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['localid'], false, $ph2ent['mode']);
982

    
983
					/* Do not print localid in some cases, such as a pure-psk or psk/xauth single phase2 mobile tunnel */
984
					if (($localid_type == "none" || $localid_type == "mobile") &&
985
					    isset($ph1ent['mobile']) && (ipsec_get_number_of_phase2($ikeid)==1)) {
986
						$left_spec = '%any';
987
					} else {
988
						if ($localid_type != "address") {
989
							$localid_type = "subnet";
990
						}
991
						// Don't let an empty subnet into config, it can cause parse errors. Ticket #2201.
992
						if (!is_ipaddr($leftsubnet_data) && !is_subnet($leftsubnet_data) && ($leftsubnet_data != "0.0.0.0/0")) {
993
							log_error("Invalid IPsec Phase 2 \"{$ph2ent['descr']}\" - {$ph2ent['localid']['type']} has no subnet.");
994
							continue;
995
						}
996
						if (!empty($ph2ent['natlocalid'])) {
997
							$natleftsubnet_data =  ipsec_idinfo_to_cidr($ph2ent['natlocalid'], false, $ph2ent['mode']);
998
							if ($ph2ent['natlocalid']['type'] != "address") {
999
								if (is_subnet($natleftsubnet_data)) {
1000
									$leftsubnet_data = "{$natleftsubnet_data}|{$leftsubnet_data}";
1001
								}
1002
							} else {
1003
								if (is_ipaddr($natleftsubnet_data)) {
1004
									$leftsubnet_data = "{$natleftsubnet_data}|{$leftsubnet_data}";
1005
								}
1006
							}
1007
							$natfilterrules = true;
1008
						}
1009
					}
1010

    
1011
					$leftsubnet_spec[] = $leftsubnet_data;
1012

    
1013
					if (!isset($ph2ent['mobile'])) {
1014
						$tmpsubnet = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']);
1015
						$rightsubnet_spec[] = $tmpsubnet;
1016
					} else if (!empty($a_client['pool_address'])) {
1017
						$rightsubnet_spec[] = "{$a_client['pool_address']}/{$a_client['pool_netbits']}";
1018
					}
1019
				} else {
1020
					$tunneltype = "type = transport";
1021

    
1022
					if ((($ph1ent['authentication_method'] == "xauth_psk_server") ||
1023
					    ($ph1ent['authentication_method'] == "pre_shared_key")) && isset($ph1ent['mobile'])) {
1024
						$left_spec = "%any";
1025
					} else {
1026
						$tmpsubnet = ipsec_get_phase1_src($ph1ent);
1027
						$leftsubnet_spec[] = $tmpsubnet;
1028
					}
1029

    
1030
					if (!isset($ph2ent['mobile'])) {
1031
						$rightsubnet_spec[] = $right_spec;
1032
					}
1033
				}
1034

    
1035
				if (isset($a_client['pfs_group']) && isset($ph2ent['mobile'])) {
1036
					$ph2ent['pfsgroup'] = $a_client['pfs_group'];
1037
				}
1038

    
1039
				if ($ph2ent['protocol'] == 'esp') {
1040
					if (is_array($ph2ent['encryption-algorithm-option'])) {
1041
						foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
1042
							$ealg_id = $ealg['name'];
1043
							$ealg_kl = $ealg['keylen'];
1044

    
1045
							if (!empty($ealg_kl) && $ealg_kl == "auto") {
1046
								if (empty($p2_ealgos) || !is_array($p2_ealgos)) {
1047
									require("ipsec.inc");
1048
								}
1049
								$key_hi = $p2_ealgos[$ealg_id]['keysel']['hi'];
1050
								$key_lo = $p2_ealgos[$ealg_id]['keysel']['lo'];
1051
								$key_step = $p2_ealgos[$ealg_id]['keysel']['step'];
1052
								/* XXX: in some cases where include ordering is suspect these variables
1053
								 * are somehow 0 and we enter this loop forever and timeout after 900
1054
								 * seconds wrecking bootup */
1055
								if ($key_hi != 0 and $key_lo !=0 and $key_step !=0) {
1056
									for ($keylen = $key_hi; $keylen >= $key_lo; $keylen -= $key_step) {
1057
										if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
1058
											foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
1059
												$halgo = str_replace('hmac_', '', $halgo);
1060
												$tmpealgo = "{$ealg_id}{$keylen}-{$halgo}";
1061
												$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1062
												if (!empty($modp)) {
1063
													$tmpealgo .= "-{$modp}";
1064
												}
1065
												$ealgoESPsp2arr[] = $tmpealgo;
1066
											}
1067
										} else {
1068
											$tmpealgo = "{$ealg_id}{$keylen}";
1069
											$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1070
											if (!empty($modp)) {
1071
												$tmpealgo .= "-{$modp}";
1072
											}
1073
											$ealgoESPsp2arr[] = $tmpealgo;
1074
										}
1075
									}
1076
								}
1077
							} else {
1078
								if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
1079
									foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
1080
										$halgo = str_replace('hmac_', '', $halgo);
1081
										$tmpealgo = "{$ealg_id}{$ealg_kl}-{$halgo}";
1082
										$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1083
										if (!empty($modp)) {
1084
											$tmpealgo .= "-{$modp}";
1085
										}
1086
										$ealgoESPsp2arr[] = $tmpealgo;
1087
									}
1088
								} else {
1089
									$tmpealgo = "{$ealg_id}{$ealg_kl}";
1090
									$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1091
									if (!empty($modp)) {
1092
										$tmpealgo .= "-{$modp}";
1093
									}
1094
									$ealgoESPsp2arr[] = $tmpealgo;
1095
								}
1096
							}
1097
						}
1098
					}
1099
				} else if ($ph2ent['protocol'] == 'ah') {
1100
					if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
1101
						$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1102
						foreach ($ph2ent['hash-algorithm-option'] as $tmpAHalgo) {
1103
							$tmpAHalgo = str_replace('hmac_', '', $tmpAHalgo);
1104
							if (!empty($modp)) {
1105
								$tmpAHalgo = "-{$modp}";
1106
							}
1107
							$ealgoAHsp2arr[] = $tmpAHalgo;
1108
						}
1109
					}
1110
				}
1111

    
1112
				$reqids[] = $ph2ent['reqid'];
1113

    
1114
				if (!empty($ph2ent['lifetime'])) {
1115
					if ($ipseclifetime == 0 || intval($ipseclifetime) > intval($ph2ent['lifetime'])) {
1116
						$ipseclifetime = intval($ph2ent['lifetime']);
1117
					}
1118
				}
1119

    
1120
			}
1121
		}
1122

    
1123
			$ipsecconnect =<<<EOD
1124
	fragmentation = yes
1125
	keyexchange = {$keyexchange}
1126
	{$reauth}
1127
	{$forceencaps}
1128
	{$mobike}
1129
	{$rekey}
1130
	installpolicy = yes
1131
	{$tunneltype}
1132
	{$dpdline}
1133
	auto = {$passive}
1134
	left = {$left_spec}
1135
	right = {$right_spec}
1136
	leftid = {$myid_data}
1137

    
1138
EOD;
1139

    
1140
			if (isset($config['ipsec']['compression'])) {
1141
				$ipsecconnect .= "\tcompress = yes\n";
1142
				$enablecompression = true;
1143
			}
1144
			if (!empty($ikelifeline)) {
1145
				$ipsecconnect .= "\t{$ikelifeline}\n";
1146
			}
1147
			if ($ipseclifetime > 0) {
1148
				$ipsecconnect .= "\tlifetime = {$ipseclifetime}s\n";
1149
			}
1150
			if (!empty($rightsourceip)) {
1151
				$ipsecconnect .= "{$rightsourceip}";
1152
			}
1153
			if (!empty($ealgosp1)) {
1154
				$ipsecconnect .= "\t{$ealgosp1}\n";
1155
			}
1156
			if (!empty($ealgoAHsp2arr)) {
1157
				$ipsecconnect .= "\tah = " . join(',', $ealgoAHsp2arr) . "!\n";
1158
			}
1159
			if (!empty($ealgoESPsp2arr)) {
1160
				$ipsecconnect .= "\tesp = " . join(',', $ealgoESPsp2arr) . "!\n";
1161
			}
1162
			if (!empty($authentication)) {
1163
				$ipsecconnect .= "\t{$authentication}\n";
1164
			}
1165
			if (!empty($peerid_spec)) {
1166
				$ipsecconnect .= "\trightid = {$peerid_spec}\n";
1167
			}
1168
			if ($keyexchange == 'ikev1') {
1169
				$ipsecconnect .= "\taggressive = {$aggressive}\n";
1170
			}
1171

    
1172
			if (!isset($ph1ent['mobile']) && $keyexchange == 'ikev1') {
1173
				if (!empty($rightsubnet_spec)) {
1174
					$ipsecfin = '';
1175
					foreach ($rightsubnet_spec as $idx => $rsubnet) {
1176
						$ipsecfin .= "\nconn con{$ph1ent['ikeid']}00{$idx}\n";
1177
						if (!empty($reqids[$idx])) {
1178
							$ipsecfin .= "\treqid = " . $reqids[$idx] . "\n";
1179
						}
1180
						$ipsecfin .= $ipsecconnect;
1181
						$ipsecfin .= "\trightsubnet = {$rsubnet}\n";
1182
						$ipsecfin .= "\tleftsubnet = " . $leftsubnet_spec[$idx] . "\n";
1183
					}
1184
				} else {
1185
					log_error("No phase2 specifications for tunnel with REQID = {$ikeid}");
1186
				}
1187
			} else {
1188
				$ipsecfin = "\nconn con{$ph1ent['ikeid']}\n";
1189
				if (!empty($reqids[$idx])) {
1190
					$ipsecfin .= "\treqid = " . $reqids[0] . "\n";
1191
				}
1192
				$ipsecfin .= $ipsecconnect;
1193
				if (!isset($ph1ent['mobile']) && !empty($rightsubnet_spec)) {
1194
					$tempsubnets = array();
1195
					foreach ($rightsubnet_spec as $rightsubnet) {
1196
						$tempsubnets[$rightsubnet] = $rightsubnet;
1197
					}
1198
					$ipsecfin .= "\trightsubnet = " . join(",", $tempsubnets) . "\n";
1199
					unset($tempsubnets, $rightsubnet);
1200
				}
1201
				if (!empty($leftsubnet_spec)) {
1202
					$tempsubnets = array();
1203
					foreach ($leftsubnet_spec as $leftsubnet) {
1204
						$tempsubnets[$leftsubnet] = $leftsubnet;
1205
					}
1206
					$ipsecfin .= "\tleftsubnet = " . join(",", $tempsubnets) . "\n";
1207
					unset($tempsubnets, $leftsubnet);
1208
				}
1209
			}
1210
			$ipsecconf .= $ipsecfin;
1211
			unset($ipsecfin);
1212
		}
1213
	}
1214

    
1215
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.conf", $ipsecconf);
1216
	unset($ipsecconf);
1217
	/* end ipsec.conf */
1218

    
1219
	if ($enablecompression === true) {
1220
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 1);
1221
	} else {
1222
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 0);
1223
	}
1224

    
1225
	/* manage process */
1226
	if ($restart === true) {
1227
		mwexec("/usr/local/sbin/ipsec restart", false);
1228
	} else {
1229
		if (isvalidpid("{$g['varrun_path']}/charon.pid")) {
1230
			/* Read secrets */
1231
			mwexec("/usr/local/sbin/ipsec rereadall", false);
1232
			/* Update configuration changes */
1233
			mwexec("/usr/local/sbin/ipsec update", false);
1234
		} else {
1235
			mwexec("/usr/local/sbin/ipsec start", false);
1236
		}
1237
	}
1238

    
1239
	if ($natfilterrules == true) {
1240
		filter_configure();
1241
	}
1242
	/* start filterdns, if necessary */
1243
	if (count($filterdns_list) > 0) {
1244
		$interval = 60;
1245
		if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval'])) {
1246
			$interval = $ipseccfg['dns-interval'];
1247
		}
1248

    
1249
		$hostnames = "";
1250
		array_unique($filterdns_list);
1251
		foreach ($filterdns_list as $hostname) {
1252
			$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload ipsecdns\"'\n";
1253
		}
1254
		file_put_contents("{$g['varetc_path']}/ipsec/filterdns-ipsec.hosts", $hostnames);
1255
		unset($hostnames);
1256

    
1257
		if (isvalidpid("{$g['varrun_path']}/filterdns-ipsec.pid")) {
1258
			sigkillbypid("{$g['varrun_path']}/filterdns-ipsec.pid", "HUP");
1259
		} else {
1260
			mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/ipsec/filterdns-ipsec.hosts -d 1");
1261
		}
1262
	} else {
1263
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
1264
		@unlink("{$g['varrun_path']}/filterdns-ipsec.pid");
1265
	}
1266

    
1267
	if (platform_booting()) {
1268
		echo "done\n";
1269
	}
1270

    
1271
	return count($filterdns_list);
1272
}
1273

    
1274
/*
1275
 * Forcefully restart IPsec
1276
 * This is required for when dynamic interfaces reload
1277
 * For all other occasions the normal vpn_ipsec_configure()
1278
 * will gracefully reload the settings without restarting
1279
 */
1280
function vpn_ipsec_force_reload($interface = "") {
1281
	global $g, $config;
1282

    
1283
	$ipseccfg = $config['ipsec'];
1284

    
1285
	if (!empty($interface) && is_array($ipseccfg['phase1'])) {
1286
		$found = false;
1287
		foreach ($ipseccfg['phase1'] as $ipsec) {
1288
			if (!isset($ipsec['disabled']) && ($ipsec['interface'] == $interface)) {
1289
				$found = true;
1290
				break;
1291
			}
1292
		}
1293
		if (!$found) {
1294
			log_error(sprintf(gettext("Ignoring IPsec reload since there are no tunnels on interface %s"), $interface));
1295
			return;
1296
		}
1297
	}
1298

    
1299
	/* if ipsec is enabled, start up again */
1300
	if (isset($ipseccfg['enable'])) {
1301
		log_error(gettext("Forcefully reloading IPsec"));
1302
		vpn_ipsec_configure();
1303
	}
1304
}
1305

    
1306
/* master setup for vpn (mpd) */
1307
function vpn_setup() {
1308
	global $g;
1309

    
1310
	if ($g['platform'] == 'jail') {
1311
		return;
1312
	}
1313

    
1314
	/* start pptpd */
1315
	vpn_pptpd_configure();
1316

    
1317
	/* start pppoe server */
1318
	vpn_pppoes_configure();
1319

    
1320
	/* setup l2tp */
1321
	vpn_l2tp_configure();
1322
}
1323

    
1324
function vpn_netgraph_support() {
1325
	$iflist = get_configured_interface_list();
1326
	foreach ($iflist as $iface) {
1327
		$realif = get_real_interface($iface);
1328
		/* Get support for netgraph(4) from the nic */
1329
		$ifinfo = pfSense_get_interface_addresses($realif);
1330
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge"))) {
1331
			pfSense_ngctl_attach(".", $realif);
1332
		}
1333
	}
1334
}
1335

    
1336
function vpn_pptpd_configure() {
1337
	global $config, $g;
1338

    
1339
	$syscfg = $config['system'];
1340
	$pptpdcfg = $config['pptpd'];
1341

    
1342
	if (platform_booting()) {
1343
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off")) {
1344
			return 0;
1345
		}
1346

    
1347
		if (platform_booting(true)) {
1348
			echo gettext("Configuring PPTP VPN service... ");
1349
		}
1350
	} else {
1351
		/* kill mpd */
1352
		killbypid("{$g['varrun_path']}/pptp-vpn.pid");
1353

    
1354
		/* wait for process to die */
1355
		sleep(3);
1356

    
1357
		if (is_process_running("mpd -b")) {
1358
			killbypid("{$g['varrun_path']}/pptp-vpn.pid");
1359
			log_error(gettext("Could not kill mpd within 3 seconds.   Trying again."));
1360
		}
1361

    
1362
		/* remove mpd.conf, if it exists */
1363
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.conf");
1364
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.links");
1365
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.secret");
1366
	}
1367

    
1368
	if (empty($pptpdcfg['n_pptp_units'])) {
1369
		log_error("Something wrong in the PPTPd configuration. Preventing starting the daemon because issues would arise.");
1370
		return;
1371
	}
1372

    
1373
	/* make sure pptp-vpn directory exists */
1374
	if (!file_exists("{$g['varetc_path']}/pptp-vpn")) {
1375
		mkdir("{$g['varetc_path']}/pptp-vpn");
1376
	}
1377

    
1378
	switch ($pptpdcfg['mode']) {
1379
		case 'server':
1380
			/* write mpd.conf */
1381
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.conf", "w");
1382
			if (!$fd) {
1383
				printf(gettext("Error: cannot open mpd.conf in vpn_pptpd_configure().") . "\n");
1384
				return 1;
1385
			}
1386

    
1387
			$mpdconf = <<<EOD
1388
pptps:
1389

    
1390
EOD;
1391

    
1392
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1393
				$mpdconf .= "	load pt{$i}\n";
1394
			}
1395

    
1396
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1397

    
1398
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
1399

    
1400
				$mpdconf .= <<<EOD
1401

    
1402
pt{$i}:
1403
	new -i pptpd{$i} pt{$i} pt{$i}
1404
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
1405
	load pts
1406

    
1407
EOD;
1408
			}
1409

    
1410
			$mpdconf .=<<<EOD
1411

    
1412
pts:
1413
	set iface disable on-demand
1414
	set iface enable proxy-arp
1415
	set iface enable tcpmssfix
1416
	set iface idle 1800
1417
	set iface up-script /usr/local/sbin/vpn-linkup
1418
	set iface down-script /usr/local/sbin/vpn-linkdown
1419
	set bundle enable multilink
1420
	set bundle enable crypt-reqd
1421
	set link yes acfcomp protocomp
1422
	set link no pap chap
1423
	set link enable chap-msv2
1424
	set link mtu 1460
1425
	set link keep-alive 10 60
1426
	set ipcp yes vjcomp
1427
	set bundle enable compression
1428
	set ccp yes mppc
1429
	set ccp yes mpp-e128
1430
	set ccp yes mpp-stateless
1431

    
1432
EOD;
1433

    
1434
			if (!isset ($pptpdcfg['req128'])) {
1435
				$mpdconf .=<<<EOD
1436
	set ccp yes mpp-e40
1437
	set ccp yes mpp-e56
1438

    
1439
EOD;
1440
			}
1441

    
1442
			if  (isset($pptpdcfg["wins"]) && $pptpdcfg['wins'] != "") {
1443
				$mpdconf  .=  "	set ipcp nbns {$pptpdcfg['wins']}\n";
1444
			}
1445

    
1446
			if (!empty($pptpdcfg['dns1'])) {
1447
				$mpdconf .= "	set ipcp dns " . $pptpdcfg['dns1'];
1448
				if (!empty($pptpdcfg['dns2'])) {
1449
					$mpdconf .= " " . $pptpdcfg['dns2'];
1450
				}
1451
				$mpdconf .= "\n";
1452
			} elseif (isset ($config['dnsmasq']['enable'])) {
1453
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1454
				if ($syscfg['dnsserver'][0]) {
1455
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1456
				}
1457
				$mpdconf .= "\n";
1458
			} elseif (isset($config['unbound']['enable'])) {
1459
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1460
				if ($syscfg['dnsserver'][0]) {
1461
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1462
				}
1463
				$mpdconf .= "\n";
1464
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1465
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1466
			}
1467

    
1468
			if (isset ($pptpdcfg['radius']['server']['enable'])) {
1469
				$authport = (isset($pptpdcfg['radius']['server']['port']) && strlen($pptpdcfg['radius']['server']['port']) > 1) ? $pptpdcfg['radius']['server']['port'] : 1812;
1470
				$acctport = $authport + 1;
1471
				$mpdconf .=<<<EOD
1472
	set radius server {$pptpdcfg['radius']['server']['ip']} "{$pptpdcfg['radius']['server']['secret']}" {$authport} {$acctport}
1473

    
1474
EOD;
1475
				if (isset ($pptpdcfg['radius']['server2']['enable'])) {
1476
					$authport = (isset($pptpdcfg['radius']['server2']['port']) && strlen($pptpdcfg['radius']['server2']['port']) > 1) ? $pptpdcfg['radius']['server2']['port'] : 1812;
1477
					$acctport = $authport + 1;
1478
					$mpdconf .=<<<EOD
1479
	set radius server {$pptpdcfg['radius']['server2']['ip']} "{$pptpdcfg['radius']['server2']['secret2']}" {$authport} {$acctport}
1480

    
1481
EOD;
1482
				}
1483
				$mpdconf .=<<<EOD
1484
	set radius retries 3
1485
	set radius timeout 10
1486
	set auth enable radius-auth
1487

    
1488
EOD;
1489

    
1490
				if (isset ($pptpdcfg['radius']['accounting'])) {
1491
					$mpdconf .=<<<EOD
1492
	set auth enable radius-acct
1493
	set radius acct-update 300
1494

    
1495
EOD;
1496
				}
1497
			}
1498

    
1499
			fwrite($fd, $mpdconf);
1500
			fclose($fd);
1501
			unset($mpdconf);
1502

    
1503
			/* write mpd.links */
1504
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.links", "w");
1505
			if (!$fd) {
1506
				printf(gettext("Error: cannot open mpd.links in vpn_pptpd_configure().") . "\n");
1507
				return 1;
1508
			}
1509

    
1510
			$mpdlinks = "";
1511

    
1512
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1513
				$mpdlinks .=<<<EOD
1514

    
1515
pt{$i}:
1516
	set link type pptp
1517
	set pptp enable incoming
1518
	set pptp disable originate
1519
	set pptp disable windowing
1520

    
1521
EOD;
1522
			}
1523

    
1524
			fwrite($fd, $mpdlinks);
1525
			fclose($fd);
1526
			unset($mpdlinks);
1527

    
1528
			/* write mpd.secret */
1529
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.secret", "w");
1530
			if (!$fd) {
1531
				printf(gettext("Error: cannot open mpd.secret in vpn_pptpd_configure().") . "\n");
1532
				return 1;
1533
			}
1534

    
1535
			$mpdsecret = "";
1536

    
1537
			if (is_array($pptpdcfg['user'])) {
1538
				foreach ($pptpdcfg['user'] as $user) {
1539
					$pass = str_replace('\\', '\\\\', $user['password']);
1540
					$pass = str_replace('"', '\"', $pass);
1541
					$mpdsecret .= "{$user['name']} \"{$pass}\" {$user['ip']}\n";
1542
				}
1543
			}
1544

    
1545
			fwrite($fd, $mpdsecret);
1546
			fclose($fd);
1547
			unset($mpdsecret);
1548
			chmod("{$g['varetc_path']}/pptp-vpn/mpd.secret", 0600);
1549

    
1550
			vpn_netgraph_support();
1551

    
1552
			/* fire up mpd */
1553
			mwexec("/usr/local/sbin/mpd4 -b -d {$g['varetc_path']}/pptp-vpn -p {$g['varrun_path']}/pptp-vpn.pid -s pptps pptps");
1554

    
1555
			break;
1556

    
1557
		case 'redir':
1558
			break;
1559
	}
1560

    
1561
	if (platform_booting()) {
1562
		echo "done\n";
1563
	}
1564

    
1565
	return 0;
1566
}
1567

    
1568
function vpn_pppoes_configure() {
1569
	global $config;
1570

    
1571
	if (is_array($config['pppoes']['pppoe'])) {
1572
		foreach ($config['pppoes']['pppoe'] as $pppoe) {
1573
			vpn_pppoe_configure($pppoe);
1574
		}
1575
	}
1576
}
1577

    
1578
function vpn_pppoe_configure(&$pppoecfg) {
1579
	global $config, $g;
1580

    
1581
	$syscfg = $config['system'];
1582

    
1583
	/* create directory if it does not exist */
1584
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn")) {
1585
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1586
	}
1587

    
1588
	if (platform_booting()) {
1589
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off")) {
1590
			return 0;
1591
		}
1592

    
1593
		echo gettext("Configuring PPPoE Server service... ");
1594
	} else {
1595
		/* kill mpd */
1596
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1597

    
1598
		/* wait for process to die */
1599
		sleep(2);
1600

    
1601
	}
1602

    
1603
	switch ($pppoecfg['mode']) {
1604

    
1605
		case 'server':
1606

    
1607
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1608

    
1609
			if ($pppoecfg['paporchap'] == "chap") {
1610
				$paporchap = "set link enable chap";
1611
			} else {
1612
				$paporchap = "set link enable pap";
1613
			}
1614

    
1615
			/* write mpd.conf */
1616
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1617
			if (!$fd) {
1618
				printf(gettext("Error: cannot open mpd.conf in vpn_pppoe_configure().") . "\n");
1619
				return 1;
1620
			}
1621
			$mpdconf = "\n\n";
1622
			$mpdconf .= "poes:\n";
1623

    
1624
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1625
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1626
			}
1627

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

    
1630
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1631

    
1632
				if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1633
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1634
				} else {
1635
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1636
				}
1637

    
1638
				$mpdconf .=<<<EOD
1639

    
1640
poes{$pppoecfg['pppoeid']}{$i}:
1641
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1642
	{$isssue_ip_type}
1643
	load pppoe_standard
1644

    
1645
EOD;
1646
			}
1647

    
1648
			$mpdconf .=<<<EOD
1649

    
1650
pppoe_standard:
1651
	set bundle no multilink
1652
	set bundle enable compression
1653
	set auth max-logins 1
1654
	set iface up-script /usr/local/sbin/vpn-linkup
1655
	set iface down-script /usr/local/sbin/vpn-linkdown
1656
	set iface idle 0
1657
	set iface disable on-demand
1658
	set iface disable proxy-arp
1659
	set iface enable tcpmssfix
1660
	set iface mtu 1500
1661
	set link no pap chap
1662
	{$paporchap}
1663
	set link keep-alive 60 180
1664
	set ipcp yes vjcomp
1665
	set ipcp no vjcomp
1666
	set link max-redial -1
1667
	set link mtu 1492
1668
	set link mru 1492
1669
	set ccp yes mpp-e40
1670
	set ccp yes mpp-e128
1671
	set ccp yes mpp-stateless
1672
	set link latency 1
1673
	#set ipcp dns 10.10.1.3
1674
	#set bundle accept encryption
1675

    
1676
EOD;
1677

    
1678
			if (!empty($pppoecfg['dns1'])) {
1679
				$mpdconf .= "	set ipcp dns " . $pppoecfg['dns1'];
1680
				if (!empty($pppoecfg['dns2'])) {
1681
					$mpdconf .= " " . $pppoecfg['dns2'];
1682
				}
1683
				$mpdconf .= "\n";
1684
			} elseif (isset ($config['dnsmasq']['enable'])) {
1685
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1686
				if ($syscfg['dnsserver'][0]) {
1687
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1688
				}
1689
				$mpdconf .= "\n";
1690
			} elseif (isset ($config['unbound']['enable'])) {
1691
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1692
				if ($syscfg['dnsserver'][0]) {
1693
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1694
				}
1695
				$mpdconf .= "\n";
1696
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1697
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1698
			}
1699

    
1700
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1701
				$radiusport = "";
1702
				$radiusacctport = "";
1703
				if (isset($pppoecfg['radius']['server']['port'])) {
1704
					$radiusport = $pppoecfg['radius']['server']['port'];
1705
				}
1706
				if (isset($pppoecfg['radius']['server']['acctport'])) {
1707
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1708
				}
1709
				$mpdconf .=<<<EOD
1710
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
1711
	set radius retries 3
1712
	set radius timeout 10
1713
	set auth enable radius-auth
1714

    
1715
EOD;
1716

    
1717
				if (isset ($pppoecfg['radius']['accounting'])) {
1718
					$mpdconf .=<<<EOD
1719
	set auth enable radius-acct
1720

    
1721
EOD;
1722
				}
1723
			}
1724

    
1725
			fwrite($fd, $mpdconf);
1726
			fclose($fd);
1727
			unset($mpdconf);
1728

    
1729
			/* write mpd.links */
1730
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.links", "w");
1731
			if (!$fd) {
1732
				printf(gettext("Error: cannot open mpd.links in vpn_pppoe_configure().") . "\n");
1733
				return 1;
1734
			}
1735

    
1736
			$mpdlinks = "";
1737

    
1738
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1739
				$mpdlinks .=<<<EOD
1740

    
1741
poes{$pppoecfg['pppoeid']}{$i}:
1742
	set phys type pppoe
1743
	set pppoe iface {$pppoe_interface}
1744
	set pppoe service "*"
1745
	set pppoe disable originate
1746
	set pppoe enable incoming
1747

    
1748
EOD;
1749
			}
1750

    
1751
			fwrite($fd, $mpdlinks);
1752
			fclose($fd);
1753
			unset($mpdlinks);
1754

    
1755
			if ($pppoecfg['username']) {
1756
				/* write mpd.secret */
1757
				$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
1758
				if (!$fd) {
1759
					printf(gettext("Error: cannot open mpd.secret in vpn_pppoe_configure().") . "\n");
1760
					return 1;
1761
				}
1762

    
1763
				$mpdsecret = "\n\n";
1764

    
1765
				if (!empty($pppoecfg['username'])) {
1766
					$item = explode(" ", $pppoecfg['username']);
1767
					foreach ($item as $userdata) {
1768
						$data = explode(":", $userdata);
1769
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1770
					}
1771
				}
1772

    
1773
				fwrite($fd, $mpdsecret);
1774
				fclose($fd);
1775
				unset($mpdsecret);
1776
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1777
			}
1778

    
1779
			/* Check if previous instance is still up */
1780
			while (file_exists("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid") && isvalidpid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid")) {
1781
				killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1782
			}
1783

    
1784
			/* Get support for netgraph(4) from the nic */
1785
			pfSense_ngctl_attach(".", $pppoe_interface);
1786
			/* fire up mpd */
1787
			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");
1788

    
1789
			break;
1790
	}
1791

    
1792
	if (platform_booting()) {
1793
		echo gettext("done") . "\n";
1794
	}
1795

    
1796
	return 0;
1797
}
1798

    
1799
function vpn_l2tp_configure() {
1800
	global $config, $g;
1801

    
1802
	$syscfg = $config['system'];
1803
	$l2tpcfg = $config['l2tp'];
1804

    
1805
	/* create directory if it does not exist */
1806
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn")) {
1807
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1808
	}
1809

    
1810
	if (platform_booting()) {
1811
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off")) {
1812
			return 0;
1813
		}
1814

    
1815
		echo gettext("Configuring l2tp VPN service... ");
1816
	} else {
1817
		/* kill mpd */
1818
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1819

    
1820
		/* wait for process to die */
1821
		sleep(8);
1822

    
1823
	}
1824

    
1825
	/* make sure l2tp-vpn directory exists */
1826
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn")) {
1827
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1828
	}
1829

    
1830
	switch ($l2tpcfg['mode']) {
1831

    
1832
		case 'server':
1833
			if ($l2tpcfg['paporchap'] == "chap") {
1834
				$paporchap = "set link enable chap";
1835
			} else {
1836
				$paporchap = "set link enable pap";
1837
			}
1838

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

    
1849
EOD;
1850

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

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

    
1857
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1858

    
1859
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1860
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1861
				} else {
1862
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1863
				}
1864

    
1865
				$mpdconf .=<<<EOD
1866

    
1867
l2tp{$i}:
1868
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1869
	{$isssue_ip_type}
1870
	load l2tp_standard
1871

    
1872
EOD;
1873
			}
1874

    
1875
			$mpdconf .=<<<EOD
1876

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

    
1893
EOD;
1894

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

    
1920
			if (isset ($l2tpcfg['radius']['enable'])) {
1921
				$mpdconf .=<<<EOD
1922
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1923
	set radius retries 3
1924
	set radius timeout 10
1925
	set auth enable radius-auth
1926

    
1927
EOD;
1928

    
1929
				if (isset ($l2tpcfg['radius']['accounting'])) {
1930
					$mpdconf .=<<<EOD
1931
	set auth enable radius-acct
1932

    
1933
EOD;
1934
				}
1935
			}
1936

    
1937
			fwrite($fd, $mpdconf);
1938
			fclose($fd);
1939
			unset($mpdconf);
1940

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

    
1948
			$mpdlinks = "";
1949

    
1950
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1951
				$mpdlinks .=<<<EOD
1952

    
1953
l2tp{$i}:
1954
	set link type l2tp
1955
	set l2tp enable incoming
1956
	set l2tp disable originate
1957

    
1958
EOD;
1959
				if (!empty($l2tpcfg['secret'])) {
1960
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
1961
				}
1962
			}
1963

    
1964
			fwrite($fd, $mpdlinks);
1965
			fclose($fd);
1966
			unset($mpdlinks);
1967

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

    
1975
			$mpdsecret = "\n\n";
1976

    
1977
			if (is_array($l2tpcfg['user'])) {
1978
				foreach ($l2tpcfg['user'] as $user) {
1979
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1980
				}
1981
			}
1982

    
1983
			fwrite($fd, $mpdsecret);
1984
			fclose($fd);
1985
			unset($mpdsecret);
1986
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
1987

    
1988
			vpn_netgraph_support();
1989

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

    
1993
			break;
1994

    
1995
		case 'redir':
1996
			break;
1997
	}
1998

    
1999
	if (platform_booting()) {
2000
		echo "done\n";
2001
	}
2002

    
2003
	return 0;
2004
}
2005

    
2006
?>
(58-58/67)