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
				if (empty($peerid_data)) {
633
					continue;
634
				}
635

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

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

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

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

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

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

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

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

    
708
EOD;
709
				}
710
			}
711
		}
712

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
942
			$left_spec = $ep;
943

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

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

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

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

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

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

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

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

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

    
1023
					$leftsubnet_spec[] = $leftsubnet_data;
1024

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

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

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

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

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

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

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

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

    
1132
			}
1133
		}
1134

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

    
1150
EOD;
1151

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

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

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

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

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

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

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

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

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

    
1282
	return count($filterdns_list);
1283
}
1284

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1401
EOD;
1402

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

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

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

    
1411
				$mpdconf .= <<<EOD
1412

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

    
1418
EOD;
1419
			}
1420

    
1421
			$mpdconf .=<<<EOD
1422

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

    
1443
EOD;
1444

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

    
1450
EOD;
1451
			}
1452

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

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

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

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

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

    
1499
EOD;
1500

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

    
1506
EOD;
1507
				}
1508
			}
1509

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

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

    
1521
			$mpdlinks = "";
1522

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

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

    
1532
EOD;
1533
			}
1534

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

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

    
1546
			$mpdsecret = "";
1547

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

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

    
1561
			vpn_netgraph_support();
1562

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

    
1566
			break;
1567

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

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

    
1576
	return 0;
1577
}
1578

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

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

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

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

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

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

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

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

    
1612
	}
1613

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

    
1616
		case 'server':
1617

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

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

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

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

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

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

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

    
1649
				$mpdconf .=<<<EOD
1650

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

    
1656
EOD;
1657
			}
1658

    
1659
			$mpdconf .=<<<EOD
1660

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

    
1687
EOD;
1688

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

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

    
1726
EOD;
1727

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

    
1732
EOD;
1733
				}
1734
			}
1735

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

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

    
1747
			$mpdlinks = "";
1748

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

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

    
1759
EOD;
1760
			}
1761

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

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

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

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

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

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

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

    
1800
			break;
1801
	}
1802

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

    
1807
	return 0;
1808
}
1809

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

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

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

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

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

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

    
1834
	}
1835

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

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

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

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

    
1860
EOD;
1861

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

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

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

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

    
1876
				$mpdconf .=<<<EOD
1877

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

    
1883
EOD;
1884
			}
1885

    
1886
			$mpdconf .=<<<EOD
1887

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

    
1904
EOD;
1905

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

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

    
1938
EOD;
1939

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

    
1944
EOD;
1945
				}
1946
			}
1947

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

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

    
1959
			$mpdlinks = "";
1960

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

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

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

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

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

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

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

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

    
1999
			vpn_netgraph_support();
2000

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

    
2004
			break;
2005

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

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

    
2014
	return 0;
2015
}
2016

    
2017
?>
(59-59/68)