Project

General

Profile

Download (54.8 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
	}
95

    
96
	return $convertion;
97
}
98

    
99
function vpn_ipsec_configure($restart = false)
100
{
101
	global $config, $g, $sa, $sn, $p1_ealgos, $p2_ealgos, $ipsec_idhandling;
102

    
103
	if ($g['platform'] == 'jail') {
104
		return;
105
	}
106

    
107
	/* get the automatic ping_hosts.sh ready */
108
	unlink_if_exists("{$g['vardb_path']}/ipsecpinghosts");
109
	touch("{$g['vardb_path']}/ipsecpinghosts");
110

    
111
	$syscfg = $config['system'];
112
	$ipseccfg = $config['ipsec'];
113
	if (!isset($ipseccfg['enable'])) {
114
		/* try to stop charon */
115
		mwexec("/usr/local/sbin/ipsec stop");
116
		/* Stop dynamic monitoring */
117
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
118

    
119
		/* wait for process to die */
120
		sleep(2);
121

    
122
		/* disallow IPSEC, it is off */
123
		mwexec("/sbin/ifconfig enc0 down");
124
		set_single_sysctl("net.inet.ip.ipsec_in_use", "0");
125

    
126
		filter_configure();
127

    
128
		return 0;
129
	}
130

    
131
	$a_phase1 = $config['ipsec']['phase1'];
132
	$a_phase2 = $config['ipsec']['phase2'];
133
	$a_client = $config['ipsec']['client'];
134

    
135
	$certpath = "{$g['varetc_path']}/ipsec/ipsec.d/certs";
136
	$capath = "{$g['varetc_path']}/ipsec/ipsec.d/cacerts";
137
	$keypath = "{$g['varetc_path']}/ipsec/ipsec.d/private";
138

    
139
	mwexec("/sbin/ifconfig enc0 up");
140
	set_single_sysctl("net.inet.ip.ipsec_in_use", "1");
141
	/* needed for config files */
142
	if (!is_dir("{$g['varetc_path']}/ipsec")) {
143
		mkdir("{$g['varetc_path']}/ipsec");
144
	}
145
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d")) {
146
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d");
147
	}
148
	if (!is_dir($capath)) {
149
		mkdir($capath);
150
	}
151
	if (!is_dir($keypath)) {
152
		mkdir($keypath);
153
	}
154
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/crls")) {
155
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/crls");
156
	}
157
	if (!is_dir($certpath)) {
158
		mkdir($certpath);
159
	}
160
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/aacerts")) {
161
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/aacerts");
162
	}
163
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/acerts")) {
164
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/acerts");
165
	}
166
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/ocspcerts")) {
167
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/ocspcerts");
168
	}
169
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/reqs")) {
170
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/reqs");
171
	}
172

    
173

    
174
	if (platform_booting()) {
175
		echo gettext("Configuring IPsec VPN... ");
176
	}
177

    
178
	/* fastforwarding is not compatible with ipsec tunnels */
179
	set_single_sysctl("net.inet.ip.fastforwarding", "0");
180

    
181
	/* resolve all local, peer addresses and setup pings */
182
	$ipmap = array();
183
	$rgmap = array();
184
	$filterdns_list = array();
185
	$listeniflist = array();
186
	$aggressive_mode_psk = false;
187
	unset($iflist);
188
	$ifacesuse = array();
189
	if (is_array($a_phase1) && count($a_phase1)) {
190

    
191
		$ipsecpinghosts = "";
192
		/* step through each phase1 entry */
193
		foreach ($a_phase1 as $ph1ent) {
194
			if (isset($ph1ent['disabled'])) {
195
				continue;
196
			}
197

    
198
			if (strpos($ph1ent['interface'], '_vip')) {
199
				$vpninterface = explode('_vip', $ph1ent['interface']);
200
				$ifacesuse[] = get_real_interface($vpninterface[0]);
201
			} else {
202
				$vpninterface = get_failover_interface($ph1ent['interface']);
203
				if (strpos($vpninterface, '_vip')) {
204
					$vpninterface = explode('_vip', $vpninterface);
205
					$ifacesuse[] = get_real_interface($vpninterface[0]);
206
				} elseif (!empty($vpninterface)) {
207
					$ifacesuse[] = $vpninterface;
208
				}
209
			}
210

    
211
			if ($ph1ent['mode'] == "aggressive" && ($ph1ent['authentication_method'] == "pre_shared_key" || $ph1ent['authentication_method'] == "xauth_psk_server")) {
212
				$aggressive_mode_psk = true;
213
			}
214

    
215
			$ikeid = $ph1ent['ikeid'];
216
			$listeniflist = get_real_interface($a_phase1['interface']);
217

    
218
			$ep = ipsec_get_phase1_src($ph1ent);
219
			if (!is_ipaddr($ep)) {
220
				log_error("IPsec ERROR: Could not find phase 1 source for connection {$ph1ent['descr']}. Omitting from configuration file.");
221
				continue;
222
			}
223

    
224
			if (!in_array($ep,$ipmap)) {
225
				$ipmap[] = $ep;
226
			}
227

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

    
231
			if (isset ($ph1ent['mobile'])) {
232
				continue;
233
			}
234

    
235
			$rg = $ph1ent['remote-gateway'];
236

    
237
			if (!is_ipaddr($rg)) {
238
				$filterdns_list[] = "{$rg}";
239
				add_hostname_to_watch($rg);
240
				if (!platform_booting()) {
241
					$rg = resolve_retry($rg);
242
				}
243
				if (!is_ipaddr($rg)) {
244
					continue;
245
				}
246
			}
247
			if (array_search($rg, $rgmap)) {
248
				log_error("The remote gateway {$rg} already exists on another phase 1 entry");
249
				continue;
250
			}
251
			$rgmap[$ph1ent['remote-gateway']] = $rg;
252

    
253
			if (is_array($a_phase2)) {
254
				/* step through each phase2 entry */
255
				foreach ($a_phase2 as $ph2ent) {
256
					if (isset($ph2ent['disabled'])) {
257
						continue;
258
					}
259

    
260
					if ($ikeid != $ph2ent['ikeid']) {
261
						continue;
262
					}
263

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

    
322
	$accept_unencrypted = "";
323
	if (isset($config['ipsec']['acceptunencryptedmainmode'])) {
324
		$accept_unencrypted = "accept_unencrypted_mainmode_messages = yes";
325
	}
326

    
327
	$stronconf = '';
328
	if (file_exists("{$g['varetc_path']}/ipsec/strongswan.conf")) {
329
		$stronconf = file_get_contents("{$g['varetc_path']}/ipsec/strongswan.conf");
330
	}
331

    
332
	$i_dont_care_about_security_and_use_aggressive_mode_psk = "";
333
	if ($aggressive_mode_psk) {
334
		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.");
335
		if (!empty($stronconf) && strpos($stronconf, 'i_dont_care_about_security_and_use_aggressive_mode_psk') === FALSE) {
336
			$restart = true;
337
		}
338
		$i_dont_care_about_security_and_use_aggressive_mode_psk = "i_dont_care_about_security_and_use_aggressive_mode_psk=yes";
339
	}
340

    
341
	$unity_enabled = 'yes';
342
	if (isset($config['ipsec']['unityplugin'])) {
343
		$unity_enabled = 'no';
344
		if (file_exists("/usr/local/lib/ipsec/plugins/libstrongswan-unity.so")) {
345
			conf_mount_rw();
346
			mwexec("mv /usr/local/lib/ipsec/plugins/libstrongswan-unity.so /usr/local/lib/ipsec/plugins/libstrongswan-unity.MOVED");
347
			conf_mount_ro();
348
		}
349
	} else if (file_exists("/usr/local/lib/ipsec/plugins/libstrongswan-unity.MOVED")) {
350
		conf_mount_rw();
351
		mwexec("mv /usr/local/lib/ipsec/plugins/libstrongswan-unity.MOVED /usr/local/lib/ipsec/plugins/libstrongswan-unity.so");
352
		conf_mount_ro();
353
	}
354

    
355
	if (isset($config['ipsec']['enableinterfacesuse'])) {
356
		if (!empty($ifacesuse)) {
357
			$ifacesuse = 'interfaces_use = ' . implode(',', array_unique($ifacesuse));
358
		} else {
359
			$ifacesuse = '';
360
		}
361
	} else {
362
		$ifacesuse = '';
363
	}
364

    
365
	unset($stronconf);
366

    
367
	$strongswan = <<<EOD
368

    
369
# Automatically generated config file - DO NOT MODIFY. Changes will be overwritten.
370
starter {
371
load_warning = no
372
}
373

    
374
charon {
375
# number of worker threads in charon
376
threads = 16
377
ikesa_table_size = 32
378
ikesa_table_segments = 4
379
init_limit_half_open = 1000
380
install_routes = no
381
{$i_dont_care_about_security_and_use_aggressive_mode_psk}
382
{$accept_unencrypted}
383
cisco_unity = {$unity_enabled}
384
{$ifacesuse}
385

    
386
# And two loggers using syslog. The subsections define the facility to log
387
# to, currently one of: daemon, auth.
388
syslog {
389
	identifier = charon
390
	# default level to the LOG_DAEMON facility
391
	daemon {
392
	}
393
	# very minimalistic IKE auditing logs to LOG_AUTHPRIV
394
	auth {
395
		default = -1
396
		ike = 1
397
		ike_name = yes
398
	}
399
}
400

    
401
EOD;
402

    
403
	$strongswan .= "\tplugins {\n";
404

    
405
	if (is_array($a_client) && isset($a_client['enable'])) {
406
		$strongswan .= "\t\tattr {\n";
407
		if ($a_client['pool_address'] && $a_client['pool_netbits']) {
408
			$strongswan .= "\t\t\tsubnet = {$a_client['pool_address']}/{$a_client['pool_netbits']}\n";
409
		}
410

    
411
		$cfgservers = array();
412
		if (!empty($a_client['dns_server1'])) {
413
			$cfgservers[] = $a_client['dns_server1'];
414
		}
415
		if (!empty($a_client['dns_server2'])) {
416
			$cfgservers[] = $a_client['dns_server2'];
417
		}
418
		if (!empty($a_client['dns_server3'])) {
419
			$cfgservers[] = $a_client['dns_server3'];
420
		}
421
		if (!empty($a_client['dns_server4'])) {
422
			$cfgservers[] = $a_client['dns_server4'];
423
		}
424

    
425
		if (!empty($cfgservers)) {
426
			$strongswan .= "\t\t\tdns = " . implode(",", $cfgservers) . "\n";
427
		}
428
		unset($cfgservers);
429
		$cfgservers = array();
430
		if (!empty($a_client['wins_server1'])) {
431
			$cfgservers[] = $a_client['wins_server1'];
432
		}
433
		if (!empty($a_client['wins_server2'])) {
434
			$cfgservers[] = $a_client['wins_server2'];
435
		}
436
		if (!empty($cfgservers)) {
437
			$strongswan .= "\t\t\tnbns = " . implode(",", $cfgservers) . "\n";
438
		}
439
		unset($cfgservers);
440

    
441
		if (isset($a_client['net_list']) && is_array($a_phase2)) {
442
			$net_list = '';
443
			foreach ($a_phase2 as $ph2ent) {
444
				if (isset($ph2ent['disabled'])) {
445
					continue;
446
				}
447

    
448
				if (!isset($ph2ent['mobile'])) {
449
					continue;
450
				}
451

    
452
				$localid = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
453

    
454
				if (!empty($net_list)) {
455
					$net_list .= ",";
456
				}
457
				$net_list .= $localid;
458
			}
459

    
460
			if (!empty($net_list)) {
461
				$strongswan .= "\t\t\tsplit-include = {$net_list}\n";
462
				unset($net_list);
463
			}
464
		}
465

    
466
		if (!empty($a_client['dns_domain'])) {
467
			$strongswan .= "\t\t\t# Search domain and default domain\n";
468
			$strongswan .= "\t\t\t28674 = \"{$a_client['dns_domain']}\"\n";
469
			if (empty($a_client['dns_split'])) {
470
				$strongswan .= "\t\t\t28675 = \"{$a_client['dns_domain']}\"";
471
			}
472
			$strongswan .= "\n";
473
		}
474

    
475
		if (!empty($a_client['dns_split'])) {
476
			$strongswan .= "\t\t\t28675 = {$a_client['dns_split']}\n";
477
		}
478

    
479
		if (!empty($a_client['login_banner'])) {
480
			$strongswan .= "\t\t\t28672 = \"{$a_client['login_banner']}\"\n";
481
		}
482

    
483
		if (isset($a_client['save_passwd'])) {
484
			$strongswan .= "\t\t\t28673 = 1\n";
485
		}
486

    
487
		if ($a_client['pfs_group']) {
488
			$strongswan .= "\t\t\t28679 = \"{$a_client['pfs_group']}\"\n";
489
		}
490
		$strongswan .= "\t\t}\n";
491

    
492
		if ($a_client['user_source'] != "none") {
493
			$strongswan .= "\t\txauth-generic {\n";
494
			$strongswan .= "\t\t\tscript = /etc/inc/ipsec.auth-user.php\n";
495
			$strongswan .= "\t\t\tauthcfg = ";
496
			$firstsed = 0;
497
			$authcfgs = explode(",", $a_client['user_source']);
498
			foreach ($authcfgs as $authcfg) {
499
				if ($firstsed > 0) {
500
					$strongswan .= ",";
501
				}
502
				if ($authcfg == "system") {
503
					$authcfg = "Local Database";
504
				}
505
				$strongswan .= $authcfg;
506
				$firstsed = 1;
507
			}
508
			$strongswan .= "\n";
509
			$strongswan .= "\t\t}\n";
510
		}
511
	}
512

    
513
	$strongswan .= "\t}\n}\n";
514
	@file_put_contents("{$g['varetc_path']}/ipsec/strongswan.conf", $strongswan);
515
	unset($strongswan);
516

    
517
	/* generate CA certificates files */
518
	if (is_array($config['ca']) && count($config['ca'])) {
519
		foreach ($config['ca'] as $ca) {
520
			if (!isset($ca['crt'])) {
521
				log_error(sprintf(gettext("Error: Invalid certificate info for %s"), $ca['descr']));
522
				continue;
523
			}
524
			$cert = base64_decode($ca['crt']);
525
			$x509cert = openssl_x509_parse(openssl_x509_read($cert));
526
			if (!is_array($x509cert) || !isset($x509cert['hash'])) {
527
				log_error(sprintf(gettext("Error: Invalid certificate hash info for %s"), $ca['descr']));
528
				continue;
529
			}
530
			$fname = "{$capath}/{$x509cert['hash']}.0.crt";
531
			if (!@file_put_contents($fname, $cert)) {
532
				log_error(sprintf(gettext("Error: Cannot write IPsec CA file for %s"), $ca['descr']));
533
				continue;
534
			}
535
			unset($cert);
536
		}
537
	}
538

    
539
	$pskconf = "";
540

    
541
	if (is_array($a_phase1) && count($a_phase1)) {
542
		foreach ($a_phase1 as $ph1ent) {
543

    
544
			if (isset($ph1ent['disabled'])) {
545
				continue;
546
			}
547

    
548
			if (strstr($ph1ent['authentication_method'], 'rsa') ||
549
			    in_array($ph1ent['authentication_method'], array('eap-mschapv2', 'eap-tls'))) {
550
				$certline = '';
551

    
552
				$ikeid = $ph1ent['ikeid'];
553
				$cert = lookup_cert($ph1ent['certref']);
554

    
555
				if (!$cert) {
556
					log_error(sprintf(gettext("Error: Invalid phase1 certificate reference for %s"), $ph1ent['name']));
557
					continue;
558
				}
559

    
560
				@chmod($certpath, 0600);
561

    
562
				$ph1keyfile = "{$keypath}/cert-{$ikeid}.key";
563
				if (!file_put_contents($ph1keyfile, base64_decode($cert['prv']))) {
564
					log_error(sprintf(gettext("Error: Cannot write phase1 key file for %s"), $ph1ent['name']));
565
					continue;
566
				}
567
				@chmod($ph1keyfile, 0600);
568

    
569
				$ph1certfile = "{$certpath}/cert-{$ikeid}.crt";
570
				if (!file_put_contents($ph1certfile, base64_decode($cert['crt']))) {
571
					log_error(sprintf(gettext("Error: Cannot write phase1 certificate file for %s"), $ph1ent['name']));
572
					@unlink($ph1keyfile);
573
					continue;
574
				}
575
				@chmod($ph1certfile, 0600);
576

    
577
				/* XXX" Traffic selectors? */
578
				$pskconf .= " : RSA {$ph1keyfile}\n";
579
			} else {
580
				list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, 'local');
581
				list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, 'peer', $rgmap);
582

    
583
				if (empty($peerid_data)) {
584
					continue;
585
				}
586

    
587
				$myid = isset($ph1ent['mobile']) ? trim($myid_data) : "%any";
588
				$peerid = ($peerid_data != 'allusers') ? trim($peerid_data) : '';
589
				if (!empty($ph1ent['pre-shared-key'])) {
590
					if ($myid_type == 'fqdn' && !empty($myid_data)) {
591
						$pskconf .= "@{$myid} {$peerid} : PSK 0s" . base64_encode(trim($ph1ent['pre-shared-key'])) . "\n";
592
					} else {
593
						$pskconf .= "{$myid} {$peerid} : PSK 0s" . base64_encode(trim($ph1ent['pre-shared-key'])) . "\n";
594
					}
595
				}
596
			}
597
		}
598
	}
599

    
600
	/* Add user PSKs */
601
	if (is_array($config['system']) && is_array($config['system']['user'])) {
602
		foreach ($config['system']['user'] as $user) {
603
			if (!empty($user['ipsecpsk'])) {
604
				$pskconf .= "%any {$user['name']} : PSK 0s" . base64_encode($user['ipsecpsk']) . "\n";
605
			}
606
		}
607
		unset($user);
608
	}
609

    
610
	/* add PSKs for mobile clients */
611
	if (is_array($ipseccfg['mobilekey'])) {
612
		foreach ($ipseccfg['mobilekey'] as $key) {
613
			if ($key['ident'] == "allusers") {
614
				$key['ident'] = '%any';
615
			}
616
			if (empty($key['type'])) {
617
				$key['type'] = 'PSK';
618
			}
619
			$pskconf .= "%any {$key['ident']} : {$key['type']} 0s" . base64_encode($key['pre-shared-key']) . "\n";
620
		}
621
		unset($key);
622
	}
623

    
624
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.secrets", $pskconf);
625
	chmod("{$g['varetc_path']}/ipsec/ipsec.secrets", 0600);
626
	unset($pskconf);
627

    
628
	$uniqueids = 'yes';
629
	if (!empty($config['ipsec']['uniqueids'])) {
630
		if (in_array($uniqueids, $ipsec_idhandling)) {
631
			$uniqueids = $config['ipsec']['uniqueids'];
632
		}
633
	}
634
	$natfilterrules = false;
635
	/* begin ipsec.conf */
636
	$ipsecconf = "";
637
	$enablecompression = false;
638
	if (is_array($a_phase1) && count($a_phase1))  {
639

    
640
		$ipsecconf .= "# This file is automatically generated. Do not edit\n";
641
		$ipsecconf .= "config setup\n\tuniqueids = {$uniqueids}\n";
642
		$ipsecconf .= "\tcharondebug=\"" . vpn_ipsec_configure_loglevels(true) . "\"\n";
643

    
644
		foreach ($a_phase1 as $ph1ent) {
645
			if (isset($ph1ent['disabled'])) {
646
				continue;
647
			}
648

    
649
			if ($ph1ent['mode'] == "aggressive") {
650
				$aggressive = "yes";
651
			} else {
652
				$aggressive = "no";
653
			}
654

    
655
			$ep = ipsec_get_phase1_src($ph1ent);
656
			if (!$ep) {
657
				continue;
658
			}
659

    
660
			$ikeid = $ph1ent['ikeid'];
661
			$keyexchange = "ikev1";
662
			$passive = "route";
663
			if (!empty($ph1ent['iketype'])) {
664
				if ($ph1ent['iketype'] == "ikev2") {
665
					$keyexchange = "ikev2";
666
					//$passive = "start";
667
				} else if ($ph1ent['iketype'] == "auto") {
668
					$keyexchange = "ike";
669
				}
670
			}
671

    
672
			if (isset($ph1ent['mobile'])) {
673
				$right_spec = "%any";
674
				$passive = 'add';
675
			} else {
676
				if (isset($ph1ent['responderonly'])) {
677
					$passive = 'add';
678
				}
679

    
680
				$right_spec = $ph1ent['remote-gateway'];
681
				if (is_ipaddr($right_spec)) {
682
					$sourcehost = $right_spec;
683
				} else {
684
					$sourcehost = $rgmap['remote-gateway'];
685
				}
686

    
687
				if ($ph1ent['protocol'] == 'inet') {
688
					if (strpos($ph1ent['interface'], '_vip')) {
689
						$vpninterface = explode('_vip', $ph1ent['interface']);
690
						$ifacesuse = get_real_interface($vpninterface[0]);
691
						$vpninterface = $vpninterface[0];
692
					} else {
693
						$ifacesuse = get_failover_interface($ph1ent['interface']);
694
						if (strpos($ifacesuse, '_vip')) {
695
							$vpninterface = explode('_vip', $ifacesuse);
696
							$ifacesuse = get_real_interface($vpninterface[0]);
697
							$vpninterface = $vpninterface[0];
698
						} else {
699
							$vpninterface = convert_real_interface_to_friendly_interface_name($ifacesuse);
700
						}
701
					}
702

    
703
					if (!empty($ifacesuse) && interface_has_gateway($vpninterface)) {
704
						$gatewayip = get_interface_gateway($vpninterface);
705
						$interfaceip = get_interface_ip($vpninterface);
706
						$subnet_bits = get_interface_subnet($vpninterface);
707
						$subnet_ip = gen_subnetv4($interfaceip, $subnet_bits);
708
						/* if the remote gateway is in the local subnet, then don't add a route */
709
						if (!ip_in_subnet($sourcehost, "{$subnet_ip}/{$subnet_bits}")) {
710
							if (is_ipaddrv4($gatewayip)) {
711
								// log_error("IPSEC interface is not WAN but {$ifacesuse}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
712
								mwexec("/sbin/route change -host {$sourcehost} {$gatewayip}", true);
713
							}
714
						}
715
					}
716
				} else if ($ph1ent['protocol'] == 'inet6') {
717
					if (strpos($ph1ent['interface'], '_vip')) {
718
						$vpninterface = explode('_vip', $ph1ent['interface']);
719
						$ifacesuse = get_real_interface($vpninterface[0]);
720
						$vpninterface = $vpninterface[0];
721
					} else {
722
						$ifacesuse = get_failover_interface($ph1ent['interface']);
723
						if (strpos($ifacesuse, '_vip')) {
724
							$vpninterface = explode('_vip', $ifacesuse);
725
							$ifacesuse = get_real_interface($vpninterface[0]);
726
							$vpninterface = $vpninterface[0];
727
						} else {
728
							$vpninterface = convert_real_interface_to_friendly_interface_name($ifacesuse);
729
						}
730
					}
731

    
732
					if (!empty($ifacesuse) && interface_has_gateway($vpninterface)) {
733
						$gatewayip = get_interface_gateway_v6($vpninterface);
734
						$interfaceip = get_interface_ipv6($vpninterface);
735
						$subnet_bits = get_interface_subnetv6($vpninterface);
736
						$subnet_ip = gen_subnetv6($interfaceip, $subnet_bits);
737
						/* if the remote gateway is in the local subnet, then don't add a route */
738
						if (!ip_in_subnet($sourcehost, "{$subnet_ip}/{$subnet_bits}")) {
739
							if (is_ipaddrv6($gatewayip)) {
740
								// log_error("IPSEC interface is not WAN but {$ifacesuse}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
741
								mwexec("/sbin/route change -inet6 -host {$sourcehost} {$gatewayip}", true);
742
							}
743
						}
744
					}
745
				}
746
			}
747

    
748
			list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, 'local');
749
			if ($myid_type != 'address') {
750
				$myid_data = "{$myid_type}:{$myid_data}";
751
			}
752

    
753
			/* Only specify peer ID if we are not dealing with a mobile PSK-only tunnel */
754
			$peerid_spec = '';
755
			if (!isset($ph1ent['mobile'])) {
756
				list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, 'peer', $rgmap);
757
				if ($peerid_type != 'address') {
758
					$peerid_spec = "{$peerid_type}:{$peerid_data}";
759
				} else {
760
					$peerid_spec = $peerid_data;
761
				}
762
			}
763

    
764
			if (is_array($ph1ent['encryption-algorithm']) && !empty($ph1ent['encryption-algorithm']['name']) && !empty($ph1ent['hash-algorithm'])) {
765
				$ealgosp1 = '';
766
				$ealg_id = $ph1ent['encryption-algorithm']['name'];
767
				$ealg_kl = $ph1ent['encryption-algorithm']['keylen'];
768
				if ($ealg_kl) {
769
					$ealgosp1 = "ike = {$ealg_id}{$ealg_kl}-{$ph1ent['hash-algorithm']}";
770
				} else {
771
					$ealgosp1 = "ike = {$ealg_id}-{$ph1ent['hash-algorithm']}";
772
				}
773

    
774
				$modp = vpn_ipsec_convert_to_modp($ph1ent['dhgroup']);
775
				if (!empty($modp)) {
776
					$ealgosp1 .= "-{$modp}";
777
				}
778

    
779
				$ealgosp1 .= "!";
780
			}
781

    
782
			if ($ph1ent['dpd_delay'] && $ph1ent['dpd_maxfail']) {
783
				if ($passive == "route") {
784
					$dpdline = "dpdaction = restart";
785
				} else {
786
					$dpdline = "dpdaction = clear";
787
				}
788
				$dpdline .= "\n\tdpddelay = {$ph1ent['dpd_delay']}s";
789
				$dpdtimeout = $ph1ent['dpd_delay'] * ($ph1ent['dpd_maxfail'] + 1);
790
				$dpdline .= "\n\tdpdtimeout = {$dpdtimeout}s";
791
			} else {
792
				$dpdline = "dpdaction = none";
793
			}
794

    
795
			$ikelifeline = '';
796
			if ($ph1ent['lifetime']) {
797
				$ikelifeline = "ikelifetime = {$ph1ent['lifetime']}s";
798
			}
799

    
800
			$rightsourceip = NULL;
801
			if (isset($ph1ent['mobile']) && !empty($a_client['pool_address'])) {
802
				$rightsourceip = "\trightsourceip = {$a_client['pool_address']}/{$a_client['pool_netbits']}\n";
803
			}
804

    
805
			$authentication = "";
806
			switch ($ph1ent['authentication_method']) {
807
				case 'eap-mschapv2':
808
					if (isset($ph1ent['mobile'])) {
809
						$authentication = "eap_identity=%any\n\t";
810
						$authentication .= "leftauth=pubkey\n\trightauth=eap-mschapv2";
811
						if (!empty($ph1ent['certref'])) {
812
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
813
						}
814
					}
815
					break;
816
				case 'eap-tls':
817
					if (isset($ph1ent['mobile'])) {
818
						$authentication = "eap_identity=%identity\n\t";
819
						$authentication .= "leftauth=pubkey\n\trightauth=eap-tls";
820
						if (!empty($ph1ent['certref'])) {
821
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
822
						}
823
					} else {
824
						$authentication = "leftauth=eap-tls\n\trightauth=eap-tls";
825
						if (!empty($ph1ent['certref'])) {
826
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
827
						}
828
					}
829
					break;
830
				case 'xauth_rsa_server':
831
					$authentication = "leftauth = pubkey\n\trightauth = pubkey";
832
					$authentication .= "\n\trightauth2 = xauth-generic";
833
					if (!empty($ph1ent['certref'])) {
834
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
835
					}
836
					break;
837
				case 'xauth_psk_server':
838
					$authentication = "leftauth = psk\n\trightauth = psk";
839
					$authentication .= "\n\trightauth2 = xauth-generic";
840
					break;
841
				case 'pre_shared_key':
842
					$authentication = "leftauth = psk\n\trightauth = psk";
843
					break;
844
				case 'rsasig':
845
					$authentication = "leftauth = pubkey\n\trightauth = pubkey";
846
					if (!empty($ph1ent['certref'])) {
847
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
848
					}
849
					break;
850
				case 'hybrid_rsa_server':
851
					$authentication = "leftauth = xauth-generic\n\trightauth = pubkey";
852
					$authentication .= "\n\trightauth2 = xauth";
853
					if (!empty($ph1ent['certref'])) {
854
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
855
					}
856
					break;
857
			}
858

    
859
			$left_spec = $ep;
860

    
861
			if (isset($ph1ent['reauth_enable'])) {
862
				$reauth = "reauth = no";
863
			} else {
864
				$reauth = "reauth = yes";
865
			}
866
			if (isset($ph1ent['rekey_enable'])) {
867
				$rekey = "rekey = no";
868
			} else {
869
				$rekey = "rekey = yes";
870
			}
871

    
872
			if ($ph1ent['nat_traversal'] == 'off') {
873
				$forceencaps = 'forceencaps = no';
874
			} else if ($ph1ent['nat_traversal'] == 'force') {
875
				$forceencaps = 'forceencaps = yes';
876
			} else {
877
				$forceencaps = 'forceencaps = no';
878
			}
879

    
880
			if ($ph1ent['mobike'] == 'on') {
881
				$mobike = 'mobike = yes';
882
			} else {
883
				$mobike = 'mobike = no';
884
			}
885

    
886
			$ipseclifetime = 0;
887
			$rightsubnet_spec = array();
888
			$leftsubnet_spec = array();
889
			$reqids = array();
890
			$ealgoAHsp2arr = array();
891
			$ealgoESPsp2arr = array();
892
		if (is_array($a_phase2) && count($a_phase2)) {
893
			foreach ($a_phase2 as $ph2ent) {
894
				if ($ikeid != $ph2ent['ikeid']) {
895
					continue;
896
				}
897

    
898
				if (isset($ph2ent['disabled'])) {
899
					continue;
900
				}
901

    
902
				if (isset($ph2ent['mobile']) && !isset($a_client['enable'])) {
903
					continue;
904
				}
905

    
906
				if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
907
					$tunneltype = "type = tunnel";
908

    
909
					$localid_type = $ph2ent['localid']['type'];
910
					$leftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['localid'], false, $ph2ent['mode']);
911

    
912
					/* Do not print localid in some cases, such as a pure-psk or psk/xauth single phase2 mobile tunnel */
913
					if (($localid_type == "none" || $localid_type == "mobile") &&
914
					    isset($ph1ent['mobile']) && (ipsec_get_number_of_phase2($ikeid)==1)) {
915
						$left_spec = '%any';
916
					} else {
917
						if ($localid_type != "address") {
918
							$localid_type = "subnet";
919
						}
920
						// Don't let an empty subnet into config, it can cause parse errors. Ticket #2201.
921
						if (!is_ipaddr($leftsubnet_data) && !is_subnet($leftsubnet_data) && ($leftsubnet_data != "0.0.0.0/0")) {
922
							log_error("Invalid IPsec Phase 2 \"{$ph2ent['descr']}\" - {$ph2ent['localid']['type']} has no subnet.");
923
							continue;
924
						}
925
						if (!empty($ph2ent['natlocalid'])) {
926
							$natleftsubnet_data =  ipsec_idinfo_to_cidr($ph2ent['natlocalid'], false, $ph2ent['mode']);
927
							if ($ph2ent['natlocalid']['type'] != "address") {
928
								if (is_subnet($natleftsubnet_data)) {
929
									$leftsubnet_data = "{$natleftsubnet_data}|{$leftsubnet_data}";
930
								}
931
							} else {
932
								if (is_ipaddr($natleftsubnet_data)) {
933
									$leftsubnet_data = "{$natleftsubnet_data}|{$leftsubnet_data}";
934
								}
935
							}
936
							$natfilterrules = true;
937
						}
938
					}
939

    
940
					$leftsubnet_spec[] = $leftsubnet_data;
941

    
942
					if (!isset($ph2ent['mobile'])) {
943
						$tmpsubnet = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']);
944
						$rightsubnet_spec[] = $tmpsubnet;
945
					} else if (!empty($a_client['pool_address'])) {
946
						$rightsubnet_spec[] = "{$a_client['pool_address']}/{$a_client['pool_netbits']}";
947
					}
948
				} else {
949
					$tunneltype = "type = transport";
950

    
951
					if ((($ph1ent['authentication_method'] == "xauth_psk_server") ||
952
					    ($ph1ent['authentication_method'] == "pre_shared_key")) && isset($ph1ent['mobile'])) {
953
						$left_spec = "%any";
954
					} else {
955
						$tmpsubnet = ipsec_get_phase1_src($ph1ent);
956
						$leftsubnet_spec[] = $tmpsubnet;
957
					}
958

    
959
					if (!isset($ph2ent['mobile'])) {
960
						$rightsubnet_spec[] = $right_spec;
961
					}
962
				}
963

    
964
				if (isset($a_client['pfs_group'])) {
965
					$ph2ent['pfsgroup'] = $a_client['pfs_group'];
966
				}
967

    
968
				if ($ph2ent['protocol'] == 'esp') {
969
					if (is_array($ph2ent['encryption-algorithm-option'])) {
970
						foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
971
							$ealg_id = $ealg['name'];
972
							$ealg_kl = $ealg['keylen'];
973

    
974
							if (!empty($ealg_kl) && $ealg_kl == "auto") {
975
								if (empty($p2_ealgos) || !is_array($p2_ealgos)) {
976
									require("ipsec.inc");
977
								}
978
								$key_hi = $p2_ealgos[$ealg_id]['keysel']['hi'];
979
								$key_lo = $p2_ealgos[$ealg_id]['keysel']['lo'];
980
								$key_step = $p2_ealgos[$ealg_id]['keysel']['step'];
981
								/* XXX: in some cases where include ordering is suspect these variables
982
								 * are somehow 0 and we enter this loop forever and timeout after 900
983
								 * seconds wrecking bootup */
984
								if ($key_hi != 0 and $key_lo !=0 and $key_step !=0) {
985
									for ($keylen = $key_hi; $keylen >= $key_lo; $keylen -= $key_step) {
986
										if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
987
											foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
988
												$halgo = str_replace('hmac_', '', $halgo);
989
												$tmpealgo = "{$ealg_id}{$keylen}-{$halgo}";
990
												$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
991
												if (!empty($modp)) {
992
													$tmpealgo .= "-{$modp}";
993
												}
994
												$ealgoESPsp2arr[] = $tmpealgo;
995
											}
996
										} else {
997
											$tmpealgo = "{$ealg_id}{$keylen}";
998
											$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
999
											if (!empty($modp)) {
1000
												$tmpealgo .= "-{$modp}";
1001
											}
1002
											$ealgoESPsp2arr[] = $tmpealgo;
1003
										}
1004
									}
1005
								}
1006
							} else {
1007
								if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
1008
									foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
1009
										$halgo = str_replace('hmac_', '', $halgo);
1010
										$tmpealgo = "{$ealg_id}{$ealg_kl}-{$halgo}";
1011
										$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1012
										if (!empty($modp)) {
1013
											$tmpealgo .= "-{$modp}";
1014
										}
1015
										$ealgoESPsp2arr[] = $tmpealgo;
1016
									}
1017
								} else {
1018
									$tmpealgo = "{$ealg_id}{$ealg_kl}";
1019
									$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1020
									if (!empty($modp)) {
1021
										$tmpealgo .= "-{$modp}";
1022
									}
1023
									$ealgoESPsp2arr[] = $tmpealgo;
1024
								}
1025
							}
1026
						}
1027
					}
1028
				} else if ($ph2ent['protocol'] == 'ah') {
1029
					if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
1030
						$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1031
						foreach ($ph2ent['hash-algorithm-option'] as $tmpAHalgo) {
1032
							$tmpAHalgo = str_replace('hmac_', '', $tmpAHalgo);
1033
							if (!empty($modp)) {
1034
								$tmpAHalgo = "-{$modp}";
1035
							}
1036
							$ealgoAHsp2arr[] = $tmpAHalgo;
1037
						}
1038
					}
1039
				}
1040

    
1041
				$reqids[] = $ph2ent['reqid'];
1042

    
1043
				if (!empty($ph2ent['lifetime'])) {
1044
					if ($ipseclifetime == 0 || intval($ipseclifetime) > intval($ph2ent['lifetime'])) {
1045
						$ipseclifetime = intval($ph2ent['lifetime']);
1046
					}
1047
				}
1048

    
1049
			}
1050
		}
1051

    
1052
			$ipsecconnect =<<<EOD
1053
	fragmentation = yes
1054
	keyexchange = {$keyexchange}
1055
	{$reauth}
1056
	{$forceencaps}
1057
	{$mobike}
1058
	{$rekey}
1059
	installpolicy = yes
1060
	{$tunneltype}
1061
	{$dpdline}
1062
	auto = {$passive}
1063
	left = {$left_spec}
1064
	right = {$right_spec}
1065
	leftid = {$myid_data}
1066

    
1067
EOD;
1068

    
1069
			if (isset($config['ipsec']['compression'])) {
1070
				$ipsecconnect .= "\tcompress = yes\n";
1071
				$enablecompression = true;
1072
			}
1073
			if (!empty($ikelifeline)) {
1074
				$ipsecconnect .= "\t{$ikelifeline}\n";
1075
			}
1076
			if ($ipseclifetime > 0) {
1077
				$ipsecconnect .= "\tlifetime = {$ipseclifetime}s\n";
1078
			}
1079
			if (!empty($rightsourceip)) {
1080
				$ipsecconnect .= "{$rightsourceip}";
1081
			}
1082
			if (!empty($ealgosp1)) {
1083
				$ipsecconnect .= "\t{$ealgosp1}\n";
1084
			}
1085
			if (!empty($ealgoAHsp2arr)) {
1086
				$ipsecconnect .= "\tah = " . join(',', $ealgoAHsp2arr) . "!\n";
1087
			}
1088
			if (!empty($ealgoESPsp2arr)) {
1089
				$ipsecconnect .= "\tesp = " . join(',', $ealgoESPsp2arr) . "!\n";
1090
			}
1091
			if (!empty($authentication)) {
1092
				$ipsecconnect .= "\t{$authentication}\n";
1093
			}
1094
			if (!empty($peerid_spec)) {
1095
				$ipsecconnect .= "\trightid = {$peerid_spec}\n";
1096
			}
1097
			if ($keyexchange == 'ikev1') {
1098
				$ipsecconnect .= "\taggressive = {$aggressive}\n";
1099
			}
1100

    
1101
			if (!isset($ph1ent['mobile']) && $keyexchange == 'ikev1') {
1102
				if (!empty($rightsubnet_spec)) {
1103
					$ipsecfin = '';
1104
					foreach ($rightsubnet_spec as $idx => $rsubnet) {
1105
						$ipsecfin .= "\nconn con{$ph1ent['ikeid']}00{$idx}\n";
1106
						if (!empty($reqids[$idx])) {
1107
							$ipsecfin .= "\treqid = " . $reqids[$idx] . "\n";
1108
						}
1109
						$ipsecfin .= $ipsecconnect;
1110
						$ipsecfin .= "\trightsubnet = {$rsubnet}\n";
1111
						$ipsecfin .= "\tleftsubnet = " . $leftsubnet_spec[$idx] . "\n";
1112
					}
1113
				} else {
1114
					log_error("No phase2 specifications for tunnel with REQID = {$ikeid}");
1115
				}
1116
			} else {
1117
				$ipsecfin = "\nconn con{$ph1ent['ikeid']}\n";
1118
				if (!empty($reqids[$idx])) {
1119
					$ipsecfin .= "\treqid = " . $reqids[0] . "\n";
1120
				}
1121
				$ipsecfin .= $ipsecconnect;
1122
				if (!isset($ph1ent['mobile']) && !empty($rightsubnet_spec)) {
1123
					$tempsubnets = array();
1124
					foreach ($rightsubnet_spec as $rightsubnet) {
1125
						$tempsubnets[$rightsubnet] = $rightsubnet;
1126
					}
1127
					$ipsecfin .= "\trightsubnet = " . join(",", $tempsubnets) . "\n";
1128
					unset($tempsubnets, $rightsubnet);
1129
				}
1130
				if (!empty($leftsubnet_spec)) {
1131
					$tempsubnets = array();
1132
					foreach ($leftsubnet_spec as $leftsubnet) {
1133
						$tempsubnets[$leftsubnet] = $leftsubnet;
1134
					}
1135
					$ipsecfin .= "\tleftsubnet = " . join(",", $leftsubnet_spec) . "\n";
1136
					unset($tempsubnets, $leftsubnet);
1137
				}
1138
			}
1139
			$ipsecconf .= $ipsecfin;
1140
			unset($ipsecfin);
1141
		}
1142
	}
1143

    
1144
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.conf", $ipsecconf);
1145
	unset($ipsecconf);
1146
	/* end ipsec.conf */
1147

    
1148
	if ($enablecompression === true) {
1149
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 1);
1150
	} else {
1151
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 0);
1152
	}
1153

    
1154
	/* manage process */
1155
	if ($restart === true) {
1156
		mwexec("/usr/local/sbin/ipsec restart", false);
1157
	} else {
1158
		if (isvalidpid("{$g['varrun_path']}/charon.pid")) {
1159
			/* Read secrets */
1160
			mwexec("/usr/local/sbin/ipsec rereadall", false);
1161
			/* Update configuration changes */
1162
			mwexec("/usr/local/sbin/ipsec update", false);
1163
		} else {
1164
			mwexec("/usr/local/sbin/ipsec start", false);
1165
		}
1166
	}
1167

    
1168
	if ($natfilterrules == true) {
1169
		filter_configure();
1170
	}
1171
	/* start filterdns, if necessary */
1172
	if (count($filterdns_list) > 0) {
1173
		$interval = 60;
1174
		if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval'])) {
1175
			$interval = $ipseccfg['dns-interval'];
1176
		}
1177

    
1178
		$hostnames = "";
1179
		array_unique($filterdns_list);
1180
		foreach ($filterdns_list as $hostname) {
1181
			$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload ipsecdns\"'\n";
1182
		}
1183
		file_put_contents("{$g['varetc_path']}/ipsec/filterdns-ipsec.hosts", $hostnames);
1184
		unset($hostnames);
1185

    
1186
		if (isvalidpid("{$g['varrun_path']}/filterdns-ipsec.pid")) {
1187
			sigkillbypid("{$g['varrun_path']}/filterdns-ipsec.pid", "HUP");
1188
		} else {
1189
			mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/ipsec/filterdns-ipsec.hosts -d 1");
1190
		}
1191
	} else {
1192
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
1193
		@unlink("{$g['varrun_path']}/filterdns-ipsec.pid");
1194
	}
1195

    
1196
	if (platform_booting()) {
1197
		echo "done\n";
1198
	}
1199

    
1200
	return count($filterdns_list);
1201
}
1202

    
1203
/*
1204
 * Forcefully restart IPsec
1205
 * This is required for when dynamic interfaces reload
1206
 * For all other occasions the normal vpn_ipsec_configure()
1207
 * will gracefully reload the settings without restarting
1208
 */
1209
function vpn_ipsec_force_reload($interface = "") {
1210
	global $g, $config;
1211

    
1212
	$ipseccfg = $config['ipsec'];
1213

    
1214
	if (!empty($interface) && is_array($ipseccfg['phase1'])) {
1215
		$found = false;
1216
		foreach ($ipseccfg['phase1'] as $ipsec) {
1217
			if (!isset($ipsec['disabled']) && ($ipsec['interface'] == $interface)) {
1218
				$found = true;
1219
				break;
1220
			}
1221
		}
1222
		if (!$found) {
1223
			log_error(sprintf(gettext("Ignoring IPsec reload since there are no tunnels on interface %s"), $interface));
1224
			return;
1225
		}
1226
	}
1227

    
1228
	/* if ipsec is enabled, start up again */
1229
	if (isset($ipseccfg['enable'])) {
1230
		log_error(gettext("Forcefully reloading IPsec"));
1231
		vpn_ipsec_configure();
1232
	}
1233
}
1234

    
1235
/* master setup for vpn (mpd) */
1236
function vpn_setup() {
1237
	global $g;
1238

    
1239
	if ($g['platform'] == 'jail') {
1240
		return;
1241
	}
1242

    
1243
	/* start pptpd */
1244
	vpn_pptpd_configure();
1245

    
1246
	/* start pppoe server */
1247
	vpn_pppoes_configure();
1248

    
1249
	/* setup l2tp */
1250
	vpn_l2tp_configure();
1251
}
1252

    
1253
function vpn_netgraph_support() {
1254
	$iflist = get_configured_interface_list();
1255
	foreach ($iflist as $iface) {
1256
		$realif = get_real_interface($iface);
1257
		/* Get support for netgraph(4) from the nic */
1258
		$ifinfo = pfSense_get_interface_addresses($realif);
1259
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge"))) {
1260
			pfSense_ngctl_attach(".", $realif);
1261
		}
1262
	}
1263
}
1264

    
1265
function vpn_pptpd_configure() {
1266
	global $config, $g;
1267

    
1268
	$syscfg = $config['system'];
1269
	$pptpdcfg = $config['pptpd'];
1270

    
1271
	if (platform_booting()) {
1272
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off")) {
1273
			return 0;
1274
		}
1275

    
1276
		if (platform_booting(true)) {
1277
			echo gettext("Configuring PPTP VPN service... ");
1278
		}
1279
	} else {
1280
		/* kill mpd */
1281
		killbypid("{$g['varrun_path']}/pptp-vpn.pid");
1282

    
1283
		/* wait for process to die */
1284
		sleep(3);
1285

    
1286
		if (is_process_running("mpd -b")) {
1287
			killbypid("{$g['varrun_path']}/pptp-vpn.pid");
1288
			log_error(gettext("Could not kill mpd within 3 seconds.   Trying again."));
1289
		}
1290

    
1291
		/* remove mpd.conf, if it exists */
1292
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.conf");
1293
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.links");
1294
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.secret");
1295
	}
1296

    
1297
	if (empty($pptpdcfg['n_pptp_units'])) {
1298
		log_error("Something wrong in the PPTPd configuration. Preventing starting the daemon because issues would arise.");
1299
		return;
1300
	}
1301

    
1302
	/* make sure pptp-vpn directory exists */
1303
	if (!file_exists("{$g['varetc_path']}/pptp-vpn")) {
1304
		mkdir("{$g['varetc_path']}/pptp-vpn");
1305
	}
1306

    
1307
	switch ($pptpdcfg['mode']) {
1308
		case 'server':
1309
			/* write mpd.conf */
1310
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.conf", "w");
1311
			if (!$fd) {
1312
				printf(gettext("Error: cannot open mpd.conf in vpn_pptpd_configure().") . "\n");
1313
				return 1;
1314
			}
1315

    
1316
			$mpdconf = <<<EOD
1317
pptps:
1318

    
1319
EOD;
1320

    
1321
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1322
				$mpdconf .= "	load pt{$i}\n";
1323
			}
1324

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

    
1327
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
1328

    
1329
				$mpdconf .= <<<EOD
1330

    
1331
pt{$i}:
1332
	new -i pptpd{$i} pt{$i} pt{$i}
1333
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
1334
	load pts
1335

    
1336
EOD;
1337
			}
1338

    
1339
			$mpdconf .=<<<EOD
1340

    
1341
pts:
1342
	set iface disable on-demand
1343
	set iface enable proxy-arp
1344
	set iface enable tcpmssfix
1345
	set iface idle 1800
1346
	set iface up-script /usr/local/sbin/vpn-linkup
1347
	set iface down-script /usr/local/sbin/vpn-linkdown
1348
	set bundle enable multilink
1349
	set bundle enable crypt-reqd
1350
	set link yes acfcomp protocomp
1351
	set link no pap chap
1352
	set link enable chap-msv2
1353
	set link mtu 1460
1354
	set link keep-alive 10 60
1355
	set ipcp yes vjcomp
1356
	set bundle enable compression
1357
	set ccp yes mppc
1358
	set ccp yes mpp-e128
1359
	set ccp yes mpp-stateless
1360

    
1361
EOD;
1362

    
1363
			if (!isset ($pptpdcfg['req128'])) {
1364
				$mpdconf .=<<<EOD
1365
	set ccp yes mpp-e40
1366
	set ccp yes mpp-e56
1367

    
1368
EOD;
1369
			}
1370

    
1371
			if  (isset($pptpdcfg["wins"]) && $pptpdcfg['wins'] != "") {
1372
				$mpdconf  .=  "	set ipcp nbns {$pptpdcfg['wins']}\n";
1373
			}
1374

    
1375
			if (!empty($pptpdcfg['dns1'])) {
1376
				$mpdconf .= "	set ipcp dns " . $pptpdcfg['dns1'];
1377
				if (!empty($pptpdcfg['dns2'])) {
1378
					$mpdconf .= " " . $pptpdcfg['dns2'];
1379
				}
1380
				$mpdconf .= "\n";
1381
			} elseif (isset ($config['dnsmasq']['enable'])) {
1382
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1383
				if ($syscfg['dnsserver'][0]) {
1384
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1385
				}
1386
				$mpdconf .= "\n";
1387
			} elseif (isset($config['unbound']['enable'])) {
1388
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1389
				if ($syscfg['dnsserver'][0]) {
1390
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1391
				}
1392
				$mpdconf .= "\n";
1393
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1394
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1395
			}
1396

    
1397
			if (isset ($pptpdcfg['radius']['server']['enable'])) {
1398
				$authport = (isset($pptpdcfg['radius']['server']['port']) && strlen($pptpdcfg['radius']['server']['port']) > 1) ? $pptpdcfg['radius']['server']['port'] : 1812;
1399
				$acctport = $authport + 1;
1400
				$mpdconf .=<<<EOD
1401
	set radius server {$pptpdcfg['radius']['server']['ip']} "{$pptpdcfg['radius']['server']['secret']}" {$authport} {$acctport}
1402

    
1403
EOD;
1404
				if (isset ($pptpdcfg['radius']['server2']['enable'])) {
1405
					$authport = (isset($pptpdcfg['radius']['server2']['port']) && strlen($pptpdcfg['radius']['server2']['port']) > 1) ? $pptpdcfg['radius']['server2']['port'] : 1812;
1406
					$acctport = $authport + 1;
1407
					$mpdconf .=<<<EOD
1408
	set radius server {$pptpdcfg['radius']['server2']['ip']} "{$pptpdcfg['radius']['server2']['secret2']}" {$authport} {$acctport}
1409

    
1410
EOD;
1411
				}
1412
				$mpdconf .=<<<EOD
1413
	set radius retries 3
1414
	set radius timeout 10
1415
	set auth enable radius-auth
1416

    
1417
EOD;
1418

    
1419
				if (isset ($pptpdcfg['radius']['accounting'])) {
1420
					$mpdconf .=<<<EOD
1421
	set auth enable radius-acct
1422
	set radius acct-update 300
1423

    
1424
EOD;
1425
				}
1426
			}
1427

    
1428
			fwrite($fd, $mpdconf);
1429
			fclose($fd);
1430
			unset($mpdconf);
1431

    
1432
			/* write mpd.links */
1433
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.links", "w");
1434
			if (!$fd) {
1435
				printf(gettext("Error: cannot open mpd.links in vpn_pptpd_configure().") . "\n");
1436
				return 1;
1437
			}
1438

    
1439
			$mpdlinks = "";
1440

    
1441
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1442
				$mpdlinks .=<<<EOD
1443

    
1444
pt{$i}:
1445
	set link type pptp
1446
	set pptp enable incoming
1447
	set pptp disable originate
1448
	set pptp disable windowing
1449

    
1450
EOD;
1451
			}
1452

    
1453
			fwrite($fd, $mpdlinks);
1454
			fclose($fd);
1455
			unset($mpdlinks);
1456

    
1457
			/* write mpd.secret */
1458
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.secret", "w");
1459
			if (!$fd) {
1460
				printf(gettext("Error: cannot open mpd.secret in vpn_pptpd_configure().") . "\n");
1461
				return 1;
1462
			}
1463

    
1464
			$mpdsecret = "";
1465

    
1466
			if (is_array($pptpdcfg['user'])) {
1467
				foreach ($pptpdcfg['user'] as $user) {
1468
					$pass = str_replace('\\', '\\\\', $user['password']);
1469
					$pass = str_replace('"', '\"', $pass);
1470
					$mpdsecret .= "{$user['name']} \"{$pass}\" {$user['ip']}\n";
1471
				}
1472
			}
1473

    
1474
			fwrite($fd, $mpdsecret);
1475
			fclose($fd);
1476
			unset($mpdsecret);
1477
			chmod("{$g['varetc_path']}/pptp-vpn/mpd.secret", 0600);
1478

    
1479
			vpn_netgraph_support();
1480

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

    
1484
			break;
1485

    
1486
		case 'redir':
1487
			break;
1488
	}
1489

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

    
1494
	return 0;
1495
}
1496

    
1497
function vpn_pppoes_configure() {
1498
	global $config;
1499

    
1500
	if (is_array($config['pppoes']['pppoe'])) {
1501
		foreach ($config['pppoes']['pppoe'] as $pppoe) {
1502
			vpn_pppoe_configure($pppoe);
1503
		}
1504
	}
1505
}
1506

    
1507
function vpn_pppoe_configure(&$pppoecfg) {
1508
	global $config, $g;
1509

    
1510
	$syscfg = $config['system'];
1511

    
1512
	/* create directory if it does not exist */
1513
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn")) {
1514
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1515
	}
1516

    
1517
	if (platform_booting()) {
1518
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off")) {
1519
			return 0;
1520
		}
1521

    
1522
		echo gettext("Configuring PPPoE Server service... ");
1523
	} else {
1524
		/* kill mpd */
1525
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1526

    
1527
		/* wait for process to die */
1528
		sleep(2);
1529

    
1530
	}
1531

    
1532
	switch ($pppoecfg['mode']) {
1533

    
1534
		case 'server':
1535

    
1536
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1537

    
1538
			if ($pppoecfg['paporchap'] == "chap") {
1539
				$paporchap = "set link enable chap";
1540
			} else {
1541
				$paporchap = "set link enable pap";
1542
			}
1543

    
1544
			/* write mpd.conf */
1545
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1546
			if (!$fd) {
1547
				printf(gettext("Error: cannot open mpd.conf in vpn_pppoe_configure().") . "\n");
1548
				return 1;
1549
			}
1550
			$mpdconf = "\n\n";
1551
			$mpdconf .= "poes:\n";
1552

    
1553
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1554
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1555
			}
1556

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

    
1559
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1560

    
1561
				if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1562
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1563
				} else {
1564
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1565
				}
1566

    
1567
				$mpdconf .=<<<EOD
1568

    
1569
poes{$pppoecfg['pppoeid']}{$i}:
1570
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1571
	{$isssue_ip_type}
1572
	load pppoe_standard
1573

    
1574
EOD;
1575
			}
1576

    
1577
			$mpdconf .=<<<EOD
1578

    
1579
pppoe_standard:
1580
	set bundle no multilink
1581
	set bundle enable compression
1582
	set auth max-logins 1
1583
	set iface up-script /usr/local/sbin/vpn-linkup
1584
	set iface down-script /usr/local/sbin/vpn-linkdown
1585
	set iface idle 0
1586
	set iface disable on-demand
1587
	set iface disable proxy-arp
1588
	set iface enable tcpmssfix
1589
	set iface mtu 1500
1590
	set link no pap chap
1591
	{$paporchap}
1592
	set link keep-alive 60 180
1593
	set ipcp yes vjcomp
1594
	set ipcp no vjcomp
1595
	set link max-redial -1
1596
	set link mtu 1492
1597
	set link mru 1492
1598
	set ccp yes mpp-e40
1599
	set ccp yes mpp-e128
1600
	set ccp yes mpp-stateless
1601
	set link latency 1
1602
	#set ipcp dns 10.10.1.3
1603
	#set bundle accept encryption
1604

    
1605
EOD;
1606

    
1607
			if (!empty($pppoecfg['dns1'])) {
1608
				$mpdconf .= "	set ipcp dns " . $pppoecfg['dns1'];
1609
				if (!empty($pppoecfg['dns2'])) {
1610
					$mpdconf .= " " . $pppoecfg['dns2'];
1611
				}
1612
				$mpdconf .= "\n";
1613
			} elseif (isset ($config['dnsmasq']['enable'])) {
1614
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1615
				if ($syscfg['dnsserver'][0]) {
1616
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1617
				}
1618
				$mpdconf .= "\n";
1619
			} elseif (isset ($config['unbound']['enable'])) {
1620
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1621
				if ($syscfg['dnsserver'][0]) {
1622
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1623
				}
1624
				$mpdconf .= "\n";
1625
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1626
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1627
			}
1628

    
1629
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1630
				$radiusport = "";
1631
				$radiusacctport = "";
1632
				if (isset($pppoecfg['radius']['server']['port'])) {
1633
					$radiusport = $pppoecfg['radius']['server']['port'];
1634
				}
1635
				if (isset($pppoecfg['radius']['server']['acctport'])) {
1636
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1637
				}
1638
				$mpdconf .=<<<EOD
1639
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
1640
	set radius retries 3
1641
	set radius timeout 10
1642
	set auth enable radius-auth
1643

    
1644
EOD;
1645

    
1646
				if (isset ($pppoecfg['radius']['accounting'])) {
1647
					$mpdconf .=<<<EOD
1648
	set auth enable radius-acct
1649

    
1650
EOD;
1651
				}
1652
			}
1653

    
1654
			fwrite($fd, $mpdconf);
1655
			fclose($fd);
1656
			unset($mpdconf);
1657

    
1658
			/* write mpd.links */
1659
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.links", "w");
1660
			if (!$fd) {
1661
				printf(gettext("Error: cannot open mpd.links in vpn_pppoe_configure().") . "\n");
1662
				return 1;
1663
			}
1664

    
1665
			$mpdlinks = "";
1666

    
1667
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1668
				$mpdlinks .=<<<EOD
1669

    
1670
poes{$pppoecfg['pppoeid']}{$i}:
1671
	set phys type pppoe
1672
	set pppoe iface {$pppoe_interface}
1673
	set pppoe service "*"
1674
	set pppoe disable originate
1675
	set pppoe enable incoming
1676

    
1677
EOD;
1678
			}
1679

    
1680
			fwrite($fd, $mpdlinks);
1681
			fclose($fd);
1682
			unset($mpdlinks);
1683

    
1684
			if ($pppoecfg['username']) {
1685
				/* write mpd.secret */
1686
				$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
1687
				if (!$fd) {
1688
					printf(gettext("Error: cannot open mpd.secret in vpn_pppoe_configure().") . "\n");
1689
					return 1;
1690
				}
1691

    
1692
				$mpdsecret = "\n\n";
1693

    
1694
				if (!empty($pppoecfg['username'])) {
1695
					$item = explode(" ", $pppoecfg['username']);
1696
					foreach ($item as $userdata) {
1697
						$data = explode(":", $userdata);
1698
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1699
					}
1700
				}
1701

    
1702
				fwrite($fd, $mpdsecret);
1703
				fclose($fd);
1704
				unset($mpdsecret);
1705
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1706
			}
1707

    
1708
			/* Check if previous instance is still up */
1709
			while (file_exists("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid") && isvalidpid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid")) {
1710
				killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1711
			}
1712

    
1713
			/* Get support for netgraph(4) from the nic */
1714
			pfSense_ngctl_attach(".", $pppoe_interface);
1715
			/* fire up mpd */
1716
			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");
1717

    
1718
			break;
1719
	}
1720

    
1721
	if (platform_booting()) {
1722
		echo gettext("done") . "\n";
1723
	}
1724

    
1725
	return 0;
1726
}
1727

    
1728
function vpn_l2tp_configure() {
1729
	global $config, $g;
1730

    
1731
	$syscfg = $config['system'];
1732
	$l2tpcfg = $config['l2tp'];
1733

    
1734
	/* create directory if it does not exist */
1735
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn")) {
1736
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1737
	}
1738

    
1739
	if (platform_booting()) {
1740
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off")) {
1741
			return 0;
1742
		}
1743

    
1744
		echo gettext("Configuring l2tp VPN service... ");
1745
	} else {
1746
		/* kill mpd */
1747
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1748

    
1749
		/* wait for process to die */
1750
		sleep(8);
1751

    
1752
	}
1753

    
1754
	/* make sure l2tp-vpn directory exists */
1755
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn")) {
1756
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1757
	}
1758

    
1759
	switch ($l2tpcfg['mode']) {
1760

    
1761
		case 'server':
1762
			if ($l2tpcfg['paporchap'] == "chap") {
1763
				$paporchap = "set link enable chap";
1764
			} else {
1765
				$paporchap = "set link enable pap";
1766
			}
1767

    
1768
			/* write mpd.conf */
1769
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1770
			if (!$fd) {
1771
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
1772
				return 1;
1773
			}
1774
			$mpdconf = "\n\n";
1775
			$mpdconf .=<<<EOD
1776
l2tps:
1777

    
1778
EOD;
1779

    
1780
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1781
				$mpdconf .= "	load l2tp{$i}\n";
1782
			}
1783

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

    
1786
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1787

    
1788
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1789
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1790
				} else {
1791
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1792
				}
1793

    
1794
				$mpdconf .=<<<EOD
1795

    
1796
l2tp{$i}:
1797
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1798
	{$isssue_ip_type}
1799
	load l2tp_standard
1800

    
1801
EOD;
1802
			}
1803

    
1804
			$mpdconf .=<<<EOD
1805

    
1806
l2tp_standard:
1807
	set bundle disable multilink
1808
	set bundle enable compression
1809
	set bundle yes crypt-reqd
1810
	set ipcp yes vjcomp
1811
	# set ipcp ranges 131.188.69.161/32 131.188.69.170/28
1812
	set ccp yes mppc
1813
	set iface disable on-demand
1814
	set iface enable proxy-arp
1815
	set iface up-script /usr/local/sbin/vpn-linkup
1816
	set iface down-script /usr/local/sbin/vpn-linkdown
1817
	set link yes acfcomp protocomp
1818
	set link no pap chap
1819
	{$paporchap}
1820
	set link keep-alive 10 180
1821

    
1822
EOD;
1823

    
1824
			if (is_ipaddr($l2tpcfg['wins'])) {
1825
				$mpdconf .= "	set ipcp nbns {$l2tpcfg['wins']}\n";
1826
			}
1827
			if (is_ipaddr($l2tpcfg['dns1'])) {
1828
				$mpdconf .= "	set ipcp dns " . $l2tpcfg['dns1'];
1829
				if (is_ipaddr($l2tpcfg['dns2'])) {
1830
					$mpdconf .= " " . $l2tpcfg['dns2'];
1831
				}
1832
				$mpdconf .= "\n";
1833
			} elseif (isset ($config['dnsmasq']['enable'])) {
1834
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1835
				if ($syscfg['dnsserver'][0]) {
1836
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1837
				}
1838
				$mpdconf .= "\n";
1839
			} elseif (isset ($config['unbound']['enable'])) {
1840
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1841
				if ($syscfg['dnsserver'][0]) {
1842
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1843
				}
1844
				$mpdconf .= "\n";
1845
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1846
				$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1847
			}
1848

    
1849
			if (isset ($l2tpcfg['radius']['enable'])) {
1850
				$mpdconf .=<<<EOD
1851
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1852
	set radius retries 3
1853
	set radius timeout 10
1854
	set auth enable radius-auth
1855

    
1856
EOD;
1857

    
1858
				if (isset ($l2tpcfg['radius']['accounting'])) {
1859
					$mpdconf .=<<<EOD
1860
	set auth enable radius-acct
1861

    
1862
EOD;
1863
				}
1864
			}
1865

    
1866
			fwrite($fd, $mpdconf);
1867
			fclose($fd);
1868
			unset($mpdconf);
1869

    
1870
			/* write mpd.links */
1871
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.links", "w");
1872
			if (!$fd) {
1873
				printf(gettext("Error: cannot open mpd.links in vpn_l2tp_configure().") . "\n");
1874
				return 1;
1875
			}
1876

    
1877
			$mpdlinks = "";
1878

    
1879
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1880
				$mpdlinks .=<<<EOD
1881

    
1882
l2tp{$i}:
1883
	set link type l2tp
1884
	set l2tp enable incoming
1885
	set l2tp disable originate
1886

    
1887
EOD;
1888
				if (!empty($l2tpcfg['secret'])) {
1889
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
1890
				}
1891
			}
1892

    
1893
			fwrite($fd, $mpdlinks);
1894
			fclose($fd);
1895
			unset($mpdlinks);
1896

    
1897
			/* write mpd.secret */
1898
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.secret", "w");
1899
			if (!$fd) {
1900
				printf(gettext("Error: cannot open mpd.secret in vpn_l2tp_configure().") . "\n");
1901
				return 1;
1902
			}
1903

    
1904
			$mpdsecret = "\n\n";
1905

    
1906
			if (is_array($l2tpcfg['user'])) {
1907
				foreach ($l2tpcfg['user'] as $user) {
1908
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1909
				}
1910
			}
1911

    
1912
			fwrite($fd, $mpdsecret);
1913
			fclose($fd);
1914
			unset($mpdsecret);
1915
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
1916

    
1917
			vpn_netgraph_support();
1918

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

    
1922
			break;
1923

    
1924
		case 'redir':
1925
			break;
1926
	}
1927

    
1928
	if (platform_booting()) {
1929
		echo "done\n";
1930
	}
1931

    
1932
	return 0;
1933
}
1934

    
1935
?>
(59-59/68)