Project

General

Profile

Download (57 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
	global $config, $ipsec_loglevels;
47

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

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

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

    
112
	return $convertion;
113
}
114

    
115
function vpn_ipsec_configure($restart = false) {
116
	global $config, $g, $sa, $sn, $p1_ealgos, $p2_ealgos, $ipsec_idhandling;
117

    
118
	if ($g['platform'] == 'jail') {
119
		return;
120
	}
121

    
122
	/* get the automatic ping_hosts.sh ready */
123
	unlink_if_exists("{$g['vardb_path']}/ipsecpinghosts");
124
	touch("{$g['vardb_path']}/ipsecpinghosts");
125

    
126
	/* service may have been enabled, disabled, or otherwise changed in a way requiring rule updates */
127
	filter_configure();
128

    
129
	$syscfg = $config['system'];
130
	$ipseccfg = $config['ipsec'];
131
	if (!isset($ipseccfg['enable'])) {
132
		/* try to stop charon */
133
		mwexec("/usr/local/sbin/ipsec stop");
134
		/* Stop dynamic monitoring */
135
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
136

    
137
		/* wait for process to die */
138
		sleep(2);
139

    
140
		/* disallow IPSEC, it is off */
141
		mwexec("/sbin/ifconfig enc0 down");
142
		set_single_sysctl("net.inet.ip.ipsec_in_use", "0");
143

    
144
		return 0;
145
	}
146

    
147
	$a_phase1 = $config['ipsec']['phase1'];
148
	$a_phase2 = $config['ipsec']['phase2'];
149
	$a_client = $config['ipsec']['client'];
150

    
151
	$certpath = "{$g['varetc_path']}/ipsec/ipsec.d/certs";
152
	$capath = "{$g['varetc_path']}/ipsec/ipsec.d/cacerts";
153
	$keypath = "{$g['varetc_path']}/ipsec/ipsec.d/private";
154

    
155
	mwexec("/sbin/ifconfig enc0 up");
156
	set_single_sysctl("net.inet.ip.ipsec_in_use", "1");
157
	if (php_uname('m') != "amd64") {
158
		set_single_sysctl("net.inet.ipsec.directdispatch", "0");
159
	}
160

    
161
	/* needed for config files */
162
	if (!is_dir("{$g['varetc_path']}/ipsec")) {
163
		mkdir("{$g['varetc_path']}/ipsec");
164
	}
165
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d")) {
166
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d");
167
	}
168
	if (!is_dir($capath)) {
169
		mkdir($capath);
170
	}
171
	if (!is_dir($keypath)) {
172
		mkdir($keypath);
173
	}
174
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/crls")) {
175
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/crls");
176
	}
177
	if (!is_dir($certpath)) {
178
		mkdir($certpath);
179
	}
180
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/aacerts")) {
181
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/aacerts");
182
	}
183
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/acerts")) {
184
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/acerts");
185
	}
186
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/ocspcerts")) {
187
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/ocspcerts");
188
	}
189
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/reqs")) {
190
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/reqs");
191
	}
192

    
193

    
194
	if (platform_booting()) {
195
		echo gettext("Configuring IPsec VPN... ");
196
	}
197

    
198
	/* fastforwarding is not compatible with ipsec tunnels */
199
	set_single_sysctl("net.inet.ip.fastforwarding", "0");
200

    
201
	/* resolve all local, peer addresses and setup pings */
202
	$ipmap = array();
203
	$rgmap = array();
204
	$filterdns_list = array();
205
	$listeniflist = array();
206
	$aggressive_mode_psk = false;
207
	unset($iflist);
208
	$ifacesuse = array();
209
	if (is_array($a_phase1) && count($a_phase1)) {
210

    
211
		$ipsecpinghosts = "";
212
		/* step through each phase1 entry */
213
		foreach ($a_phase1 as $ph1ent) {
214
			if (isset($ph1ent['disabled'])) {
215
				continue;
216
			}
217

    
218
			if (strpos($ph1ent['interface'], '_vip')) {
219
				$vpninterface = explode('_vip', $ph1ent['interface']);
220
				$ifacesuse[] = get_real_interface($vpninterface[0]);
221
			} else {
222
				$vpninterface = get_failover_interface($ph1ent['interface']);
223
				if (strpos($vpninterface, '_vip')) {
224
					$vpninterface = explode('_vip', $vpninterface);
225
					$ifacesuse[] = get_real_interface($vpninterface[0]);
226
				} elseif (!empty($vpninterface)) {
227
					$ifacesuse[] = $vpninterface;
228
				}
229
			}
230

    
231
			if ($ph1ent['mode'] == "aggressive" && ($ph1ent['authentication_method'] == "pre_shared_key" || $ph1ent['authentication_method'] == "xauth_psk_server")) {
232
				$aggressive_mode_psk = true;
233
			}
234

    
235
			$ikeid = $ph1ent['ikeid'];
236
			$listeniflist = get_real_interface($a_phase1['interface']);
237

    
238
			$ep = ipsec_get_phase1_src($ph1ent);
239
			if (!is_ipaddr($ep)) {
240
				log_error("IPsec ERROR: Could not find phase 1 source for connection {$ph1ent['descr']}. Omitting from configuration file.");
241
				continue;
242
			}
243

    
244
			if (!in_array($ep, $ipmap)) {
245
				$ipmap[] = $ep;
246
			}
247

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

    
251
			if (isset ($ph1ent['mobile'])) {
252
				continue;
253
			}
254

    
255
			$rg = $ph1ent['remote-gateway'];
256

    
257
			if (!is_ipaddr($rg)) {
258
				$filterdns_list[] = "{$rg}";
259
				add_hostname_to_watch($rg);
260
				if (!platform_booting()) {
261
					$rg = resolve_retry($rg);
262
				}
263
				if (!is_ipaddr($rg)) {
264
					continue;
265
				}
266
			}
267
			if (array_search($rg, $rgmap)) {
268
				log_error("The remote gateway {$rg} already exists on another phase 1 entry");
269
				continue;
270
			}
271
			$rgmap[$ph1ent['remote-gateway']] = $rg;
272

    
273
			if (is_array($a_phase2)) {
274
				/* step through each phase2 entry */
275
				foreach ($a_phase2 as $ph2ent) {
276
					if (isset($ph2ent['disabled'])) {
277
						continue;
278
					}
279

    
280
					if ($ikeid != $ph2ent['ikeid']) {
281
						continue;
282
					}
283

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

    
342
	$accept_unencrypted = "";
343
	if (isset($config['ipsec']['acceptunencryptedmainmode'])) {
344
		$accept_unencrypted = "accept_unencrypted_mainmode_messages = yes";
345
	}
346

    
347
	$stronconf = '';
348
	if (file_exists("{$g['varetc_path']}/ipsec/strongswan.conf")) {
349
		$stronconf = file_get_contents("{$g['varetc_path']}/ipsec/strongswan.conf");
350
	}
351

    
352
	$i_dont_care_about_security_and_use_aggressive_mode_psk = "";
353
	if ($aggressive_mode_psk) {
354
		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.");
355
		if (!empty($stronconf) && strpos($stronconf, 'i_dont_care_about_security_and_use_aggressive_mode_psk') === FALSE) {
356
			$restart = true;
357
		}
358
		$i_dont_care_about_security_and_use_aggressive_mode_psk = "i_dont_care_about_security_and_use_aggressive_mode_psk=yes";
359
	}
360

    
361
	$unity_enabled = 'yes';
362
	if (isset($config['ipsec']['unityplugin'])) {
363
		$unity_enabled = 'no';
364
		if (file_exists("/usr/local/lib/ipsec/plugins/libstrongswan-unity.so")) {
365
			conf_mount_rw();
366
			mwexec("mv /usr/local/lib/ipsec/plugins/libstrongswan-unity.so /usr/local/lib/ipsec/plugins/libstrongswan-unity.MOVED");
367
			conf_mount_ro();
368
		}
369
	} else if (file_exists("/usr/local/lib/ipsec/plugins/libstrongswan-unity.MOVED")) {
370
		conf_mount_rw();
371
		mwexec("mv /usr/local/lib/ipsec/plugins/libstrongswan-unity.MOVED /usr/local/lib/ipsec/plugins/libstrongswan-unity.so");
372
		conf_mount_ro();
373
	}
374

    
375
	$makebeforebreak = '';
376
	if (isset($config['ipsec']['makebeforebreak'])) {
377
		$makebeforebreak = 'make_before_break = yes';
378
	}
379

    
380
	if (isset($config['ipsec']['enableinterfacesuse'])) {
381
		if (!empty($ifacesuse)) {
382
			$ifacesuse = 'interfaces_use = ' . implode(',', array_unique($ifacesuse));
383
		} else {
384
			$ifacesuse = '';
385
		}
386
	} else {
387
		$ifacesuse = '';
388
	}
389

    
390
	unset($stronconf);
391

    
392
	$strongswan = <<<EOD
393

    
394
# Automatically generated config file - DO NOT MODIFY. Changes will be overwritten.
395
starter {
396
load_warning = no
397
}
398

    
399
charon {
400
# number of worker threads in charon
401
threads = 16
402
ikesa_table_size = 32
403
ikesa_table_segments = 4
404
init_limit_half_open = 1000
405
install_routes = no
406
{$i_dont_care_about_security_and_use_aggressive_mode_psk}
407
{$accept_unencrypted}
408
cisco_unity = {$unity_enabled}
409
{$ifacesuse}
410
{$makebeforebreak}
411

    
412
# And two loggers using syslog. The subsections define the facility to log
413
# to, currently one of: daemon, auth.
414
syslog {
415
	identifier = charon
416
	# default level to the LOG_DAEMON facility
417
	daemon {
418
		ike_name = yes
419
	}
420
	# very minimalistic IKE auditing logs to LOG_AUTHPRIV
421
	auth {
422
		default = -1
423
		ike = 1
424
		ike_name = yes
425
	}
426
}
427

    
428
EOD;
429

    
430
	$strongswan .= "\tplugins {\n";
431

    
432
	$a_servers = auth_get_authserver_list();
433
	foreach ($a_servers as $id => $pconfig) {
434
		if ($id == $config['ipsec']['client']['user_source'] && $pconfig['type'] == "radius") {
435
			$strongswan .= <<<EOD
436
		eap-radius {
437
			class_group = yes
438
			eap_start = no
439
			servers {
440
				primary {
441
					address = {$pconfig['host']}
442
					secret = {$pconfig['radius_secret']}
443
					auth_port = {$pconfig['radius_auth_port']}
444
					acct_port = {$pconfig['radius_acct_port']}
445
				}
446
			}
447
		}
448

    
449
EOD;
450
			break;
451
		}
452
	}
453

    
454
	if (is_array($a_client) && isset($a_client['enable'])) {
455
		$strongswan .= "\t\tattr {\n";
456
		if ($a_client['pool_address'] && $a_client['pool_netbits']) {
457
			$strongswan .= "\t\t\tsubnet = {$a_client['pool_address']}/{$a_client['pool_netbits']}\n";
458
		}
459

    
460
		$cfgservers = array();
461
		if (!empty($a_client['dns_server1'])) {
462
			$cfgservers[] = $a_client['dns_server1'];
463
		}
464
		if (!empty($a_client['dns_server2'])) {
465
			$cfgservers[] = $a_client['dns_server2'];
466
		}
467
		if (!empty($a_client['dns_server3'])) {
468
			$cfgservers[] = $a_client['dns_server3'];
469
		}
470
		if (!empty($a_client['dns_server4'])) {
471
			$cfgservers[] = $a_client['dns_server4'];
472
		}
473

    
474
		if (!empty($cfgservers)) {
475
			$strongswan .= "\t\t\tdns = " . implode(",", $cfgservers) . "\n";
476
		}
477
		unset($cfgservers);
478
		$cfgservers = array();
479
		if (!empty($a_client['wins_server1'])) {
480
			$cfgservers[] = $a_client['wins_server1'];
481
		}
482
		if (!empty($a_client['wins_server2'])) {
483
			$cfgservers[] = $a_client['wins_server2'];
484
		}
485
		if (!empty($cfgservers)) {
486
			$strongswan .= "\t\t\tnbns = " . implode(",", $cfgservers) . "\n";
487
		}
488
		unset($cfgservers);
489

    
490
		if (isset($a_client['net_list']) && is_array($a_phase2)) {
491
			$net_list = '';
492
			foreach ($a_phase2 as $ph2ent) {
493
				if (isset($ph2ent['disabled'])) {
494
					continue;
495
				}
496

    
497
				if (!isset($ph2ent['mobile'])) {
498
					continue;
499
				}
500

    
501
				$localid = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
502

    
503
				if (!empty($net_list)) {
504
					$net_list .= ",";
505
				}
506
				$net_list .= $localid;
507
			}
508

    
509
			if (!empty($net_list)) {
510
				$strongswan .= "\t\t\tsplit-include = {$net_list}\n";
511
				unset($net_list);
512
			}
513
		}
514

    
515
		if (!empty($a_client['dns_domain'])) {
516
			$strongswan .= "\t\t\t# Search domain and default domain\n";
517
			$strongswan .= "\t\t\t28674 = \"{$a_client['dns_domain']}\"\n";
518
			if (empty($a_client['dns_split'])) {
519
				$strongswan .= "\t\t\t28675 = \"{$a_client['dns_domain']}\"";
520
			}
521
			$strongswan .= "\n";
522
		}
523

    
524
		if (!empty($a_client['dns_split'])) {
525
			$strongswan .= "\t\t\t28675 = {$a_client['dns_split']}\n";
526
		}
527

    
528
		if (!empty($a_client['login_banner'])) {
529
			$strongswan .= "\t\t\t28672 = \"{$a_client['login_banner']}\"\n";
530
		}
531

    
532
		if (isset($a_client['save_passwd'])) {
533
			$strongswan .= "\t\t\t28673 = 1\n";
534
		}
535

    
536
		if ($a_client['pfs_group']) {
537
			$strongswan .= "\t\t\t28679 = \"{$a_client['pfs_group']}\"\n";
538
		}
539
		$strongswan .= "\t\t}\n";
540

    
541
		if ($a_client['user_source'] != "none") {
542
			$strongswan .= "\t\txauth-generic {\n";
543
			$strongswan .= "\t\t\tscript = /etc/inc/ipsec.auth-user.php\n";
544
			$strongswan .= "\t\t\tauthcfg = ";
545
			$firstsed = 0;
546
			$authcfgs = explode(",", $a_client['user_source']);
547
			foreach ($authcfgs as $authcfg) {
548
				if ($firstsed > 0) {
549
					$strongswan .= ",";
550
				}
551
				if ($authcfg == "system") {
552
					$authcfg = "Local Database";
553
				}
554
				$strongswan .= $authcfg;
555
				$firstsed = 1;
556
			}
557
			$strongswan .= "\n";
558
			$strongswan .= "\t\t}\n";
559
		}
560
	}
561

    
562
	$strongswan .= "\t}\n}\n";
563
	@file_put_contents("{$g['varetc_path']}/ipsec/strongswan.conf", $strongswan);
564
	unset($strongswan);
565

    
566
	/* generate CA certificates files */
567
	if (is_array($config['ca']) && count($config['ca'])) {
568
		foreach ($config['ca'] as $ca) {
569
			if (!isset($ca['crt'])) {
570
				log_error(sprintf(gettext("Error: Invalid certificate info for %s"), $ca['descr']));
571
				continue;
572
			}
573
			$cert = base64_decode($ca['crt']);
574
			$x509cert = openssl_x509_parse(openssl_x509_read($cert));
575
			if (!is_array($x509cert) || !isset($x509cert['hash'])) {
576
				log_error(sprintf(gettext("Error: Invalid certificate hash info for %s"), $ca['descr']));
577
				continue;
578
			}
579
			$fname = "{$capath}/{$x509cert['hash']}.0.crt";
580
			if (!@file_put_contents($fname, $cert)) {
581
				log_error(sprintf(gettext("Error: Cannot write IPsec CA file for %s"), $ca['descr']));
582
				continue;
583
			}
584
			unset($cert);
585
		}
586
	}
587

    
588
	$pskconf = "";
589

    
590
	if (is_array($a_phase1) && count($a_phase1)) {
591
		foreach ($a_phase1 as $ph1ent) {
592

    
593
			if (isset($ph1ent['disabled'])) {
594
				continue;
595
			}
596

    
597
			if (strstr($ph1ent['authentication_method'], 'rsa') ||
598
			    in_array($ph1ent['authentication_method'], array('eap-mschapv2', 'eap-tls', 'eap-radius'))) {
599
				$certline = '';
600

    
601
				$ikeid = $ph1ent['ikeid'];
602
				$cert = lookup_cert($ph1ent['certref']);
603

    
604
				if (!$cert) {
605
					log_error(sprintf(gettext("Error: Invalid phase1 certificate reference for %s"), $ph1ent['name']));
606
					continue;
607
				}
608

    
609
				@chmod($certpath, 0600);
610

    
611
				$ph1keyfile = "{$keypath}/cert-{$ikeid}.key";
612
				if (!file_put_contents($ph1keyfile, base64_decode($cert['prv']))) {
613
					log_error(sprintf(gettext("Error: Cannot write phase1 key file for %s"), $ph1ent['name']));
614
					continue;
615
				}
616
				@chmod($ph1keyfile, 0600);
617

    
618
				$ph1certfile = "{$certpath}/cert-{$ikeid}.crt";
619
				if (!file_put_contents($ph1certfile, base64_decode($cert['crt']))) {
620
					log_error(sprintf(gettext("Error: Cannot write phase1 certificate file for %s"), $ph1ent['name']));
621
					@unlink($ph1keyfile);
622
					continue;
623
				}
624
				@chmod($ph1certfile, 0600);
625

    
626
				/* XXX" Traffic selectors? */
627
				$pskconf .= " : RSA {$ph1keyfile}\n";
628
			} else {
629
				list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, 'local');
630
				list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, 'peer', $rgmap);
631
				
632
				$myid = trim($myid_data);
633

    
634
				if (empty($peerid_data)) {
635
					continue;
636
				}
637

    
638
				$peerid = ($peerid_data != 'allusers') ? trim($peerid_data) : '';
639
				if (!empty($ph1ent['pre-shared-key'])) {
640
					if ($myid_type == 'fqdn' && !empty($myid)) {
641
						$pskconf .= "@{$myid} {$peerid} : PSK 0s" . base64_encode(trim($ph1ent['pre-shared-key'])) . "\n";
642
					} else {
643
						$pskconf .= "{$myid} {$peerid} : PSK 0s" . base64_encode(trim($ph1ent['pre-shared-key'])) . "\n";
644
					}
645
				}
646
			}
647
		}
648
	}
649

    
650
	/* Add user PSKs */
651
	if (is_array($config['system']) && is_array($config['system']['user'])) {
652
		foreach ($config['system']['user'] as $user) {
653
			if (!empty($user['ipsecpsk'])) {
654
				$pskconf .= "{$myid} {$user['name']} : PSK 0s" . base64_encode($user['ipsecpsk']) . "\n";
655
			}
656
		}
657
		unset($user);
658
	}
659

    
660
	/* add PSKs for mobile clients */
661
	if (is_array($ipseccfg['mobilekey'])) {
662
		foreach ($ipseccfg['mobilekey'] as $key) {
663
			if ($key['ident'] == "allusers") {
664
				$key['ident'] = '%any';
665
			}
666
			if (empty($key['type'])) {
667
				$key['type'] = 'PSK';
668
			}
669
			$pskconf .= "{$myid} {$key['ident']} : {$key['type']} 0s" . base64_encode($key['pre-shared-key']) . "\n";
670
		}
671
		unset($key);
672
	}
673

    
674
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.secrets", $pskconf);
675
	chmod("{$g['varetc_path']}/ipsec/ipsec.secrets", 0600);
676
	unset($pskconf);
677

    
678
	$uniqueids = 'yes';
679
	if (!empty($config['ipsec']['uniqueids'])) {
680
		if (array_key_exists($config['ipsec']['uniqueids'], $ipsec_idhandling)) {
681
			$uniqueids = $config['ipsec']['uniqueids'];
682
		}
683
	}
684
	$natfilterrules = false;
685
	/* begin ipsec.conf */
686
	$ipsecconf = "";
687
	$enablecompression = false;
688
	if (is_array($a_phase1) && count($a_phase1)) {
689

    
690
		$ipsecconf .= "# This file is automatically generated. Do not edit\n";
691
		$ipsecconf .= "config setup\n\tuniqueids = {$uniqueids}\n";
692
		$ipsecconf .= "\tcharondebug=\"" . vpn_ipsec_configure_loglevels(true) . "\"\n";
693

    
694
		if (!isset($config['ipsec']['noshuntlaninterfaces'])) {
695
			if ($config['interfaces']['lan']) {
696
				$lanip = get_interface_ip("lan");
697
				if (!empty($lanip) && is_ipaddrv4($lanip)) {
698
					$lansn = get_interface_subnet("lan");
699
					$lansa = gen_subnet($lanip, $lansn);
700
					$ipsecconf .= <<<EOD
701

    
702
conn bypasslan
703
	leftsubnet = {$lanip}/32
704
	rightsubnet = {$lansa}/{$lansn}
705
	authby = never
706
	type = passthrough
707
	auto = route
708

    
709
EOD;
710
				}
711
			}
712
		}
713

    
714
		foreach ($a_phase1 as $ph1ent) {
715
			if (isset($ph1ent['disabled'])) {
716
				continue;
717
			}
718

    
719
			if ($ph1ent['mode'] == "aggressive") {
720
				$aggressive = "yes";
721
			} else {
722
				$aggressive = "no";
723
			}
724

    
725
			$ep = ipsec_get_phase1_src($ph1ent);
726
			if (!$ep) {
727
				continue;
728
			}
729

    
730
			$ikeid = $ph1ent['ikeid'];
731
			$keyexchange = "ikev1";
732
			$passive = "route";
733
			if (!empty($ph1ent['iketype'])) {
734
				if ($ph1ent['iketype'] == "ikev2") {
735
					$keyexchange = "ikev2";
736
					//$passive = "start";
737
				} else if ($ph1ent['iketype'] == "auto") {
738
					$keyexchange = "ike";
739
				}
740
			}
741

    
742
			if (isset($ph1ent['mobile'])) {
743
				$right_spec = "%any";
744
				$passive = 'add';
745
			} else {
746
				if (isset($ph1ent['responderonly'])) {
747
					$passive = 'add';
748
				}
749

    
750
				$right_spec = $ph1ent['remote-gateway'];
751
				if (is_ipaddr($right_spec)) {
752
					$sourcehost = $right_spec;
753
				} else {
754
					$sourcehost = $rgmap['remote-gateway'];
755
				}
756

    
757
				if ($ph1ent['protocol'] == 'inet') {
758
					if (strpos($ph1ent['interface'], '_vip')) {
759
						$vpninterface = explode('_vip', $ph1ent['interface']);
760
						$ifacesuse = get_real_interface($vpninterface[0]);
761
						$vpninterface = $vpninterface[0];
762
					} else {
763
						$ifacesuse = get_failover_interface($ph1ent['interface']);
764
						if (strpos($ifacesuse, '_vip')) {
765
							$vpninterface = explode('_vip', $ifacesuse);
766
							$ifacesuse = get_real_interface($vpninterface[0]);
767
							$vpninterface = $vpninterface[0];
768
						} else {
769
							$vpninterface = convert_real_interface_to_friendly_interface_name($ifacesuse);
770
						}
771
					}
772

    
773
					if (!empty($ifacesuse) && interface_has_gateway($vpninterface)) {
774
						$gatewayip = get_interface_gateway($vpninterface);
775
						$interfaceip = get_interface_ip($vpninterface);
776
						$subnet_bits = get_interface_subnet($vpninterface);
777
						$subnet_ip = gen_subnetv4($interfaceip, $subnet_bits);
778
						/* if the remote gateway is in the local subnet, then don't add a route */
779
						if (!ip_in_subnet($sourcehost, "{$subnet_ip}/{$subnet_bits}")) {
780
							if (is_ipaddrv4($gatewayip)) {
781
								// log_error("IPSEC interface is not WAN but {$ifacesuse}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
782
								mwexec("/sbin/route change -host {$sourcehost} {$gatewayip}", true);
783
							}
784
						}
785
					}
786
				} else if ($ph1ent['protocol'] == 'inet6') {
787
					if (strpos($ph1ent['interface'], '_vip')) {
788
						$vpninterface = explode('_vip', $ph1ent['interface']);
789
						$ifacesuse = get_real_interface($vpninterface[0]);
790
						$vpninterface = $vpninterface[0];
791
					} else {
792
						$ifacesuse = get_failover_interface($ph1ent['interface']);
793
						if (strpos($ifacesuse, '_vip')) {
794
							$vpninterface = explode('_vip', $ifacesuse);
795
							$ifacesuse = get_real_interface($vpninterface[0]);
796
							$vpninterface = $vpninterface[0];
797
						} else {
798
							$vpninterface = convert_real_interface_to_friendly_interface_name($ifacesuse);
799
						}
800
					}
801

    
802
					if (!empty($ifacesuse) && interface_has_gateway($vpninterface)) {
803
						$gatewayip = get_interface_gateway_v6($vpninterface);
804
						$interfaceip = get_interface_ipv6($vpninterface);
805
						$subnet_bits = get_interface_subnetv6($vpninterface);
806
						$subnet_ip = gen_subnetv6($interfaceip, $subnet_bits);
807
						/* if the remote gateway is in the local subnet, then don't add a route */
808
						if (!ip_in_subnet($sourcehost, "{$subnet_ip}/{$subnet_bits}")) {
809
							if (is_ipaddrv6($gatewayip)) {
810
								// log_error("IPSEC interface is not WAN but {$ifacesuse}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
811
								mwexec("/sbin/route change -inet6 -host {$sourcehost} {$gatewayip}", true);
812
							}
813
						}
814
					}
815
				}
816
			}
817

    
818
			list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, 'local');
819
			if ($myid_type != 'address') {
820
				$myid_data = "{$myid_type}:{$myid_data}";
821
			}
822

    
823
			/* Only specify peer ID if we are not dealing with a mobile PSK-only tunnel */
824
			$peerid_spec = '';
825
			if (!isset($ph1ent['mobile'])) {
826
				list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, 'peer', $rgmap);
827
				if ($peerid_type != 'address') {
828
					$peerid_spec = "{$peerid_type}:{$peerid_data}";
829
				} else {
830
					$peerid_spec = $peerid_data;
831
				}
832
			}
833

    
834
			if (is_array($ph1ent['encryption-algorithm']) && !empty($ph1ent['encryption-algorithm']['name']) && !empty($ph1ent['hash-algorithm'])) {
835
				$ealgosp1 = '';
836
				$ealg_id = $ph1ent['encryption-algorithm']['name'];
837
				$ealg_kl = $ph1ent['encryption-algorithm']['keylen'];
838
				if ($ealg_kl) {
839
					$ealgosp1 = "ike = {$ealg_id}{$ealg_kl}-{$ph1ent['hash-algorithm']}";
840
				} else {
841
					$ealgosp1 = "ike = {$ealg_id}-{$ph1ent['hash-algorithm']}";
842
				}
843

    
844
				$modp = vpn_ipsec_convert_to_modp($ph1ent['dhgroup']);
845
				if (!empty($modp)) {
846
					$ealgosp1 .= "-{$modp}";
847
				}
848

    
849
				$ealgosp1 .= "!";
850
			}
851

    
852
			if ($ph1ent['dpd_delay'] && $ph1ent['dpd_maxfail']) {
853
				if ($passive == "route") {
854
					$dpdline = "dpdaction = restart";
855
				} else {
856
					$dpdline = "dpdaction = clear";
857
				}
858
				$dpdline .= "\n\tdpddelay = {$ph1ent['dpd_delay']}s";
859
				$dpdtimeout = $ph1ent['dpd_delay'] * ($ph1ent['dpd_maxfail'] + 1);
860
				$dpdline .= "\n\tdpdtimeout = {$dpdtimeout}s";
861
			} else {
862
				$dpdline = "dpdaction = none";
863
			}
864

    
865
			$ikelifeline = '';
866
			if ($ph1ent['lifetime']) {
867
				$ikelifeline = "ikelifetime = {$ph1ent['lifetime']}s";
868
			}
869

    
870
			$rightsourceip = NULL;
871
			if (isset($ph1ent['mobile']) && !empty($a_client['pool_address'])) {
872
				$rightsourceip = "\trightsourceip = {$a_client['pool_address']}/{$a_client['pool_netbits']}\n";
873
			}
874

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

    
943
			$left_spec = $ep;
944

    
945
			if (isset($ph1ent['reauth_enable'])) {
946
				$reauth = "reauth = no";
947
			} else {
948
				$reauth = "reauth = yes";
949
			}
950
			if (isset($ph1ent['rekey_enable'])) {
951
				$rekey = "rekey = no";
952
			} else {
953
				$rekey = "rekey = yes";
954
			}
955

    
956
			if ($ph1ent['nat_traversal'] == 'off') {
957
				$forceencaps = 'forceencaps = no';
958
			} else if ($ph1ent['nat_traversal'] == 'force') {
959
				$forceencaps = 'forceencaps = yes';
960
			} else {
961
				$forceencaps = 'forceencaps = no';
962
			}
963

    
964
			if ($ph1ent['mobike'] == 'on') {
965
				$mobike = 'mobike = yes';
966
			} else {
967
				$mobike = 'mobike = no';
968
			}
969

    
970
			$ipseclifetime = 0;
971
			$rightsubnet_spec = array();
972
			$leftsubnet_spec = array();
973
			$reqids = array();
974
			$ealgoAHsp2arr = array();
975
			$ealgoESPsp2arr = array();
976
		if (is_array($a_phase2) && count($a_phase2)) {
977
			foreach ($a_phase2 as $ph2ent) {
978
				if ($ikeid != $ph2ent['ikeid']) {
979
					continue;
980
				}
981

    
982
				if (isset($ph2ent['disabled'])) {
983
					continue;
984
				}
985

    
986
				if (isset($ph2ent['mobile']) && !isset($a_client['enable'])) {
987
					continue;
988
				}
989

    
990
				if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
991
					$tunneltype = "type = tunnel";
992

    
993
					$localid_type = $ph2ent['localid']['type'];
994
					$leftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['localid'], false, $ph2ent['mode']);
995

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

    
1024
					$leftsubnet_spec[] = $leftsubnet_data;
1025

    
1026
					if (!isset($ph2ent['mobile'])) {
1027
						$tmpsubnet = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']);
1028
						$rightsubnet_spec[] = $tmpsubnet;
1029
					} else if (!empty($a_client['pool_address'])) {
1030
						$rightsubnet_spec[] = "{$a_client['pool_address']}/{$a_client['pool_netbits']}";
1031
					}
1032
				} else {
1033
					$tunneltype = "type = transport";
1034

    
1035
					if ((($ph1ent['authentication_method'] == "xauth_psk_server") ||
1036
					    ($ph1ent['authentication_method'] == "pre_shared_key")) && isset($ph1ent['mobile'])) {
1037
						$left_spec = "%any";
1038
					} else {
1039
						$tmpsubnet = ipsec_get_phase1_src($ph1ent);
1040
						$leftsubnet_spec[] = $tmpsubnet;
1041
					}
1042

    
1043
					if (!isset($ph2ent['mobile'])) {
1044
						$rightsubnet_spec[] = $right_spec;
1045
					}
1046
				}
1047

    
1048
				if (isset($a_client['pfs_group']) && isset($ph2ent['mobile'])) {
1049
					$ph2ent['pfsgroup'] = $a_client['pfs_group'];
1050
				}
1051

    
1052
				if ($ph2ent['protocol'] == 'esp') {
1053
					if (is_array($ph2ent['encryption-algorithm-option'])) {
1054
						foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
1055
							$ealg_id = $ealg['name'];
1056
							$ealg_kl = $ealg['keylen'];
1057

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

    
1125
				$reqids[] = $ph2ent['reqid'];
1126

    
1127
				if (!empty($ph2ent['lifetime'])) {
1128
					if ($ipseclifetime == 0 || intval($ipseclifetime) > intval($ph2ent['lifetime'])) {
1129
						$ipseclifetime = intval($ph2ent['lifetime']);
1130
					}
1131
				}
1132

    
1133
			}
1134
		}
1135

    
1136
			$ipsecconnect =<<<EOD
1137
	fragmentation = yes
1138
	keyexchange = {$keyexchange}
1139
	{$reauth}
1140
	{$forceencaps}
1141
	{$mobike}
1142
	{$rekey}
1143
	installpolicy = yes
1144
	{$tunneltype}
1145
	{$dpdline}
1146
	auto = {$passive}
1147
	left = {$left_spec}
1148
	right = {$right_spec}
1149
	leftid = {$myid_data}
1150

    
1151
EOD;
1152

    
1153
			if (isset($config['ipsec']['compression'])) {
1154
				$ipsecconnect .= "\tcompress = yes\n";
1155
				$enablecompression = true;
1156
			}
1157
			if (!empty($ikelifeline)) {
1158
				$ipsecconnect .= "\t{$ikelifeline}\n";
1159
			}
1160
			if ($ipseclifetime > 0) {
1161
				$ipsecconnect .= "\tlifetime = {$ipseclifetime}s\n";
1162
			}
1163
			if (!empty($rightsourceip)) {
1164
				$ipsecconnect .= "{$rightsourceip}";
1165
			}
1166
			if (!empty($ealgosp1)) {
1167
				$ipsecconnect .= "\t{$ealgosp1}\n";
1168
			}
1169
			if (!empty($ealgoAHsp2arr)) {
1170
				$ipsecconnect .= "\tah = " . join(',', $ealgoAHsp2arr) . "!\n";
1171
			}
1172
			if (!empty($ealgoESPsp2arr)) {
1173
				$ipsecconnect .= "\tesp = " . join(',', $ealgoESPsp2arr) . "!\n";
1174
			}
1175
			if (!empty($authentication)) {
1176
				$ipsecconnect .= "\t{$authentication}\n";
1177
			}
1178
			if (!empty($peerid_spec)) {
1179
				$ipsecconnect .= "\trightid = {$peerid_spec}\n";
1180
			}
1181
			if ($keyexchange == 'ikev1') {
1182
				$ipsecconnect .= "\taggressive = {$aggressive}\n";
1183
			}
1184

    
1185
			if (!isset($ph1ent['mobile']) && $keyexchange == 'ikev1') {
1186
				if (!empty($rightsubnet_spec)) {
1187
					$ipsecfin = '';
1188
					foreach ($rightsubnet_spec as $idx => $rsubnet) {
1189
						$ipsecfin .= "\nconn con{$ph1ent['ikeid']}00{$idx}\n";
1190
						//if (!empty($reqids[$idx])) {
1191
						//	$ipsecfin .= "\treqid = " . $reqids[$idx] . "\n";
1192
						//}
1193
						$ipsecfin .= $ipsecconnect;
1194
						$ipsecfin .= "\trightsubnet = {$rsubnet}\n";
1195
						$ipsecfin .= "\tleftsubnet = " . $leftsubnet_spec[$idx] . "\n";
1196
					}
1197
				} else {
1198
					log_error("No phase2 specifications for tunnel with REQID = {$ikeid}");
1199
				}
1200
			} else {
1201
				$ipsecfin = "\nconn con{$ph1ent['ikeid']}\n";
1202
				//if (!empty($reqids[$idx])) {
1203
				//	$ipsecfin .= "\treqid = " . $reqids[0] . "\n";
1204
				//}
1205
				$ipsecfin .= $ipsecconnect;
1206
				if (!isset($ph1ent['mobile']) && !empty($rightsubnet_spec)) {
1207
					$tempsubnets = array();
1208
					foreach ($rightsubnet_spec as $rightsubnet) {
1209
						$tempsubnets[$rightsubnet] = $rightsubnet;
1210
					}
1211
					$ipsecfin .= "\trightsubnet = " . join(",", $tempsubnets) . "\n";
1212
					unset($tempsubnets, $rightsubnet);
1213
				}
1214
				if (!empty($leftsubnet_spec)) {
1215
					$tempsubnets = array();
1216
					foreach ($leftsubnet_spec as $leftsubnet) {
1217
						$tempsubnets[$leftsubnet] = $leftsubnet;
1218
					}
1219
					$ipsecfin .= "\tleftsubnet = " . join(",", $tempsubnets) . "\n";
1220
					unset($tempsubnets, $leftsubnet);
1221
				}
1222
			}
1223
			$ipsecconf .= $ipsecfin;
1224
			unset($ipsecfin);
1225
		}
1226
	}
1227

    
1228
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.conf", $ipsecconf);
1229
	unset($ipsecconf);
1230
	/* end ipsec.conf */
1231

    
1232
	if ($enablecompression === true) {
1233
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 1);
1234
	} else {
1235
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 0);
1236
	}
1237

    
1238
	/* manage process */
1239
	if ($restart === true) {
1240
		mwexec("/usr/local/sbin/ipsec restart", false);
1241
	} else {
1242
		if (isvalidpid("{$g['varrun_path']}/starter.charon.pid")) {
1243
			/* Update configuration changes */
1244
			/* Read secrets */
1245
			sigkillbypid("{$g['varrun_path']}/starter.charon.pid", 'USR1');
1246
		} else {
1247
			mwexec("/usr/local/sbin/ipsec start", false);
1248
		}
1249
	}
1250

    
1251
	if ($natfilterrules == true) {
1252
		filter_configure();
1253
	}
1254
	/* start filterdns, if necessary */
1255
	if (count($filterdns_list) > 0) {
1256
		$interval = 60;
1257
		if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval'])) {
1258
			$interval = $ipseccfg['dns-interval'];
1259
		}
1260

    
1261
		$hostnames = "";
1262
		array_unique($filterdns_list);
1263
		foreach ($filterdns_list as $hostname) {
1264
			$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload ipsecdns\"'\n";
1265
		}
1266
		file_put_contents("{$g['varetc_path']}/ipsec/filterdns-ipsec.hosts", $hostnames);
1267
		unset($hostnames);
1268

    
1269
		if (isvalidpid("{$g['varrun_path']}/filterdns-ipsec.pid")) {
1270
			sigkillbypid("{$g['varrun_path']}/filterdns-ipsec.pid", "HUP");
1271
		} else {
1272
			mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/ipsec/filterdns-ipsec.hosts -d 1");
1273
		}
1274
	} else {
1275
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
1276
		@unlink("{$g['varrun_path']}/filterdns-ipsec.pid");
1277
	}
1278

    
1279
	if (platform_booting()) {
1280
		echo "done\n";
1281
	}
1282

    
1283
	return count($filterdns_list);
1284
}
1285

    
1286
/*
1287
 * Forcefully restart IPsec
1288
 * This is required for when dynamic interfaces reload
1289
 * For all other occasions the normal vpn_ipsec_configure()
1290
 * will gracefully reload the settings without restarting
1291
 */
1292
function vpn_ipsec_force_reload($interface = "") {
1293
	global $g, $config;
1294

    
1295
	$ipseccfg = $config['ipsec'];
1296

    
1297
	if (!empty($interface) && is_array($ipseccfg['phase1'])) {
1298
		$found = false;
1299
		foreach ($ipseccfg['phase1'] as $ipsec) {
1300
			if (!isset($ipsec['disabled']) && ($ipsec['interface'] == $interface)) {
1301
				$found = true;
1302
				break;
1303
			}
1304
		}
1305
		if (!$found) {
1306
			log_error(sprintf(gettext("Ignoring IPsec reload since there are no tunnels on interface %s"), $interface));
1307
			return;
1308
		}
1309
	}
1310

    
1311
	/* if ipsec is enabled, start up again */
1312
	if (isset($ipseccfg['enable'])) {
1313
		log_error(gettext("Forcefully reloading IPsec"));
1314
		vpn_ipsec_configure();
1315
	}
1316
}
1317

    
1318
/* master setup for vpn (mpd) */
1319
function vpn_setup() {
1320
	global $g;
1321

    
1322
	if ($g['platform'] == 'jail') {
1323
		return;
1324
	}
1325

    
1326
	/* start pptpd */
1327
	vpn_pptpd_configure();
1328

    
1329
	/* start pppoe server */
1330
	vpn_pppoes_configure();
1331

    
1332
	/* setup l2tp */
1333
	vpn_l2tp_configure();
1334
}
1335

    
1336
function vpn_netgraph_support() {
1337
	$iflist = get_configured_interface_list();
1338
	foreach ($iflist as $iface) {
1339
		$realif = get_real_interface($iface);
1340
		/* Get support for netgraph(4) from the nic */
1341
		$ifinfo = pfSense_get_interface_addresses($realif);
1342
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge"))) {
1343
			pfSense_ngctl_attach(".", $realif);
1344
		}
1345
	}
1346
}
1347

    
1348
function vpn_pptpd_configure() {
1349
	global $config, $g;
1350

    
1351
	$syscfg = $config['system'];
1352
	$pptpdcfg = $config['pptpd'];
1353

    
1354
	if (platform_booting()) {
1355
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off")) {
1356
			return 0;
1357
		}
1358

    
1359
		if (platform_booting(true)) {
1360
			echo gettext("Configuring PPTP VPN service... ");
1361
		}
1362
	} else {
1363
		/* kill mpd */
1364
		killbypid("{$g['varrun_path']}/pptp-vpn.pid");
1365

    
1366
		/* wait for process to die */
1367
		sleep(3);
1368

    
1369
		if (is_process_running("mpd -b")) {
1370
			killbypid("{$g['varrun_path']}/pptp-vpn.pid");
1371
			log_error(gettext("Could not kill mpd within 3 seconds.   Trying again."));
1372
		}
1373

    
1374
		/* remove mpd.conf, if it exists */
1375
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.conf");
1376
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.links");
1377
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.secret");
1378
	}
1379

    
1380
	if (empty($pptpdcfg['n_pptp_units'])) {
1381
		log_error("Something wrong in the PPTPd configuration. Preventing starting the daemon because issues would arise.");
1382
		return;
1383
	}
1384

    
1385
	/* make sure pptp-vpn directory exists */
1386
	if (!file_exists("{$g['varetc_path']}/pptp-vpn")) {
1387
		mkdir("{$g['varetc_path']}/pptp-vpn");
1388
	}
1389

    
1390
	switch ($pptpdcfg['mode']) {
1391
		case 'server':
1392
			/* write mpd.conf */
1393
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.conf", "w");
1394
			if (!$fd) {
1395
				printf(gettext("Error: cannot open mpd.conf in vpn_pptpd_configure().") . "\n");
1396
				return 1;
1397
			}
1398

    
1399
			$mpdconf = <<<EOD
1400
pptps:
1401

    
1402
EOD;
1403

    
1404
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1405
				$mpdconf .= "	load pt{$i}\n";
1406
			}
1407

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

    
1410
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
1411

    
1412
				$mpdconf .= <<<EOD
1413

    
1414
pt{$i}:
1415
	new -i pptpd{$i} pt{$i} pt{$i}
1416
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
1417
	load pts
1418

    
1419
EOD;
1420
			}
1421

    
1422
			$mpdconf .=<<<EOD
1423

    
1424
pts:
1425
	set iface disable on-demand
1426
	set iface enable proxy-arp
1427
	set iface enable tcpmssfix
1428
	set iface idle 1800
1429
	set iface up-script /usr/local/sbin/vpn-linkup
1430
	set iface down-script /usr/local/sbin/vpn-linkdown
1431
	set bundle enable multilink
1432
	set bundle enable crypt-reqd
1433
	set link yes acfcomp protocomp
1434
	set link no pap chap
1435
	set link enable chap-msv2
1436
	set link mtu 1460
1437
	set link keep-alive 10 60
1438
	set ipcp yes vjcomp
1439
	set bundle enable compression
1440
	set ccp yes mppc
1441
	set ccp yes mpp-e128
1442
	set ccp yes mpp-stateless
1443

    
1444
EOD;
1445

    
1446
			if (!isset ($pptpdcfg['req128'])) {
1447
				$mpdconf .=<<<EOD
1448
	set ccp yes mpp-e40
1449
	set ccp yes mpp-e56
1450

    
1451
EOD;
1452
			}
1453

    
1454
			if (isset($pptpdcfg["wins"]) && $pptpdcfg['wins'] != "") {
1455
				$mpdconf .= "	set ipcp nbns {$pptpdcfg['wins']}\n";
1456
			}
1457

    
1458
			if (!empty($pptpdcfg['dns1'])) {
1459
				$mpdconf .= "	set ipcp dns " . $pptpdcfg['dns1'];
1460
				if (!empty($pptpdcfg['dns2'])) {
1461
					$mpdconf .= " " . $pptpdcfg['dns2'];
1462
				}
1463
				$mpdconf .= "\n";
1464
			} elseif (isset ($config['dnsmasq']['enable'])) {
1465
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1466
				if ($syscfg['dnsserver'][0]) {
1467
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1468
				}
1469
				$mpdconf .= "\n";
1470
			} elseif (isset($config['unbound']['enable'])) {
1471
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1472
				if ($syscfg['dnsserver'][0]) {
1473
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1474
				}
1475
				$mpdconf .= "\n";
1476
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1477
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1478
			}
1479

    
1480
			if (isset ($pptpdcfg['radius']['server']['enable'])) {
1481
				$authport = (isset($pptpdcfg['radius']['server']['port']) && strlen($pptpdcfg['radius']['server']['port']) > 1) ? $pptpdcfg['radius']['server']['port'] : 1812;
1482
				$acctport = $authport + 1;
1483
				$mpdconf .=<<<EOD
1484
	set radius server {$pptpdcfg['radius']['server']['ip']} "{$pptpdcfg['radius']['server']['secret']}" {$authport} {$acctport}
1485

    
1486
EOD;
1487
				if (isset ($pptpdcfg['radius']['server2']['enable'])) {
1488
					$authport = (isset($pptpdcfg['radius']['server2']['port']) && strlen($pptpdcfg['radius']['server2']['port']) > 1) ? $pptpdcfg['radius']['server2']['port'] : 1812;
1489
					$acctport = $authport + 1;
1490
					$mpdconf .=<<<EOD
1491
	set radius server {$pptpdcfg['radius']['server2']['ip']} "{$pptpdcfg['radius']['server2']['secret2']}" {$authport} {$acctport}
1492

    
1493
EOD;
1494
				}
1495
				$mpdconf .=<<<EOD
1496
	set radius retries 3
1497
	set radius timeout 10
1498
	set auth enable radius-auth
1499

    
1500
EOD;
1501

    
1502
				if (isset ($pptpdcfg['radius']['accounting'])) {
1503
					$mpdconf .=<<<EOD
1504
	set auth enable radius-acct
1505
	set radius acct-update 300
1506

    
1507
EOD;
1508
				}
1509
			}
1510

    
1511
			fwrite($fd, $mpdconf);
1512
			fclose($fd);
1513
			unset($mpdconf);
1514

    
1515
			/* write mpd.links */
1516
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.links", "w");
1517
			if (!$fd) {
1518
				printf(gettext("Error: cannot open mpd.links in vpn_pptpd_configure().") . "\n");
1519
				return 1;
1520
			}
1521

    
1522
			$mpdlinks = "";
1523

    
1524
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1525
				$mpdlinks .=<<<EOD
1526

    
1527
pt{$i}:
1528
	set link type pptp
1529
	set pptp enable incoming
1530
	set pptp disable originate
1531
	set pptp disable windowing
1532

    
1533
EOD;
1534
			}
1535

    
1536
			fwrite($fd, $mpdlinks);
1537
			fclose($fd);
1538
			unset($mpdlinks);
1539

    
1540
			/* write mpd.secret */
1541
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.secret", "w");
1542
			if (!$fd) {
1543
				printf(gettext("Error: cannot open mpd.secret in vpn_pptpd_configure().") . "\n");
1544
				return 1;
1545
			}
1546

    
1547
			$mpdsecret = "";
1548

    
1549
			if (is_array($pptpdcfg['user'])) {
1550
				foreach ($pptpdcfg['user'] as $user) {
1551
					$pass = str_replace('\\', '\\\\', $user['password']);
1552
					$pass = str_replace('"', '\"', $pass);
1553
					$mpdsecret .= "{$user['name']} \"{$pass}\" {$user['ip']}\n";
1554
				}
1555
			}
1556

    
1557
			fwrite($fd, $mpdsecret);
1558
			fclose($fd);
1559
			unset($mpdsecret);
1560
			chmod("{$g['varetc_path']}/pptp-vpn/mpd.secret", 0600);
1561

    
1562
			vpn_netgraph_support();
1563

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

    
1567
			break;
1568

    
1569
		case 'redir':
1570
			break;
1571
	}
1572

    
1573
	if (platform_booting()) {
1574
		echo "done\n";
1575
	}
1576

    
1577
	return 0;
1578
}
1579

    
1580
function vpn_pppoes_configure() {
1581
	global $config;
1582

    
1583
	if (is_array($config['pppoes']['pppoe'])) {
1584
		foreach ($config['pppoes']['pppoe'] as $pppoe) {
1585
			vpn_pppoe_configure($pppoe);
1586
		}
1587
	}
1588
}
1589

    
1590
function vpn_pppoe_configure(&$pppoecfg) {
1591
	global $config, $g;
1592

    
1593
	$syscfg = $config['system'];
1594

    
1595
	/* create directory if it does not exist */
1596
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn")) {
1597
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1598
	}
1599

    
1600
	if (platform_booting()) {
1601
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off")) {
1602
			return 0;
1603
		}
1604

    
1605
		echo gettext("Configuring PPPoE Server service... ");
1606
	} else {
1607
		/* kill mpd */
1608
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1609

    
1610
		/* wait for process to die */
1611
		sleep(2);
1612

    
1613
	}
1614

    
1615
	switch ($pppoecfg['mode']) {
1616

    
1617
		case 'server':
1618

    
1619
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1620

    
1621
			if ($pppoecfg['paporchap'] == "chap") {
1622
				$paporchap = "set link enable chap";
1623
			} else {
1624
				$paporchap = "set link enable pap";
1625
			}
1626

    
1627
			/* write mpd.conf */
1628
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1629
			if (!$fd) {
1630
				printf(gettext("Error: cannot open mpd.conf in vpn_pppoe_configure().") . "\n");
1631
				return 1;
1632
			}
1633
			$mpdconf = "\n\n";
1634
			$mpdconf .= "poes:\n";
1635

    
1636
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1637
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1638
			}
1639

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

    
1642
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1643

    
1644
				if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1645
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1646
				} else {
1647
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1648
				}
1649

    
1650
				$mpdconf .=<<<EOD
1651

    
1652
poes{$pppoecfg['pppoeid']}{$i}:
1653
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1654
	{$isssue_ip_type}
1655
	load pppoe_standard
1656

    
1657
EOD;
1658
			}
1659

    
1660
			$mpdconf .=<<<EOD
1661

    
1662
pppoe_standard:
1663
	set bundle no multilink
1664
	set bundle enable compression
1665
	set auth max-logins 1
1666
	set iface up-script /usr/local/sbin/vpn-linkup
1667
	set iface down-script /usr/local/sbin/vpn-linkdown
1668
	set iface idle 0
1669
	set iface disable on-demand
1670
	set iface disable proxy-arp
1671
	set iface enable tcpmssfix
1672
	set iface mtu 1500
1673
	set link no pap chap
1674
	{$paporchap}
1675
	set link keep-alive 60 180
1676
	set ipcp yes vjcomp
1677
	set ipcp no vjcomp
1678
	set link max-redial -1
1679
	set link mtu 1492
1680
	set link mru 1492
1681
	set ccp yes mpp-e40
1682
	set ccp yes mpp-e128
1683
	set ccp yes mpp-stateless
1684
	set link latency 1
1685
	#set ipcp dns 10.10.1.3
1686
	#set bundle accept encryption
1687

    
1688
EOD;
1689

    
1690
			if (!empty($pppoecfg['dns1'])) {
1691
				$mpdconf .= "	set ipcp dns " . $pppoecfg['dns1'];
1692
				if (!empty($pppoecfg['dns2'])) {
1693
					$mpdconf .= " " . $pppoecfg['dns2'];
1694
				}
1695
				$mpdconf .= "\n";
1696
			} elseif (isset ($config['dnsmasq']['enable'])) {
1697
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1698
				if ($syscfg['dnsserver'][0]) {
1699
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1700
				}
1701
				$mpdconf .= "\n";
1702
			} elseif (isset ($config['unbound']['enable'])) {
1703
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1704
				if ($syscfg['dnsserver'][0]) {
1705
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1706
				}
1707
				$mpdconf .= "\n";
1708
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1709
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1710
			}
1711

    
1712
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1713
				$radiusport = "";
1714
				$radiusacctport = "";
1715
				if (isset($pppoecfg['radius']['server']['port'])) {
1716
					$radiusport = $pppoecfg['radius']['server']['port'];
1717
				}
1718
				if (isset($pppoecfg['radius']['server']['acctport'])) {
1719
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1720
				}
1721
				$mpdconf .=<<<EOD
1722
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
1723
	set radius retries 3
1724
	set radius timeout 10
1725
	set auth enable radius-auth
1726

    
1727
EOD;
1728

    
1729
				if (isset ($pppoecfg['radius']['accounting'])) {
1730
					$mpdconf .=<<<EOD
1731
	set auth enable radius-acct
1732

    
1733
EOD;
1734
				}
1735
			}
1736

    
1737
			fwrite($fd, $mpdconf);
1738
			fclose($fd);
1739
			unset($mpdconf);
1740

    
1741
			/* write mpd.links */
1742
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.links", "w");
1743
			if (!$fd) {
1744
				printf(gettext("Error: cannot open mpd.links in vpn_pppoe_configure().") . "\n");
1745
				return 1;
1746
			}
1747

    
1748
			$mpdlinks = "";
1749

    
1750
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1751
				$mpdlinks .=<<<EOD
1752

    
1753
poes{$pppoecfg['pppoeid']}{$i}:
1754
	set phys type pppoe
1755
	set pppoe iface {$pppoe_interface}
1756
	set pppoe service "*"
1757
	set pppoe disable originate
1758
	set pppoe enable incoming
1759

    
1760
EOD;
1761
			}
1762

    
1763
			fwrite($fd, $mpdlinks);
1764
			fclose($fd);
1765
			unset($mpdlinks);
1766

    
1767
			if ($pppoecfg['username']) {
1768
				/* write mpd.secret */
1769
				$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
1770
				if (!$fd) {
1771
					printf(gettext("Error: cannot open mpd.secret in vpn_pppoe_configure().") . "\n");
1772
					return 1;
1773
				}
1774

    
1775
				$mpdsecret = "\n\n";
1776

    
1777
				if (!empty($pppoecfg['username'])) {
1778
					$item = explode(" ", $pppoecfg['username']);
1779
					foreach ($item as $userdata) {
1780
						$data = explode(":", $userdata);
1781
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1782
					}
1783
				}
1784

    
1785
				fwrite($fd, $mpdsecret);
1786
				fclose($fd);
1787
				unset($mpdsecret);
1788
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1789
			}
1790

    
1791
			/* Check if previous instance is still up */
1792
			while (file_exists("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid") && isvalidpid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid")) {
1793
				killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1794
			}
1795

    
1796
			/* Get support for netgraph(4) from the nic */
1797
			pfSense_ngctl_attach(".", $pppoe_interface);
1798
			/* fire up mpd */
1799
			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");
1800

    
1801
			break;
1802
	}
1803

    
1804
	if (platform_booting()) {
1805
		echo gettext("done") . "\n";
1806
	}
1807

    
1808
	return 0;
1809
}
1810

    
1811
function vpn_l2tp_configure() {
1812
	global $config, $g;
1813

    
1814
	$syscfg = $config['system'];
1815
	$l2tpcfg = $config['l2tp'];
1816

    
1817
	/* create directory if it does not exist */
1818
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn")) {
1819
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1820
	}
1821

    
1822
	if (platform_booting()) {
1823
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off")) {
1824
			return 0;
1825
		}
1826

    
1827
		echo gettext("Configuring l2tp VPN service... ");
1828
	} else {
1829
		/* kill mpd */
1830
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1831

    
1832
		/* wait for process to die */
1833
		sleep(8);
1834

    
1835
	}
1836

    
1837
	/* make sure l2tp-vpn directory exists */
1838
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn")) {
1839
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1840
	}
1841

    
1842
	switch ($l2tpcfg['mode']) {
1843

    
1844
		case 'server':
1845
			if ($l2tpcfg['paporchap'] == "chap") {
1846
				$paporchap = "set link enable chap";
1847
			} else {
1848
				$paporchap = "set link enable pap";
1849
			}
1850

    
1851
			/* write mpd.conf */
1852
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1853
			if (!$fd) {
1854
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
1855
				return 1;
1856
			}
1857
			$mpdconf = "\n\n";
1858
			$mpdconf .=<<<EOD
1859
l2tps:
1860

    
1861
EOD;
1862

    
1863
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1864
				$mpdconf .= "	load l2tp{$i}\n";
1865
			}
1866

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

    
1869
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1870

    
1871
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1872
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1873
				} else {
1874
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1875
				}
1876

    
1877
				$mpdconf .=<<<EOD
1878

    
1879
l2tp{$i}:
1880
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1881
	{$isssue_ip_type}
1882
	load l2tp_standard
1883

    
1884
EOD;
1885
			}
1886

    
1887
			$mpdconf .=<<<EOD
1888

    
1889
l2tp_standard:
1890
	set bundle disable multilink
1891
	set bundle enable compression
1892
	set bundle yes crypt-reqd
1893
	set ipcp yes vjcomp
1894
	# set ipcp ranges 131.188.69.161/32 131.188.69.170/28
1895
	set ccp yes mppc
1896
	set iface disable on-demand
1897
	set iface enable proxy-arp
1898
	set iface up-script /usr/local/sbin/vpn-linkup
1899
	set iface down-script /usr/local/sbin/vpn-linkdown
1900
	set link yes acfcomp protocomp
1901
	set link no pap chap
1902
	{$paporchap}
1903
	set link keep-alive 10 180
1904

    
1905
EOD;
1906

    
1907
			if (is_ipaddr($l2tpcfg['wins'])) {
1908
				$mpdconf .= "	set ipcp nbns {$l2tpcfg['wins']}\n";
1909
			}
1910
			if (is_ipaddr($l2tpcfg['dns1'])) {
1911
				$mpdconf .= "	set ipcp dns " . $l2tpcfg['dns1'];
1912
				if (is_ipaddr($l2tpcfg['dns2'])) {
1913
					$mpdconf .= " " . $l2tpcfg['dns2'];
1914
				}
1915
				$mpdconf .= "\n";
1916
			} elseif (isset ($config['dnsmasq']['enable'])) {
1917
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1918
				if ($syscfg['dnsserver'][0]) {
1919
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1920
				}
1921
				$mpdconf .= "\n";
1922
			} elseif (isset ($config['unbound']['enable'])) {
1923
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1924
				if ($syscfg['dnsserver'][0]) {
1925
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1926
				}
1927
				$mpdconf .= "\n";
1928
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1929
				$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1930
			}
1931

    
1932
			if (isset ($l2tpcfg['radius']['enable'])) {
1933
				$mpdconf .=<<<EOD
1934
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1935
	set radius retries 3
1936
	set radius timeout 10
1937
	set auth enable radius-auth
1938

    
1939
EOD;
1940

    
1941
				if (isset ($l2tpcfg['radius']['accounting'])) {
1942
					$mpdconf .=<<<EOD
1943
	set auth enable radius-acct
1944

    
1945
EOD;
1946
				}
1947
			}
1948

    
1949
			fwrite($fd, $mpdconf);
1950
			fclose($fd);
1951
			unset($mpdconf);
1952

    
1953
			/* write mpd.links */
1954
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.links", "w");
1955
			if (!$fd) {
1956
				printf(gettext("Error: cannot open mpd.links in vpn_l2tp_configure().") . "\n");
1957
				return 1;
1958
			}
1959

    
1960
			$mpdlinks = "";
1961

    
1962
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1963
				$mpdlinks .=<<<EOD
1964

    
1965
l2tp{$i}:
1966
	set link type l2tp
1967
	set l2tp enable incoming
1968
	set l2tp disable originate
1969

    
1970
EOD;
1971
				if (!empty($l2tpcfg['secret'])) {
1972
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
1973
				}
1974
			}
1975

    
1976
			fwrite($fd, $mpdlinks);
1977
			fclose($fd);
1978
			unset($mpdlinks);
1979

    
1980
			/* write mpd.secret */
1981
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.secret", "w");
1982
			if (!$fd) {
1983
				printf(gettext("Error: cannot open mpd.secret in vpn_l2tp_configure().") . "\n");
1984
				return 1;
1985
			}
1986

    
1987
			$mpdsecret = "\n\n";
1988

    
1989
			if (is_array($l2tpcfg['user'])) {
1990
				foreach ($l2tpcfg['user'] as $user) {
1991
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1992
				}
1993
			}
1994

    
1995
			fwrite($fd, $mpdsecret);
1996
			fclose($fd);
1997
			unset($mpdsecret);
1998
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
1999

    
2000
			vpn_netgraph_support();
2001

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

    
2005
			break;
2006

    
2007
		case 'redir':
2008
			break;
2009
	}
2010

    
2011
	if (platform_booting()) {
2012
		echo "done\n";
2013
	}
2014

    
2015
	return 0;
2016
}
2017

    
2018
?>
(59-59/68)