Project

General

Profile

Download (58.3 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
require_once("filter.inc");
45

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

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

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

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

    
113
	return $convertion;
114
}
115

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

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

    
123
	/* service may have been enabled, disabled, or otherwise changed in a way requiring rule updates */
124
	filter_configure();
125

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

    
134
		/* wait for process to die */
135
		sleep(2);
136

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

    
141
		return 0;
142
	}
143

    
144
	$a_phase1 = $config['ipsec']['phase1'];
145
	$a_phase2 = $config['ipsec']['phase2'];
146
	$a_client = $config['ipsec']['client'];
147

    
148
	$certpath = "{$g['varetc_path']}/ipsec/ipsec.d/certs";
149
	$capath = "{$g['varetc_path']}/ipsec/ipsec.d/cacerts";
150
	$keypath = "{$g['varetc_path']}/ipsec/ipsec.d/private";
151
	$crlpath = "{$g['varetc_path']}/ipsec/ipsec.d/crls";
152

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

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

    
191

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

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

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

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

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

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

    
233
			$ikeid = $ph1ent['ikeid'];
234
			$listeniflist = get_real_interface($a_phase1['interface']);
235

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

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

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

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

    
253
			$rg = $ph1ent['remote-gateway'];
254

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

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

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

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

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

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

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

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

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

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

    
388
	unset($stronconf);
389

    
390
	$strongswan = <<<EOD
391

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

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

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

    
426
EOD;
427

    
428
	$strongswan .= "\tplugins {\n";
429

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

    
447
EOD;
448
			break;
449
		}
450
	}
451

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

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

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

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

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

    
499
				$localid = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
500

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

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

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

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

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

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

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

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

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

    
564
	/* generate CA certificates files */
565
	if (is_array($config['ca']) && count($config['ca'])) {
566
		foreach ($config['ca'] as $ca) {
567
			if (!isset($ca['crt'])) {
568
				log_error(sprintf(gettext("Error: Invalid certificate info for %s"), $ca['descr']));
569
				continue;
570
			}
571
			$cert = base64_decode($ca['crt']);
572
			$x509cert = openssl_x509_parse(openssl_x509_read($cert));
573
			if (!is_array($x509cert) || !isset($x509cert['hash'])) {
574
				log_error(sprintf(gettext("Error: Invalid certificate hash info for %s"), $ca['descr']));
575
				continue;
576
			}
577
			$fname = "{$capath}/{$x509cert['hash']}.0.crt";
578
			if (!@file_put_contents($fname, $cert)) {
579
				log_error(sprintf(gettext("Error: Cannot write IPsec CA file for %s"), $ca['descr']));
580
				continue;
581
			}
582
			unset($cert);
583
		}
584
	}
585
	
586
	/* write out CRL files */
587
	if (is_array($config['crl']) && count($config['crl'])) {
588
		foreach ($config['crl'] as $crl) {
589
			if (!isset($crl['text'])) {
590
				log_error(sprintf(gettext("Warning: Missing CRL data for %s"), $crl['descr']));
591
				continue;
592
			}
593
			$fpath = "{$crlpath}/{$crl['refid']}.crl";
594
			if (!@file_put_contents($fpath, base64_decode($crl['text']))) {
595
				log_error(sprintf(gettext("Error: Cannot write IPsec CRL file for %s"), $crl['descr']));
596
				continue;
597
			}
598
		}
599
	}
600

    
601
	$pskconf = "";
602

    
603
	if (is_array($a_phase1) && count($a_phase1)) {
604
		foreach ($a_phase1 as $ph1ent) {
605

    
606
			if (isset($ph1ent['disabled'])) {
607
				continue;
608
			}
609

    
610
			if (strstr($ph1ent['authentication_method'], 'rsa') ||
611
			    in_array($ph1ent['authentication_method'], array('eap-mschapv2', 'eap-tls', 'eap-radius'))) {
612
				$certline = '';
613

    
614
				$ikeid = $ph1ent['ikeid'];
615
				$cert = lookup_cert($ph1ent['certref']);
616

    
617
				if (!$cert) {
618
					log_error(sprintf(gettext("Error: Invalid phase1 certificate reference for %s"), $ph1ent['name']));
619
					continue;
620
				}
621

    
622
				@chmod($certpath, 0600);
623

    
624
				$ph1keyfile = "{$keypath}/cert-{$ikeid}.key";
625
				if (!file_put_contents($ph1keyfile, base64_decode($cert['prv']))) {
626
					log_error(sprintf(gettext("Error: Cannot write phase1 key file for %s"), $ph1ent['name']));
627
					continue;
628
				}
629
				@chmod($ph1keyfile, 0600);
630

    
631
				$ph1certfile = "{$certpath}/cert-{$ikeid}.crt";
632
				if (!file_put_contents($ph1certfile, base64_decode($cert['crt']))) {
633
					log_error(sprintf(gettext("Error: Cannot write phase1 certificate file for %s"), $ph1ent['name']));
634
					@unlink($ph1keyfile);
635
					continue;
636
				}
637
				@chmod($ph1certfile, 0600);
638

    
639
				/* XXX" Traffic selectors? */
640
				$pskconf .= " : RSA {$ph1keyfile}\n";
641
			} else {
642
				list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, 'local');
643
				list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, 'peer', $rgmap);
644
				
645
				$myid = trim($myid_data);
646

    
647
				if (empty($peerid_data)) {
648
					continue;
649
				}
650

    
651
				if ($myid_type == 'fqdn' && !empty($myid)) {
652
					$myid = "@{$myid}";
653
				}
654
				
655
				$myid = isset($ph1ent['mobile']) ? trim($myid_data) : "%any";
656

    
657
				$peerid = ($peerid_data != 'allusers') ? trim($peerid_data) : '';
658

    
659
				if ($peerid_type == 'fqdn' && !empty($peerid)) {
660
					$peerid = "@{$peerid}";
661
				}
662

    
663
				if (!empty($ph1ent['pre-shared-key'])) {
664
					$pskconf .= "{$myid} {$peerid} : PSK 0s" . base64_encode(trim($ph1ent['pre-shared-key'])) . "\n";
665
				}
666
			}
667
		}
668
	}
669

    
670
	/* Add user PSKs */
671
	if (is_array($config['system']) && is_array($config['system']['user'])) {
672
		foreach ($config['system']['user'] as $user) {
673
			if (!empty($user['ipsecpsk'])) {
674
				$pskconf .= "{$myid} {$user['name']} : PSK 0s" . base64_encode($user['ipsecpsk']) . "\n";
675
			}
676
		}
677
		unset($user);
678
	}
679

    
680
	/* add PSKs for mobile clients */
681
	if (is_array($ipseccfg['mobilekey'])) {
682
		foreach ($ipseccfg['mobilekey'] as $key) {
683
			if ($key['ident'] == "allusers") {
684
				$key['ident'] = '%any';
685
			}
686
			if (empty($key['type'])) {
687
				$key['type'] = 'PSK';
688
			}
689
			$pskconf .= "{$myid} {$key['ident']} : {$key['type']} 0s" . base64_encode($key['pre-shared-key']) . "\n";
690
		}
691
		unset($key);
692
	}
693

    
694
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.secrets", $pskconf);
695
	chmod("{$g['varetc_path']}/ipsec/ipsec.secrets", 0600);
696
	unset($pskconf);
697

    
698
	$uniqueids = 'yes';
699
	if (!empty($config['ipsec']['uniqueids'])) {
700
		if (array_key_exists($config['ipsec']['uniqueids'], $ipsec_idhandling)) {
701
			$uniqueids = $config['ipsec']['uniqueids'];
702
		}
703
	}
704
	$natfilterrules = false;
705
	/* begin ipsec.conf */
706
	$ipsecconf = "";
707
	$enablecompression = false;
708
	if (is_array($a_phase1) && count($a_phase1)) {
709

    
710
		$ipsecconf .= "# This file is automatically generated. Do not edit\n";
711
		$ipsecconf .= "config setup\n\tuniqueids = {$uniqueids}\n";
712
		$ipsecconf .= "\tcharondebug=\"" . vpn_ipsec_configure_loglevels(true) . "\"\n";
713
		
714
		if (isset($config['ipsec']['strictcrlpolicy'])) {
715
			$ipsecconf .= "\tstrictcrlpolicy = yes \n";
716
		}
717

    
718
		if (!isset($config['ipsec']['noshuntlaninterfaces'])) {
719
			if ($config['interfaces']['lan']) {
720
				$lanip = get_interface_ip("lan");
721
				if (!empty($lanip) && is_ipaddrv4($lanip)) {
722
					$lansn = get_interface_subnet("lan");
723
					$lansa = gen_subnet($lanip, $lansn);
724
					$ipsecconf .= <<<EOD
725

    
726
conn bypasslan
727
	leftsubnet = {$lansa}/{$lansn}
728
	rightsubnet = {$lansa}/{$lansn}
729
	authby = never
730
	type = passthrough
731
	auto = route
732

    
733
EOD;
734
				}
735
			}
736
		}
737

    
738
		foreach ($a_phase1 as $ph1ent) {
739
			if (isset($ph1ent['disabled'])) {
740
				continue;
741
			}
742

    
743
			if ($ph1ent['mode'] == "aggressive") {
744
				$aggressive = "yes";
745
			} else {
746
				$aggressive = "no";
747
			}
748

    
749
			$ep = ipsec_get_phase1_src($ph1ent);
750
			if (!$ep) {
751
				continue;
752
			}
753

    
754
			$ikeid = $ph1ent['ikeid'];
755
			$keyexchange = "ikev1";
756
			$passive = "route";
757
			if (!empty($ph1ent['iketype'])) {
758
				if ($ph1ent['iketype'] == "ikev2") {
759
					$keyexchange = "ikev2";
760
					//$passive = "start";
761
				} 
762
			}
763

    
764
			if (isset($ph1ent['mobile'])) {
765
				$right_spec = "%any";
766
				$passive = 'add';
767
			} else {
768
				if (isset($ph1ent['responderonly'])) {
769
					$passive = 'add';
770
				}
771

    
772
				$right_spec = $ph1ent['remote-gateway'];
773
				if (is_ipaddr($right_spec)) {
774
					$sourcehost = $right_spec;
775
				} else {
776
					$sourcehost = $rgmap['remote-gateway'];
777
				}
778

    
779
				if ($ph1ent['protocol'] == 'inet') {
780
					if (strpos($ph1ent['interface'], '_vip')) {
781
						$vpninterface = explode('_vip', $ph1ent['interface']);
782
						$ifacesuse = get_real_interface($vpninterface[0]);
783
						$vpninterface = $vpninterface[0];
784
					} else {
785
						$ifacesuse = get_failover_interface($ph1ent['interface']);
786
						if (strpos($ifacesuse, '_vip')) {
787
							$vpninterface = explode('_vip', $ifacesuse);
788
							$ifacesuse = get_real_interface($vpninterface[0]);
789
							$vpninterface = $vpninterface[0];
790
						} else {
791
							$vpninterface = convert_real_interface_to_friendly_interface_name($ifacesuse);
792
						}
793
					}
794

    
795
					if (!empty($ifacesuse) && interface_has_gateway($vpninterface)) {
796
						$gatewayip = get_interface_gateway($vpninterface);
797
						$interfaceip = get_interface_ip($vpninterface);
798
						$subnet_bits = get_interface_subnet($vpninterface);
799
						$subnet_ip = gen_subnetv4($interfaceip, $subnet_bits);
800
						/* if the remote gateway is in the local subnet, then don't add a route */
801
						if (!ip_in_subnet($sourcehost, "{$subnet_ip}/{$subnet_bits}")) {
802
							if (is_ipaddrv4($gatewayip)) {
803
								// log_error("IPSEC interface is not WAN but {$ifacesuse}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
804
								mwexec("/sbin/route change -host {$sourcehost} {$gatewayip}", true);
805
							}
806
						}
807
					}
808
				} else if ($ph1ent['protocol'] == 'inet6') {
809
					if (strpos($ph1ent['interface'], '_vip')) {
810
						$vpninterface = explode('_vip', $ph1ent['interface']);
811
						$ifacesuse = get_real_interface($vpninterface[0]);
812
						$vpninterface = $vpninterface[0];
813
					} else {
814
						$ifacesuse = get_failover_interface($ph1ent['interface']);
815
						if (strpos($ifacesuse, '_vip')) {
816
							$vpninterface = explode('_vip', $ifacesuse);
817
							$ifacesuse = get_real_interface($vpninterface[0]);
818
							$vpninterface = $vpninterface[0];
819
						} else {
820
							$vpninterface = convert_real_interface_to_friendly_interface_name($ifacesuse);
821
						}
822
					}
823

    
824
					if (!empty($ifacesuse) && interface_has_gateway($vpninterface)) {
825
						$gatewayip = get_interface_gateway_v6($vpninterface);
826
						$interfaceip = get_interface_ipv6($vpninterface);
827
						$subnet_bits = get_interface_subnetv6($vpninterface);
828
						$subnet_ip = gen_subnetv6($interfaceip, $subnet_bits);
829
						/* if the remote gateway is in the local subnet, then don't add a route */
830
						if (!ip_in_subnet($sourcehost, "{$subnet_ip}/{$subnet_bits}")) {
831
							if (is_ipaddrv6($gatewayip)) {
832
								// log_error("IPSEC interface is not WAN but {$ifacesuse}, adding static route for VPN endpoint {$rgip} via {$gatewayip}");
833
								mwexec("/sbin/route change -inet6 -host {$sourcehost} {$gatewayip}", true);
834
							}
835
						}
836
					}
837
				}
838
			}
839

    
840
			list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, 'local');
841
			if ($myid_type != 'address' && $myid_type != 'keyid' && $myid_type != 'asn1dn') {
842
				$myid_data = "{$myid_type}:{$myid_data}";
843
			} elseif ($myid_type == "asn1dn" && !empty($myid_data)) {
844
				if ($myid_data[0] == '#') {
845
				/* asn1dn needs double quotes */
846
					$myid_data = "\"{$myid_type}:{$myid_data}\"";
847
				} else {
848
					$myid_data = "\"{$myid_data}\"";
849
				}
850
			}
851
			$leftid = '';
852
			if (!empty($myid_data)) {
853
				$leftid = "leftid = {$myid_data}";
854
			}
855

    
856
			$peerid_spec = '';
857
			if (isset($ph1ent['mobile']) && ($ph1ent['authentication_method'] == "pre_shared_key" || $ph1ent['authentication_method'] == "xauth_psk_server")) {
858
				// Only specify peer ID if we are not dealing with mobile PSK
859
			} else {
860
				list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, 'peer', $rgmap);
861
				if ($peerid_type == 'any') {
862
					$peerid_spec = '';
863
				} elseif ($peerid_type != 'address' && $peerid_type != 'keyid' && $peerid_type != 'asn1dn') {
864
					$peerid_spec = "{$peerid_type}:{$peerid_data}";
865
				} elseif ($peerid_type == "asn1dn") {
866
					/* asn1dn needs double quotes */
867
					if ($peerid_data[0] == '#') {
868
						$peerid_spec = "\"{$peerid_type}:{$peerid_data}\"";
869
					} elseif (!empty($peerid_data)) {
870
						$peerid_spec = "\"{$peerid_data}\"";
871
					}
872
				} else {
873
					$peerid_spec = $peerid_data;
874
				}
875
			}
876

    
877
			if (is_array($ph1ent['encryption-algorithm']) && !empty($ph1ent['encryption-algorithm']['name']) && !empty($ph1ent['hash-algorithm'])) {
878
				$ealgosp1 = '';
879
				$ealg_id = $ph1ent['encryption-algorithm']['name'];
880
				$ealg_kl = $ph1ent['encryption-algorithm']['keylen'];
881
				if ($ealg_kl) {
882
					$ealgosp1 = "ike = {$ealg_id}{$ealg_kl}-{$ph1ent['hash-algorithm']}";
883
				} else {
884
					$ealgosp1 = "ike = {$ealg_id}-{$ph1ent['hash-algorithm']}";
885
				}
886

    
887
				$modp = vpn_ipsec_convert_to_modp($ph1ent['dhgroup']);
888
				if (!empty($modp)) {
889
					$ealgosp1 .= "-{$modp}";
890
				}
891

    
892
				$ealgosp1 .= "!";
893
			}
894

    
895
			if ($ph1ent['dpd_delay'] && $ph1ent['dpd_maxfail']) {
896
				if ($passive == "route") {
897
					$dpdline = "dpdaction = restart";
898
				} else {
899
					$dpdline = "dpdaction = clear";
900
				}
901
				$dpdline .= "\n\tdpddelay = {$ph1ent['dpd_delay']}s";
902
				$dpdtimeout = $ph1ent['dpd_delay'] * ($ph1ent['dpd_maxfail'] + 1);
903
				$dpdline .= "\n\tdpdtimeout = {$dpdtimeout}s";
904
			} else {
905
				$dpdline = "dpdaction = none";
906
			}
907

    
908
			$ikelifeline = '';
909
			if ($ph1ent['lifetime']) {
910
				$ikelifeline = "ikelifetime = {$ph1ent['lifetime']}s";
911
			}
912

    
913
			$rightsourceip = NULL;
914
			if (isset($ph1ent['mobile']) && !empty($a_client['pool_address'])) {
915
				$rightsourceip = "\trightsourceip = {$a_client['pool_address']}/{$a_client['pool_netbits']}\n";
916
			}
917

    
918
			$authentication = "";
919
			switch ($ph1ent['authentication_method']) {
920
				case 'eap-mschapv2':
921
					if (isset($ph1ent['mobile'])) {
922
						$authentication = "eap_identity=%any\n\t";
923
						$authentication .= "leftauth=pubkey\n\trightauth=eap-mschapv2";
924
						if (!empty($ph1ent['certref'])) {
925
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
926
						}
927
					}
928
					break;
929
				case 'eap-tls':
930
					if (isset($ph1ent['mobile'])) {
931
						$authentication = "eap_identity=%identity\n\t";
932
						$authentication .= "leftauth=pubkey\n\trightauth=eap-tls";
933
						if (!empty($ph1ent['certref'])) {
934
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
935
						}
936
					} else {
937
						$authentication = "leftauth=eap-tls\n\trightauth=eap-tls";
938
						if (!empty($ph1ent['certref'])) {
939
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
940
						}
941
					}
942
					break;
943
				case 'eap-radius':
944
					if (isset($ph1ent['mobile'])) {
945
						$authentication = "eap_identity=%identity\n\t";
946
						$authentication .= "leftauth=pubkey\n\trightauth=eap-radius";
947
						if (!empty($ph1ent['certref'])) {
948
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
949
						}
950
					} else {
951
						$authentication = "leftauth=eap-radius\n\trightauth=eap-radius";
952
						if (!empty($ph1ent['certref'])) {
953
							$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
954
						}
955
					}
956
					break;
957
				case 'xauth_rsa_server':
958
					$authentication = "leftauth = pubkey\n\trightauth = pubkey";
959
					$authentication .= "\n\trightauth2 = xauth-generic";
960
					if (!empty($ph1ent['certref'])) {
961
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
962
					}
963
					break;
964
				case 'xauth_psk_server':
965
					$authentication = "leftauth = psk\n\trightauth = psk";
966
					$authentication .= "\n\trightauth2 = xauth-generic";
967
					break;
968
				case 'pre_shared_key':
969
					$authentication = "leftauth = psk\n\trightauth = psk";
970
					break;
971
				case 'rsasig':
972
					$authentication = "leftauth = pubkey\n\trightauth = pubkey";
973
					if (!empty($ph1ent['certref'])) {
974
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
975
					}
976
					break;
977
				case 'hybrid_rsa_server':
978
					$authentication = "leftauth = xauth-generic\n\trightauth = pubkey";
979
					$authentication .= "\n\trightauth2 = xauth";
980
					if (!empty($ph1ent['certref'])) {
981
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
982
					}
983
					break;
984
			}
985

    
986
			$left_spec = $ep;
987

    
988
			if (isset($ph1ent['reauth_enable'])) {
989
				$reauth = "reauth = no";
990
			} else {
991
				$reauth = "reauth = yes";
992
			}
993
			if (isset($ph1ent['rekey_enable'])) {
994
				$rekey = "rekey = no";
995
			} else {
996
				$rekey = "rekey = yes";
997
			}
998

    
999
			if ($ph1ent['nat_traversal'] == 'off') {
1000
				$forceencaps = 'forceencaps = no';
1001
			} else if ($ph1ent['nat_traversal'] == 'force') {
1002
				$forceencaps = 'forceencaps = yes';
1003
			} else {
1004
				$forceencaps = 'forceencaps = no';
1005
			}
1006

    
1007
			if ($ph1ent['mobike'] == 'on') {
1008
				$mobike = 'mobike = yes';
1009
			} else {
1010
				$mobike = 'mobike = no';
1011
			}
1012

    
1013
			$ipseclifetime = 0;
1014
			$rightsubnet_spec = array();
1015
			$leftsubnet_spec = array();
1016
			$reqids = array();
1017
			$ealgoAHsp2arr = array();
1018
			$ealgoESPsp2arr = array();
1019
		if (is_array($a_phase2) && count($a_phase2)) {
1020
			foreach ($a_phase2 as $ph2ent) {
1021
				if ($ikeid != $ph2ent['ikeid']) {
1022
					continue;
1023
				}
1024

    
1025
				if (isset($ph2ent['disabled'])) {
1026
					continue;
1027
				}
1028

    
1029
				if (isset($ph2ent['mobile']) && !isset($a_client['enable'])) {
1030
					continue;
1031
				}
1032

    
1033
				if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
1034
					$tunneltype = "type = tunnel";
1035

    
1036
					$localid_type = $ph2ent['localid']['type'];
1037
					$leftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['localid'], false, $ph2ent['mode']);
1038

    
1039
					/* Do not print localid in some cases, such as a pure-psk or psk/xauth single phase2 mobile tunnel */
1040
					if (($localid_type == "none" || $localid_type == "mobile") &&
1041
					    isset($ph1ent['mobile']) && (ipsec_get_number_of_phase2($ikeid) == 1)) {
1042
						$left_spec = '%any';
1043
					} else {
1044
						if ($localid_type != "address") {
1045
							$localid_type = "subnet";
1046
						}
1047
						// Don't let an empty subnet into config, it can cause parse errors. Ticket #2201.
1048
						if (!is_ipaddr($leftsubnet_data) && !is_subnet($leftsubnet_data) && ($leftsubnet_data != "0.0.0.0/0")) {
1049
							log_error("Invalid IPsec Phase 2 \"{$ph2ent['descr']}\" - {$ph2ent['localid']['type']} has no subnet.");
1050
							continue;
1051
						}
1052
						if (!empty($ph2ent['natlocalid'])) {
1053
							$natleftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['natlocalid'], false, $ph2ent['mode']);
1054
							if ($ph2ent['natlocalid']['type'] != "address") {
1055
								if (is_subnet($natleftsubnet_data)) {
1056
									$leftsubnet_data = "{$natleftsubnet_data}|{$leftsubnet_data}";
1057
								}
1058
							} else {
1059
								if (is_ipaddr($natleftsubnet_data)) {
1060
									$leftsubnet_data = "{$natleftsubnet_data}|{$leftsubnet_data}";
1061
								}
1062
							}
1063
							$natfilterrules = true;
1064
						}
1065
					}
1066

    
1067
					$leftsubnet_spec[] = $leftsubnet_data;
1068

    
1069
					if (!isset($ph2ent['mobile'])) {
1070
						$tmpsubnet = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']);
1071
						$rightsubnet_spec[] = $tmpsubnet;
1072
					} else if (!empty($a_client['pool_address'])) {
1073
						$rightsubnet_spec[] = "{$a_client['pool_address']}/{$a_client['pool_netbits']}";
1074
					}
1075
				} else {
1076
					$tunneltype = "type = transport";
1077

    
1078
					if ((($ph1ent['authentication_method'] == "xauth_psk_server") ||
1079
					    ($ph1ent['authentication_method'] == "pre_shared_key")) && isset($ph1ent['mobile'])) {
1080
						$left_spec = "%any";
1081
					} else {
1082
						$tmpsubnet = ipsec_get_phase1_src($ph1ent);
1083
						$leftsubnet_spec[] = $tmpsubnet;
1084
					}
1085

    
1086
					if (!isset($ph2ent['mobile'])) {
1087
						$rightsubnet_spec[] = $right_spec;
1088
					}
1089
				}
1090

    
1091
				if (isset($a_client['pfs_group']) && isset($ph2ent['mobile'])) {
1092
					$ph2ent['pfsgroup'] = $a_client['pfs_group'];
1093
				}
1094

    
1095
				if ($ph2ent['protocol'] == 'esp') {
1096
					if (is_array($ph2ent['encryption-algorithm-option'])) {
1097
						foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
1098
							$ealg_id = $ealg['name'];
1099
							$ealg_kl = $ealg['keylen'];
1100

    
1101
							if (!empty($ealg_kl) && $ealg_kl == "auto") {
1102
								if (empty($p2_ealgos) || !is_array($p2_ealgos)) {
1103
									require("ipsec.inc");
1104
								}
1105
								$key_hi = $p2_ealgos[$ealg_id]['keysel']['hi'];
1106
								$key_lo = $p2_ealgos[$ealg_id]['keysel']['lo'];
1107
								$key_step = $p2_ealgos[$ealg_id]['keysel']['step'];
1108
								/* XXX: in some cases where include ordering is suspect these variables
1109
								 * are somehow 0 and we enter this loop forever and timeout after 900
1110
								 * seconds wrecking bootup */
1111
								if ($key_hi != 0 and $key_lo != 0 and $key_step != 0) {
1112
									for ($keylen = $key_hi; $keylen >= $key_lo; $keylen -= $key_step) {
1113
										if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
1114
											foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
1115
												$halgo = str_replace('hmac_', '', $halgo);
1116
												$tmpealgo = "{$ealg_id}{$keylen}-{$halgo}";
1117
												$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1118
												if (!empty($modp)) {
1119
													$tmpealgo .= "-{$modp}";
1120
												}
1121
												$ealgoESPsp2arr[] = $tmpealgo;
1122
											}
1123
										} else {
1124
											$tmpealgo = "{$ealg_id}{$keylen}";
1125
											$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1126
											if (!empty($modp)) {
1127
												$tmpealgo .= "-{$modp}";
1128
											}
1129
											$ealgoESPsp2arr[] = $tmpealgo;
1130
										}
1131
									}
1132
								}
1133
							} else {
1134
								if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
1135
									foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
1136
										$halgo = str_replace('hmac_', '', $halgo);
1137
										$tmpealgo = "{$ealg_id}{$ealg_kl}-{$halgo}";
1138
										$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1139
										if (!empty($modp)) {
1140
											$tmpealgo .= "-{$modp}";
1141
										}
1142
										$ealgoESPsp2arr[] = $tmpealgo;
1143
									}
1144
								} else {
1145
									$tmpealgo = "{$ealg_id}{$ealg_kl}";
1146
									$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1147
									if (!empty($modp)) {
1148
										$tmpealgo .= "-{$modp}";
1149
									}
1150
									$ealgoESPsp2arr[] = $tmpealgo;
1151
								}
1152
							}
1153
						}
1154
					}
1155
				} else if ($ph2ent['protocol'] == 'ah') {
1156
					if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
1157
						$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
1158
						foreach ($ph2ent['hash-algorithm-option'] as $tmpAHalgo) {
1159
							$tmpAHalgo = str_replace('hmac_', '', $tmpAHalgo);
1160
							if (!empty($modp)) {
1161
								$tmpAHalgo = "-{$modp}";
1162
							}
1163
							$ealgoAHsp2arr[] = $tmpAHalgo;
1164
						}
1165
					}
1166
				}
1167

    
1168
				$reqids[] = $ph2ent['reqid'];
1169

    
1170
				if (!empty($ph2ent['lifetime'])) {
1171
					if ($ipseclifetime == 0 || intval($ipseclifetime) > intval($ph2ent['lifetime'])) {
1172
						$ipseclifetime = intval($ph2ent['lifetime']);
1173
					}
1174
				}
1175

    
1176
			}
1177
		}
1178

    
1179
			$ipsecconnect =<<<EOD
1180
	fragmentation = yes
1181
	keyexchange = {$keyexchange}
1182
	{$reauth}
1183
	{$forceencaps}
1184
	{$mobike}
1185
	{$rekey}
1186
	installpolicy = yes
1187
	{$tunneltype}
1188
	{$dpdline}
1189
	auto = {$passive}
1190
	left = {$left_spec}
1191
	right = {$right_spec}
1192
	{$leftid}
1193

    
1194
EOD;
1195

    
1196
			if (isset($config['ipsec']['compression'])) {
1197
				$ipsecconnect .= "\tcompress = yes\n";
1198
				$enablecompression = true;
1199
			}
1200
			if (!empty($ikelifeline)) {
1201
				$ipsecconnect .= "\t{$ikelifeline}\n";
1202
			}
1203
			if ($ipseclifetime > 0) {
1204
				$ipsecconnect .= "\tlifetime = {$ipseclifetime}s\n";
1205
			}
1206
			if (!empty($rightsourceip)) {
1207
				$ipsecconnect .= "{$rightsourceip}";
1208
			}
1209
			if (!empty($ealgosp1)) {
1210
				$ipsecconnect .= "\t{$ealgosp1}\n";
1211
			}
1212
			if (!empty($ealgoAHsp2arr)) {
1213
				$ipsecconnect .= "\tah = " . join(',', $ealgoAHsp2arr) . "!\n";
1214
			}
1215
			if (!empty($ealgoESPsp2arr)) {
1216
				$ipsecconnect .= "\tesp = " . join(',', $ealgoESPsp2arr) . "!\n";
1217
			}
1218
			if (!empty($authentication)) {
1219
				$ipsecconnect .= "\t{$authentication}\n";
1220
			}
1221
			if (!empty($peerid_spec)) {
1222
				$ipsecconnect .= "\trightid = {$peerid_spec}\n";
1223
			}
1224
			if ($keyexchange == 'ikev1') {
1225
				$ipsecconnect .= "\taggressive = {$aggressive}\n";
1226
			}
1227

    
1228
			if (!isset($ph1ent['mobile']) && $keyexchange == 'ikev1') {
1229
				if (!empty($rightsubnet_spec)) {
1230
					$ipsecfin = '';
1231
					foreach ($rightsubnet_spec as $idx => $rsubnet) {
1232
						$ipsecfin .= "\nconn con{$ph1ent['ikeid']}00{$idx}\n";
1233
						//if (!empty($reqids[$idx])) {
1234
						//	$ipsecfin .= "\treqid = " . $reqids[$idx] . "\n";
1235
						//}
1236
						$ipsecfin .= $ipsecconnect;
1237
						$ipsecfin .= "\trightsubnet = {$rsubnet}\n";
1238
						$ipsecfin .= "\tleftsubnet = " . $leftsubnet_spec[$idx] . "\n";
1239
					}
1240
				} else {
1241
					log_error("No phase2 specifications for tunnel with REQID = {$ikeid}");
1242
				}
1243
			} else {
1244
				$ipsecfin = "\nconn con{$ph1ent['ikeid']}\n";
1245
				//if (!empty($reqids[$idx])) {
1246
				//	$ipsecfin .= "\treqid = " . $reqids[0] . "\n";
1247
				//}
1248
				$ipsecfin .= $ipsecconnect;
1249
				if (!isset($ph1ent['mobile']) && !empty($rightsubnet_spec)) {
1250
					$tempsubnets = array();
1251
					foreach ($rightsubnet_spec as $rightsubnet) {
1252
						$tempsubnets[$rightsubnet] = $rightsubnet;
1253
					}
1254
					$ipsecfin .= "\trightsubnet = " . join(",", $tempsubnets) . "\n";
1255
					unset($tempsubnets, $rightsubnet);
1256
				}
1257
				if (!empty($leftsubnet_spec)) {
1258
					$tempsubnets = array();
1259
					foreach ($leftsubnet_spec as $leftsubnet) {
1260
						$tempsubnets[$leftsubnet] = $leftsubnet;
1261
					}
1262
					$ipsecfin .= "\tleftsubnet = " . join(",", $tempsubnets) . "\n";
1263
					unset($tempsubnets, $leftsubnet);
1264
				}
1265
			}
1266
			$ipsecconf .= $ipsecfin;
1267
			unset($ipsecfin);
1268
		}
1269
	}
1270

    
1271
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.conf", $ipsecconf);
1272
	unset($ipsecconf);
1273
	/* end ipsec.conf */
1274

    
1275
	if ($enablecompression === true) {
1276
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 1);
1277
	} else {
1278
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 0);
1279
	}
1280

    
1281
	/* manage process */
1282
	if ($restart === true) {
1283
		mwexec("/usr/local/sbin/ipsec restart", false);
1284
	} else {
1285
		if (isvalidpid("{$g['varrun_path']}/starter.charon.pid")) {
1286
			/* Update configuration changes */
1287
			/* Read secrets */
1288
			mwexec("/usr/local/sbin/ipsec rereadall", false);
1289
			mwexec("/usr/local/sbin/ipsec reload", false);
1290
		} else {
1291
			mwexec("/usr/local/sbin/ipsec start", false);
1292
		}
1293
	}
1294

    
1295
	if ($natfilterrules == true) {
1296
		filter_configure();
1297
	}
1298
	/* start filterdns, if necessary */
1299
	if (count($filterdns_list) > 0) {
1300
		$interval = 60;
1301
		if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval'])) {
1302
			$interval = $ipseccfg['dns-interval'];
1303
		}
1304

    
1305
		$hostnames = "";
1306
		array_unique($filterdns_list);
1307
		foreach ($filterdns_list as $hostname) {
1308
			$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload ipsecdns\"'\n";
1309
		}
1310
		file_put_contents("{$g['varetc_path']}/ipsec/filterdns-ipsec.hosts", $hostnames);
1311
		unset($hostnames);
1312

    
1313
		if (isvalidpid("{$g['varrun_path']}/filterdns-ipsec.pid")) {
1314
			sigkillbypid("{$g['varrun_path']}/filterdns-ipsec.pid", "HUP");
1315
		} else {
1316
			mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/ipsec/filterdns-ipsec.hosts -d 1");
1317
		}
1318
	} else {
1319
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
1320
		@unlink("{$g['varrun_path']}/filterdns-ipsec.pid");
1321
	}
1322

    
1323
	if (platform_booting()) {
1324
		echo "done\n";
1325
	}
1326

    
1327
	return count($filterdns_list);
1328
}
1329

    
1330
/*
1331
 * Forcefully restart IPsec
1332
 * This is required for when dynamic interfaces reload
1333
 * For all other occasions the normal vpn_ipsec_configure()
1334
 * will gracefully reload the settings without restarting
1335
 */
1336
function vpn_ipsec_force_reload($interface = "") {
1337
	global $g, $config;
1338

    
1339
	$ipseccfg = $config['ipsec'];
1340

    
1341
	if (!empty($interface) && is_array($ipseccfg['phase1'])) {
1342
		$found = false;
1343
		foreach ($ipseccfg['phase1'] as $ipsec) {
1344
			if (!isset($ipsec['disabled']) && ($ipsec['interface'] == $interface)) {
1345
				$found = true;
1346
				break;
1347
			}
1348
		}
1349
		if (!$found) {
1350
			log_error(sprintf(gettext("Ignoring IPsec reload since there are no tunnels on interface %s"), $interface));
1351
			return;
1352
		}
1353
	}
1354

    
1355
	/* if ipsec is enabled, start up again */
1356
	if (isset($ipseccfg['enable'])) {
1357
		log_error(gettext("Forcefully reloading IPsec"));
1358
		vpn_ipsec_configure();
1359
	}
1360
}
1361

    
1362
/* master setup for vpn (mpd) */
1363
function vpn_setup() {
1364
	/* start pptpd */
1365
	vpn_pptpd_configure();
1366

    
1367
	/* start pppoe server */
1368
	vpn_pppoes_configure();
1369

    
1370
	/* setup l2tp */
1371
	vpn_l2tp_configure();
1372
}
1373

    
1374
function vpn_netgraph_support() {
1375
	$iflist = get_configured_interface_list();
1376
	foreach ($iflist as $iface) {
1377
		$realif = get_real_interface($iface);
1378
		/* Get support for netgraph(4) from the nic */
1379
		$ifinfo = pfSense_get_interface_addresses($realif);
1380
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge"))) {
1381
			pfSense_ngctl_attach(".", $realif);
1382
		}
1383
	}
1384
}
1385

    
1386
function vpn_pptpd_configure() {
1387
	global $config, $g;
1388

    
1389
	$syscfg = $config['system'];
1390
	$pptpdcfg = $config['pptpd'];
1391

    
1392
	if (platform_booting()) {
1393
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off")) {
1394
			return 0;
1395
		}
1396

    
1397
		if (platform_booting(true)) {
1398
			echo gettext("Configuring PPTP VPN service... ");
1399
		}
1400
	} else {
1401
		/* kill mpd */
1402
		killbypid("{$g['varrun_path']}/pptp-vpn.pid");
1403

    
1404
		/* wait for process to die */
1405
		sleep(3);
1406

    
1407
		if (is_process_running("mpd -b")) {
1408
			killbypid("{$g['varrun_path']}/pptp-vpn.pid");
1409
			log_error(gettext("Could not kill mpd within 3 seconds.   Trying again."));
1410
		}
1411

    
1412
		/* remove mpd.conf, if it exists */
1413
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.conf");
1414
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.links");
1415
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.secret");
1416
	}
1417

    
1418
	if (empty($pptpdcfg['n_pptp_units'])) {
1419
		log_error("Something wrong in the PPTPd configuration. Preventing starting the daemon because issues would arise.");
1420
		return;
1421
	}
1422

    
1423
	/* make sure pptp-vpn directory exists */
1424
	if (!file_exists("{$g['varetc_path']}/pptp-vpn")) {
1425
		mkdir("{$g['varetc_path']}/pptp-vpn");
1426
	}
1427

    
1428
	switch ($pptpdcfg['mode']) {
1429
		case 'server':
1430
			/* write mpd.conf */
1431
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.conf", "w");
1432
			if (!$fd) {
1433
				printf(gettext("Error: cannot open mpd.conf in vpn_pptpd_configure().") . "\n");
1434
				return 1;
1435
			}
1436

    
1437
			$mpdconf = <<<EOD
1438
pptps:
1439

    
1440
EOD;
1441

    
1442
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1443
				$mpdconf .= "	load pt{$i}\n";
1444
			}
1445

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

    
1448
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
1449

    
1450
				$mpdconf .= <<<EOD
1451

    
1452
pt{$i}:
1453
	new -i pptpd{$i} pt{$i} pt{$i}
1454
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
1455
	load pts
1456

    
1457
EOD;
1458
			}
1459

    
1460
			$mpdconf .=<<<EOD
1461

    
1462
pts:
1463
	set iface disable on-demand
1464
	set iface enable proxy-arp
1465
	set iface enable tcpmssfix
1466
	set iface idle 1800
1467
	set iface up-script /usr/local/sbin/vpn-linkup
1468
	set iface down-script /usr/local/sbin/vpn-linkdown
1469
	set bundle enable multilink
1470
	set bundle enable crypt-reqd
1471
	set link yes acfcomp protocomp
1472
	set link no pap chap
1473
	set link enable chap-msv2
1474
	set link mtu 1460
1475
	set link keep-alive 10 60
1476
	set ipcp yes vjcomp
1477
	set bundle enable compression
1478
	set ccp yes mppc
1479
	set ccp yes mpp-e128
1480
	set ccp yes mpp-stateless
1481

    
1482
EOD;
1483

    
1484
			if (!isset ($pptpdcfg['req128'])) {
1485
				$mpdconf .=<<<EOD
1486
	set ccp yes mpp-e40
1487
	set ccp yes mpp-e56
1488

    
1489
EOD;
1490
			}
1491

    
1492
			if (isset($pptpdcfg["wins"]) && $pptpdcfg['wins'] != "") {
1493
				$mpdconf .= "	set ipcp nbns {$pptpdcfg['wins']}\n";
1494
			}
1495

    
1496
			if (!empty($pptpdcfg['dns1'])) {
1497
				$mpdconf .= "	set ipcp dns " . $pptpdcfg['dns1'];
1498
				if (!empty($pptpdcfg['dns2'])) {
1499
					$mpdconf .= " " . $pptpdcfg['dns2'];
1500
				}
1501
				$mpdconf .= "\n";
1502
			} elseif (isset ($config['dnsmasq']['enable'])) {
1503
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1504
				if ($syscfg['dnsserver'][0]) {
1505
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1506
				}
1507
				$mpdconf .= "\n";
1508
			} elseif (isset($config['unbound']['enable'])) {
1509
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1510
				if ($syscfg['dnsserver'][0]) {
1511
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1512
				}
1513
				$mpdconf .= "\n";
1514
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1515
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1516
			}
1517

    
1518
			if (isset ($pptpdcfg['radius']['server']['enable'])) {
1519
				$authport = (isset($pptpdcfg['radius']['server']['port']) && strlen($pptpdcfg['radius']['server']['port']) > 1) ? $pptpdcfg['radius']['server']['port'] : 1812;
1520
				$acctport = $authport + 1;
1521
				$mpdconf .=<<<EOD
1522
	set radius server {$pptpdcfg['radius']['server']['ip']} "{$pptpdcfg['radius']['server']['secret']}" {$authport} {$acctport}
1523

    
1524
EOD;
1525
				if (isset ($pptpdcfg['radius']['server2']['enable'])) {
1526
					$authport = (isset($pptpdcfg['radius']['server2']['port']) && strlen($pptpdcfg['radius']['server2']['port']) > 1) ? $pptpdcfg['radius']['server2']['port'] : 1812;
1527
					$acctport = $authport + 1;
1528
					$mpdconf .=<<<EOD
1529
	set radius server {$pptpdcfg['radius']['server2']['ip']} "{$pptpdcfg['radius']['server2']['secret2']}" {$authport} {$acctport}
1530

    
1531
EOD;
1532
				}
1533
				$mpdconf .=<<<EOD
1534
	set radius retries 3
1535
	set radius timeout 10
1536
	set auth enable radius-auth
1537

    
1538
EOD;
1539

    
1540
				if (isset ($pptpdcfg['radius']['accounting'])) {
1541
					$mpdconf .=<<<EOD
1542
	set auth enable radius-acct
1543
	set radius acct-update 300
1544

    
1545
EOD;
1546
				}
1547
			}
1548

    
1549
			fwrite($fd, $mpdconf);
1550
			fclose($fd);
1551
			unset($mpdconf);
1552

    
1553
			/* write mpd.links */
1554
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.links", "w");
1555
			if (!$fd) {
1556
				printf(gettext("Error: cannot open mpd.links in vpn_pptpd_configure().") . "\n");
1557
				return 1;
1558
			}
1559

    
1560
			$mpdlinks = "";
1561

    
1562
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1563
				$mpdlinks .=<<<EOD
1564

    
1565
pt{$i}:
1566
	set link type pptp
1567
	set pptp enable incoming
1568
	set pptp disable originate
1569
	set pptp disable windowing
1570

    
1571
EOD;
1572
			}
1573

    
1574
			fwrite($fd, $mpdlinks);
1575
			fclose($fd);
1576
			unset($mpdlinks);
1577

    
1578
			/* write mpd.secret */
1579
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.secret", "w");
1580
			if (!$fd) {
1581
				printf(gettext("Error: cannot open mpd.secret in vpn_pptpd_configure().") . "\n");
1582
				return 1;
1583
			}
1584

    
1585
			$mpdsecret = "";
1586

    
1587
			if (is_array($pptpdcfg['user'])) {
1588
				foreach ($pptpdcfg['user'] as $user) {
1589
					$pass = str_replace('\\', '\\\\', $user['password']);
1590
					$pass = str_replace('"', '\"', $pass);
1591
					$mpdsecret .= "{$user['name']} \"{$pass}\" {$user['ip']}\n";
1592
				}
1593
			}
1594

    
1595
			fwrite($fd, $mpdsecret);
1596
			fclose($fd);
1597
			unset($mpdsecret);
1598
			chmod("{$g['varetc_path']}/pptp-vpn/mpd.secret", 0600);
1599

    
1600
			vpn_netgraph_support();
1601

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

    
1605
			break;
1606

    
1607
		case 'redir':
1608
			break;
1609
	}
1610

    
1611
	if (platform_booting()) {
1612
		echo "done\n";
1613
	}
1614

    
1615
	return 0;
1616
}
1617

    
1618
function vpn_pppoes_configure() {
1619
	global $config;
1620

    
1621
	if (is_array($config['pppoes']['pppoe'])) {
1622
		foreach ($config['pppoes']['pppoe'] as $pppoe) {
1623
			vpn_pppoe_configure($pppoe);
1624
		}
1625
	}
1626
}
1627

    
1628
function vpn_pppoe_configure(&$pppoecfg) {
1629
	global $config, $g;
1630

    
1631
	$syscfg = $config['system'];
1632

    
1633
	/* create directory if it does not exist */
1634
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn")) {
1635
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1636
	}
1637

    
1638
	if (platform_booting()) {
1639
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off")) {
1640
			return 0;
1641
		}
1642

    
1643
		echo gettext("Configuring PPPoE Server service... ");
1644
	} else {
1645
		/* kill mpd */
1646
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1647

    
1648
		/* wait for process to die */
1649
		sleep(2);
1650

    
1651
	}
1652

    
1653
	switch ($pppoecfg['mode']) {
1654

    
1655
		case 'server':
1656

    
1657
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1658

    
1659
			if ($pppoecfg['paporchap'] == "chap") {
1660
				$paporchap = "set link enable chap";
1661
			} else {
1662
				$paporchap = "set link enable pap";
1663
			}
1664

    
1665
			/* write mpd.conf */
1666
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1667
			if (!$fd) {
1668
				printf(gettext("Error: cannot open mpd.conf in vpn_pppoe_configure().") . "\n");
1669
				return 1;
1670
			}
1671
			$mpdconf = "\n\n";
1672
			$mpdconf .= "poes:\n";
1673

    
1674
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1675
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1676
			}
1677

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

    
1680
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1681

    
1682
				if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1683
					$issue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1684
				} else {
1685
					$issue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1686
				}
1687

    
1688
				$mpdconf .=<<<EOD
1689

    
1690
poes{$pppoecfg['pppoeid']}{$i}:
1691
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1692
	{$issue_ip_type}
1693
	load pppoe_standard
1694

    
1695
EOD;
1696
			}
1697

    
1698
			$mpdconf .=<<<EOD
1699

    
1700
pppoe_standard:
1701
	set bundle no multilink
1702
	set bundle enable compression
1703
	set auth max-logins 1
1704
	set iface up-script /usr/local/sbin/vpn-linkup
1705
	set iface down-script /usr/local/sbin/vpn-linkdown
1706
	set iface idle 0
1707
	set iface disable on-demand
1708
	set iface disable proxy-arp
1709
	set iface enable tcpmssfix
1710
	set iface mtu 1500
1711
	set link no pap chap
1712
	{$paporchap}
1713
	set link keep-alive 60 180
1714
	set ipcp yes vjcomp
1715
	set ipcp no vjcomp
1716
	set link max-redial -1
1717
	set link mtu 1492
1718
	set link mru 1492
1719
	set ccp yes mpp-e40
1720
	set ccp yes mpp-e128
1721
	set ccp yes mpp-stateless
1722
	set link latency 1
1723
	#set ipcp dns 10.10.1.3
1724
	#set bundle accept encryption
1725

    
1726
EOD;
1727

    
1728
			if (!empty($pppoecfg['dns1'])) {
1729
				$mpdconf .= "	set ipcp dns " . $pppoecfg['dns1'];
1730
				if (!empty($pppoecfg['dns2'])) {
1731
					$mpdconf .= " " . $pppoecfg['dns2'];
1732
				}
1733
				$mpdconf .= "\n";
1734
			} elseif (isset ($config['dnsmasq']['enable'])) {
1735
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1736
				if ($syscfg['dnsserver'][0]) {
1737
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1738
				}
1739
				$mpdconf .= "\n";
1740
			} elseif (isset ($config['unbound']['enable'])) {
1741
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1742
				if ($syscfg['dnsserver'][0]) {
1743
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1744
				}
1745
				$mpdconf .= "\n";
1746
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1747
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1748
			}
1749

    
1750
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1751
				$radiusport = "";
1752
				$radiusacctport = "";
1753
				if (isset($pppoecfg['radius']['server']['port'])) {
1754
					$radiusport = $pppoecfg['radius']['server']['port'];
1755
				}
1756
				if (isset($pppoecfg['radius']['server']['acctport'])) {
1757
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1758
				}
1759
				$mpdconf .=<<<EOD
1760
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
1761
	set radius retries 3
1762
	set radius timeout 10
1763
	set auth enable radius-auth
1764

    
1765
EOD;
1766

    
1767
				if (isset ($pppoecfg['radius']['accounting'])) {
1768
					$mpdconf .=<<<EOD
1769
	set auth enable radius-acct
1770

    
1771
EOD;
1772
				}
1773
			}
1774

    
1775
			fwrite($fd, $mpdconf);
1776
			fclose($fd);
1777
			unset($mpdconf);
1778

    
1779
			/* write mpd.links */
1780
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.links", "w");
1781
			if (!$fd) {
1782
				printf(gettext("Error: cannot open mpd.links in vpn_pppoe_configure().") . "\n");
1783
				return 1;
1784
			}
1785

    
1786
			$mpdlinks = "";
1787

    
1788
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1789
				$mpdlinks .=<<<EOD
1790

    
1791
poes{$pppoecfg['pppoeid']}{$i}:
1792
	set phys type pppoe
1793
	set pppoe iface {$pppoe_interface}
1794
	set pppoe service "*"
1795
	set pppoe disable originate
1796
	set pppoe enable incoming
1797

    
1798
EOD;
1799
			}
1800

    
1801
			fwrite($fd, $mpdlinks);
1802
			fclose($fd);
1803
			unset($mpdlinks);
1804

    
1805
			if ($pppoecfg['username']) {
1806
				/* write mpd.secret */
1807
				$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
1808
				if (!$fd) {
1809
					printf(gettext("Error: cannot open mpd.secret in vpn_pppoe_configure().") . "\n");
1810
					return 1;
1811
				}
1812

    
1813
				$mpdsecret = "\n\n";
1814

    
1815
				if (!empty($pppoecfg['username'])) {
1816
					$item = explode(" ", $pppoecfg['username']);
1817
					foreach ($item as $userdata) {
1818
						$data = explode(":", $userdata);
1819
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1820
					}
1821
				}
1822

    
1823
				fwrite($fd, $mpdsecret);
1824
				fclose($fd);
1825
				unset($mpdsecret);
1826
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1827
			}
1828

    
1829
			/* Check if previous instance is still up */
1830
			while (file_exists("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid") && isvalidpid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid")) {
1831
				killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1832
			}
1833

    
1834
			/* Get support for netgraph(4) from the nic */
1835
			pfSense_ngctl_attach(".", $pppoe_interface);
1836
			/* fire up mpd */
1837
			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");
1838

    
1839
			break;
1840
	}
1841

    
1842
	if (platform_booting()) {
1843
		echo gettext("done") . "\n";
1844
	}
1845

    
1846
	return 0;
1847
}
1848

    
1849
function vpn_l2tp_configure() {
1850
	global $config, $g;
1851

    
1852
	$syscfg = $config['system'];
1853
	$l2tpcfg = $config['l2tp'];
1854

    
1855
	/* create directory if it does not exist */
1856
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn")) {
1857
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1858
	}
1859

    
1860
	if (platform_booting()) {
1861
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off")) {
1862
			return 0;
1863
		}
1864

    
1865
		echo gettext("Configuring l2tp VPN service... ");
1866
	} else {
1867
		/* kill mpd */
1868
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1869

    
1870
		/* wait for process to die */
1871
		sleep(8);
1872

    
1873
	}
1874

    
1875
	/* make sure l2tp-vpn directory exists */
1876
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn")) {
1877
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1878
	}
1879

    
1880
	switch ($l2tpcfg['mode']) {
1881

    
1882
		case 'server':
1883
			if ($l2tpcfg['paporchap'] == "chap") {
1884
				$paporchap = "set link enable chap";
1885
			} else {
1886
				$paporchap = "set link enable pap";
1887
			}
1888

    
1889
			/* write mpd.conf */
1890
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1891
			if (!$fd) {
1892
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
1893
				return 1;
1894
			}
1895
			$mpdconf = "\n\n";
1896
			$mpdconf .=<<<EOD
1897
l2tps:
1898

    
1899
EOD;
1900

    
1901
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1902
				$mpdconf .= "	load l2tp{$i}\n";
1903
			}
1904

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

    
1907
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1908

    
1909
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1910
					$issue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1911
				} else {
1912
					$issue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1913
				}
1914

    
1915
				$mpdconf .=<<<EOD
1916

    
1917
l2tp{$i}:
1918
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1919
	{$issue_ip_type}
1920
	load l2tp_standard
1921

    
1922
EOD;
1923
			}
1924

    
1925
			$mpdconf .=<<<EOD
1926

    
1927
l2tp_standard:
1928
	set bundle disable multilink
1929
	set bundle enable compression
1930
	set bundle yes crypt-reqd
1931
	set ipcp yes vjcomp
1932
	# set ipcp ranges 131.188.69.161/32 131.188.69.170/28
1933
	set ccp yes mppc
1934
	set iface disable on-demand
1935
	set iface enable proxy-arp
1936
	set iface up-script /usr/local/sbin/vpn-linkup
1937
	set iface down-script /usr/local/sbin/vpn-linkdown
1938
	set link yes acfcomp protocomp
1939
	set link no pap chap
1940
	{$paporchap}
1941
	set link keep-alive 10 180
1942

    
1943
EOD;
1944

    
1945
			if (is_ipaddr($l2tpcfg['wins'])) {
1946
				$mpdconf .= "	set ipcp nbns {$l2tpcfg['wins']}\n";
1947
			}
1948
			if (is_ipaddr($l2tpcfg['dns1'])) {
1949
				$mpdconf .= "	set ipcp dns " . $l2tpcfg['dns1'];
1950
				if (is_ipaddr($l2tpcfg['dns2'])) {
1951
					$mpdconf .= " " . $l2tpcfg['dns2'];
1952
				}
1953
				$mpdconf .= "\n";
1954
			} elseif (isset ($config['dnsmasq']['enable'])) {
1955
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1956
				if ($syscfg['dnsserver'][0]) {
1957
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1958
				}
1959
				$mpdconf .= "\n";
1960
			} elseif (isset ($config['unbound']['enable'])) {
1961
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1962
				if ($syscfg['dnsserver'][0]) {
1963
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1964
				}
1965
				$mpdconf .= "\n";
1966
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1967
				$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1968
			}
1969

    
1970
			if (isset ($l2tpcfg['radius']['enable'])) {
1971
				$mpdconf .=<<<EOD
1972
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1973
	set radius retries 3
1974
	set radius timeout 10
1975
	set auth enable radius-auth
1976

    
1977
EOD;
1978

    
1979
				if (isset ($l2tpcfg['radius']['accounting'])) {
1980
					$mpdconf .=<<<EOD
1981
	set auth enable radius-acct
1982

    
1983
EOD;
1984
				}
1985
			}
1986

    
1987
			fwrite($fd, $mpdconf);
1988
			fclose($fd);
1989
			unset($mpdconf);
1990

    
1991
			/* write mpd.links */
1992
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.links", "w");
1993
			if (!$fd) {
1994
				printf(gettext("Error: cannot open mpd.links in vpn_l2tp_configure().") . "\n");
1995
				return 1;
1996
			}
1997

    
1998
			$mpdlinks = "";
1999

    
2000
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
2001
				$mpdlinks .=<<<EOD
2002

    
2003
l2tp{$i}:
2004
	set link type l2tp
2005
	set l2tp enable incoming
2006
	set l2tp disable originate
2007

    
2008
EOD;
2009
				if (!empty($l2tpcfg['secret'])) {
2010
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
2011
				}
2012
			}
2013

    
2014
			fwrite($fd, $mpdlinks);
2015
			fclose($fd);
2016
			unset($mpdlinks);
2017

    
2018
			/* write mpd.secret */
2019
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.secret", "w");
2020
			if (!$fd) {
2021
				printf(gettext("Error: cannot open mpd.secret in vpn_l2tp_configure().") . "\n");
2022
				return 1;
2023
			}
2024

    
2025
			$mpdsecret = "\n\n";
2026

    
2027
			if (is_array($l2tpcfg['user'])) {
2028
				foreach ($l2tpcfg['user'] as $user) {
2029
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
2030
				}
2031
			}
2032

    
2033
			fwrite($fd, $mpdsecret);
2034
			fclose($fd);
2035
			unset($mpdsecret);
2036
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
2037

    
2038
			vpn_netgraph_support();
2039

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

    
2043
			break;
2044

    
2045
		case 'redir':
2046
			break;
2047
	}
2048

    
2049
	if (platform_booting()) {
2050
		echo "done\n";
2051
	}
2052

    
2053
	return 0;
2054
}
2055

    
2056
?>
(59-59/68)