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

    
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
	$crlpath = "{$g['varetc_path']}/ipsec/ipsec.d/crls";
155

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

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

    
194

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
391
	unset($stronconf);
392

    
393
	$strongswan = <<<EOD
394

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

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

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

    
429
EOD;
430

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

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

    
450
EOD;
451
			break;
452
		}
453
	}
454

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
604
	$pskconf = "";
605

    
606
	if (is_array($a_phase1) && count($a_phase1)) {
607
		foreach ($a_phase1 as $ph1ent) {
608

    
609
			if (isset($ph1ent['disabled'])) {
610
				continue;
611
			}
612

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

    
617
				$ikeid = $ph1ent['ikeid'];
618
				$cert = lookup_cert($ph1ent['certref']);
619

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

    
625
				@chmod($certpath, 0600);
626

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

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

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

    
650
				if (empty($peerid_data)) {
651
					continue;
652
				}
653

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

    
660
				$peerid = ($peerid_data != 'allusers') ? trim($peerid_data) : '';
661

    
662
				if ($peerid_type == 'fqdn' && !empty($peerid)) {
663
					$peerid = "@{$peerid}";
664
				}
665

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

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

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

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

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

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

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

    
729
conn bypasslan
730
	leftsubnet = {$lanip}/32
731
	rightsubnet = {$lansa}/{$lansn}
732
	authby = never
733
	type = passthrough
734
	auto = route
735

    
736
EOD;
737
				}
738
			}
739
		}
740

    
741
		foreach ($a_phase1 as $ph1ent) {
742
			if (isset($ph1ent['disabled'])) {
743
				continue;
744
			}
745

    
746
			if ($ph1ent['mode'] == "aggressive") {
747
				$aggressive = "yes";
748
			} else {
749
				$aggressive = "no";
750
			}
751

    
752
			$ep = ipsec_get_phase1_src($ph1ent);
753
			if (!$ep) {
754
				continue;
755
			}
756

    
757
			$ikeid = $ph1ent['ikeid'];
758
			$keyexchange = "ikev1";
759
			$passive = "route";
760
			if (!empty($ph1ent['iketype'])) {
761
				if ($ph1ent['iketype'] == "ikev2") {
762
					$keyexchange = "ikev2";
763
					//$passive = "start";
764
				} else if ($ph1ent['iketype'] == "auto") {
765
					$keyexchange = "ike";
766
				}
767
			}
768

    
769
			if (isset($ph1ent['mobile'])) {
770
				$right_spec = "%any";
771
				$passive = 'add';
772
			} else {
773
				if (isset($ph1ent['responderonly'])) {
774
					$passive = 'add';
775
				}
776

    
777
				$right_spec = $ph1ent['remote-gateway'];
778
				if (is_ipaddr($right_spec)) {
779
					$sourcehost = $right_spec;
780
				} else {
781
					$sourcehost = $rgmap['remote-gateway'];
782
				}
783

    
784
				if ($ph1ent['protocol'] == 'inet') {
785
					if (strpos($ph1ent['interface'], '_vip')) {
786
						$vpninterface = explode('_vip', $ph1ent['interface']);
787
						$ifacesuse = get_real_interface($vpninterface[0]);
788
						$vpninterface = $vpninterface[0];
789
					} else {
790
						$ifacesuse = get_failover_interface($ph1ent['interface']);
791
						if (strpos($ifacesuse, '_vip')) {
792
							$vpninterface = explode('_vip', $ifacesuse);
793
							$ifacesuse = get_real_interface($vpninterface[0]);
794
							$vpninterface = $vpninterface[0];
795
						} else {
796
							$vpninterface = convert_real_interface_to_friendly_interface_name($ifacesuse);
797
						}
798
					}
799

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

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

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

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

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

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

    
894
				$ealgosp1 .= "!";
895
			}
896

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

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

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

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

    
988
			$left_spec = $ep;
989

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

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

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

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

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

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

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

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

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

    
1069
					$leftsubnet_spec[] = $leftsubnet_data;
1070

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

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

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

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

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

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

    
1170
				$reqids[] = $ph2ent['reqid'];
1171

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

    
1178
			}
1179
		}
1180

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

    
1196
EOD;
1197

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

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

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

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

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

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

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

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

    
1325
	if (platform_booting()) {
1326
		echo "done\n";
1327
	}
1328

    
1329
	return count($filterdns_list);
1330
}
1331

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

    
1341
	$ipseccfg = $config['ipsec'];
1342

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

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

    
1364
/* master setup for vpn (mpd) */
1365
function vpn_setup() {
1366
	global $g;
1367

    
1368
	if ($g['platform'] == 'jail') {
1369
		return;
1370
	}
1371

    
1372
	/* start pptpd */
1373
	vpn_pptpd_configure();
1374

    
1375
	/* start pppoe server */
1376
	vpn_pppoes_configure();
1377

    
1378
	/* setup l2tp */
1379
	vpn_l2tp_configure();
1380
}
1381

    
1382
function vpn_netgraph_support() {
1383
	$iflist = get_configured_interface_list();
1384
	foreach ($iflist as $iface) {
1385
		$realif = get_real_interface($iface);
1386
		/* Get support for netgraph(4) from the nic */
1387
		$ifinfo = pfSense_get_interface_addresses($realif);
1388
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge"))) {
1389
			pfSense_ngctl_attach(".", $realif);
1390
		}
1391
	}
1392
}
1393

    
1394
function vpn_pptpd_configure() {
1395
	global $config, $g;
1396

    
1397
	$syscfg = $config['system'];
1398
	$pptpdcfg = $config['pptpd'];
1399

    
1400
	if (platform_booting()) {
1401
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off")) {
1402
			return 0;
1403
		}
1404

    
1405
		if (platform_booting(true)) {
1406
			echo gettext("Configuring PPTP VPN service... ");
1407
		}
1408
	} else {
1409
		/* kill mpd */
1410
		killbypid("{$g['varrun_path']}/pptp-vpn.pid");
1411

    
1412
		/* wait for process to die */
1413
		sleep(3);
1414

    
1415
		if (is_process_running("mpd -b")) {
1416
			killbypid("{$g['varrun_path']}/pptp-vpn.pid");
1417
			log_error(gettext("Could not kill mpd within 3 seconds.   Trying again."));
1418
		}
1419

    
1420
		/* remove mpd.conf, if it exists */
1421
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.conf");
1422
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.links");
1423
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.secret");
1424
	}
1425

    
1426
	if (empty($pptpdcfg['n_pptp_units'])) {
1427
		log_error("Something wrong in the PPTPd configuration. Preventing starting the daemon because issues would arise.");
1428
		return;
1429
	}
1430

    
1431
	/* make sure pptp-vpn directory exists */
1432
	if (!file_exists("{$g['varetc_path']}/pptp-vpn")) {
1433
		mkdir("{$g['varetc_path']}/pptp-vpn");
1434
	}
1435

    
1436
	switch ($pptpdcfg['mode']) {
1437
		case 'server':
1438
			/* write mpd.conf */
1439
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.conf", "w");
1440
			if (!$fd) {
1441
				printf(gettext("Error: cannot open mpd.conf in vpn_pptpd_configure().") . "\n");
1442
				return 1;
1443
			}
1444

    
1445
			$mpdconf = <<<EOD
1446
pptps:
1447

    
1448
EOD;
1449

    
1450
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1451
				$mpdconf .= "	load pt{$i}\n";
1452
			}
1453

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

    
1456
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
1457

    
1458
				$mpdconf .= <<<EOD
1459

    
1460
pt{$i}:
1461
	new -i pptpd{$i} pt{$i} pt{$i}
1462
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
1463
	load pts
1464

    
1465
EOD;
1466
			}
1467

    
1468
			$mpdconf .=<<<EOD
1469

    
1470
pts:
1471
	set iface disable on-demand
1472
	set iface enable proxy-arp
1473
	set iface enable tcpmssfix
1474
	set iface idle 1800
1475
	set iface up-script /usr/local/sbin/vpn-linkup
1476
	set iface down-script /usr/local/sbin/vpn-linkdown
1477
	set bundle enable multilink
1478
	set bundle enable crypt-reqd
1479
	set link yes acfcomp protocomp
1480
	set link no pap chap
1481
	set link enable chap-msv2
1482
	set link mtu 1460
1483
	set link keep-alive 10 60
1484
	set ipcp yes vjcomp
1485
	set bundle enable compression
1486
	set ccp yes mppc
1487
	set ccp yes mpp-e128
1488
	set ccp yes mpp-stateless
1489

    
1490
EOD;
1491

    
1492
			if (!isset ($pptpdcfg['req128'])) {
1493
				$mpdconf .=<<<EOD
1494
	set ccp yes mpp-e40
1495
	set ccp yes mpp-e56
1496

    
1497
EOD;
1498
			}
1499

    
1500
			if (isset($pptpdcfg["wins"]) && $pptpdcfg['wins'] != "") {
1501
				$mpdconf .= "	set ipcp nbns {$pptpdcfg['wins']}\n";
1502
			}
1503

    
1504
			if (!empty($pptpdcfg['dns1'])) {
1505
				$mpdconf .= "	set ipcp dns " . $pptpdcfg['dns1'];
1506
				if (!empty($pptpdcfg['dns2'])) {
1507
					$mpdconf .= " " . $pptpdcfg['dns2'];
1508
				}
1509
				$mpdconf .= "\n";
1510
			} elseif (isset ($config['dnsmasq']['enable'])) {
1511
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1512
				if ($syscfg['dnsserver'][0]) {
1513
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1514
				}
1515
				$mpdconf .= "\n";
1516
			} elseif (isset($config['unbound']['enable'])) {
1517
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1518
				if ($syscfg['dnsserver'][0]) {
1519
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1520
				}
1521
				$mpdconf .= "\n";
1522
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1523
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1524
			}
1525

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

    
1532
EOD;
1533
				if (isset ($pptpdcfg['radius']['server2']['enable'])) {
1534
					$authport = (isset($pptpdcfg['radius']['server2']['port']) && strlen($pptpdcfg['radius']['server2']['port']) > 1) ? $pptpdcfg['radius']['server2']['port'] : 1812;
1535
					$acctport = $authport + 1;
1536
					$mpdconf .=<<<EOD
1537
	set radius server {$pptpdcfg['radius']['server2']['ip']} "{$pptpdcfg['radius']['server2']['secret2']}" {$authport} {$acctport}
1538

    
1539
EOD;
1540
				}
1541
				$mpdconf .=<<<EOD
1542
	set radius retries 3
1543
	set radius timeout 10
1544
	set auth enable radius-auth
1545

    
1546
EOD;
1547

    
1548
				if (isset ($pptpdcfg['radius']['accounting'])) {
1549
					$mpdconf .=<<<EOD
1550
	set auth enable radius-acct
1551
	set radius acct-update 300
1552

    
1553
EOD;
1554
				}
1555
			}
1556

    
1557
			fwrite($fd, $mpdconf);
1558
			fclose($fd);
1559
			unset($mpdconf);
1560

    
1561
			/* write mpd.links */
1562
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.links", "w");
1563
			if (!$fd) {
1564
				printf(gettext("Error: cannot open mpd.links in vpn_pptpd_configure().") . "\n");
1565
				return 1;
1566
			}
1567

    
1568
			$mpdlinks = "";
1569

    
1570
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1571
				$mpdlinks .=<<<EOD
1572

    
1573
pt{$i}:
1574
	set link type pptp
1575
	set pptp enable incoming
1576
	set pptp disable originate
1577
	set pptp disable windowing
1578

    
1579
EOD;
1580
			}
1581

    
1582
			fwrite($fd, $mpdlinks);
1583
			fclose($fd);
1584
			unset($mpdlinks);
1585

    
1586
			/* write mpd.secret */
1587
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.secret", "w");
1588
			if (!$fd) {
1589
				printf(gettext("Error: cannot open mpd.secret in vpn_pptpd_configure().") . "\n");
1590
				return 1;
1591
			}
1592

    
1593
			$mpdsecret = "";
1594

    
1595
			if (is_array($pptpdcfg['user'])) {
1596
				foreach ($pptpdcfg['user'] as $user) {
1597
					$pass = str_replace('\\', '\\\\', $user['password']);
1598
					$pass = str_replace('"', '\"', $pass);
1599
					$mpdsecret .= "{$user['name']} \"{$pass}\" {$user['ip']}\n";
1600
				}
1601
			}
1602

    
1603
			fwrite($fd, $mpdsecret);
1604
			fclose($fd);
1605
			unset($mpdsecret);
1606
			chmod("{$g['varetc_path']}/pptp-vpn/mpd.secret", 0600);
1607

    
1608
			vpn_netgraph_support();
1609

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

    
1613
			break;
1614

    
1615
		case 'redir':
1616
			break;
1617
	}
1618

    
1619
	if (platform_booting()) {
1620
		echo "done\n";
1621
	}
1622

    
1623
	return 0;
1624
}
1625

    
1626
function vpn_pppoes_configure() {
1627
	global $config;
1628

    
1629
	if (is_array($config['pppoes']['pppoe'])) {
1630
		foreach ($config['pppoes']['pppoe'] as $pppoe) {
1631
			vpn_pppoe_configure($pppoe);
1632
		}
1633
	}
1634
}
1635

    
1636
function vpn_pppoe_configure(&$pppoecfg) {
1637
	global $config, $g;
1638

    
1639
	$syscfg = $config['system'];
1640

    
1641
	/* create directory if it does not exist */
1642
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn")) {
1643
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1644
	}
1645

    
1646
	if (platform_booting()) {
1647
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off")) {
1648
			return 0;
1649
		}
1650

    
1651
		echo gettext("Configuring PPPoE Server service... ");
1652
	} else {
1653
		/* kill mpd */
1654
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1655

    
1656
		/* wait for process to die */
1657
		sleep(2);
1658

    
1659
	}
1660

    
1661
	switch ($pppoecfg['mode']) {
1662

    
1663
		case 'server':
1664

    
1665
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1666

    
1667
			if ($pppoecfg['paporchap'] == "chap") {
1668
				$paporchap = "set link enable chap";
1669
			} else {
1670
				$paporchap = "set link enable pap";
1671
			}
1672

    
1673
			/* write mpd.conf */
1674
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1675
			if (!$fd) {
1676
				printf(gettext("Error: cannot open mpd.conf in vpn_pppoe_configure().") . "\n");
1677
				return 1;
1678
			}
1679
			$mpdconf = "\n\n";
1680
			$mpdconf .= "poes:\n";
1681

    
1682
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1683
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1684
			}
1685

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

    
1688
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1689

    
1690
				if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1691
					$issue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1692
				} else {
1693
					$issue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1694
				}
1695

    
1696
				$mpdconf .=<<<EOD
1697

    
1698
poes{$pppoecfg['pppoeid']}{$i}:
1699
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1700
	{$issue_ip_type}
1701
	load pppoe_standard
1702

    
1703
EOD;
1704
			}
1705

    
1706
			$mpdconf .=<<<EOD
1707

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

    
1734
EOD;
1735

    
1736
			if (!empty($pppoecfg['dns1'])) {
1737
				$mpdconf .= "	set ipcp dns " . $pppoecfg['dns1'];
1738
				if (!empty($pppoecfg['dns2'])) {
1739
					$mpdconf .= " " . $pppoecfg['dns2'];
1740
				}
1741
				$mpdconf .= "\n";
1742
			} elseif (isset ($config['dnsmasq']['enable'])) {
1743
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1744
				if ($syscfg['dnsserver'][0]) {
1745
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1746
				}
1747
				$mpdconf .= "\n";
1748
			} elseif (isset ($config['unbound']['enable'])) {
1749
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1750
				if ($syscfg['dnsserver'][0]) {
1751
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1752
				}
1753
				$mpdconf .= "\n";
1754
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1755
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1756
			}
1757

    
1758
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1759
				$radiusport = "";
1760
				$radiusacctport = "";
1761
				if (isset($pppoecfg['radius']['server']['port'])) {
1762
					$radiusport = $pppoecfg['radius']['server']['port'];
1763
				}
1764
				if (isset($pppoecfg['radius']['server']['acctport'])) {
1765
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1766
				}
1767
				$mpdconf .=<<<EOD
1768
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
1769
	set radius retries 3
1770
	set radius timeout 10
1771
	set auth enable radius-auth
1772

    
1773
EOD;
1774

    
1775
				if (isset ($pppoecfg['radius']['accounting'])) {
1776
					$mpdconf .=<<<EOD
1777
	set auth enable radius-acct
1778

    
1779
EOD;
1780
				}
1781
			}
1782

    
1783
			fwrite($fd, $mpdconf);
1784
			fclose($fd);
1785
			unset($mpdconf);
1786

    
1787
			/* write mpd.links */
1788
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.links", "w");
1789
			if (!$fd) {
1790
				printf(gettext("Error: cannot open mpd.links in vpn_pppoe_configure().") . "\n");
1791
				return 1;
1792
			}
1793

    
1794
			$mpdlinks = "";
1795

    
1796
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1797
				$mpdlinks .=<<<EOD
1798

    
1799
poes{$pppoecfg['pppoeid']}{$i}:
1800
	set phys type pppoe
1801
	set pppoe iface {$pppoe_interface}
1802
	set pppoe service "*"
1803
	set pppoe disable originate
1804
	set pppoe enable incoming
1805

    
1806
EOD;
1807
			}
1808

    
1809
			fwrite($fd, $mpdlinks);
1810
			fclose($fd);
1811
			unset($mpdlinks);
1812

    
1813
			if ($pppoecfg['username']) {
1814
				/* write mpd.secret */
1815
				$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
1816
				if (!$fd) {
1817
					printf(gettext("Error: cannot open mpd.secret in vpn_pppoe_configure().") . "\n");
1818
					return 1;
1819
				}
1820

    
1821
				$mpdsecret = "\n\n";
1822

    
1823
				if (!empty($pppoecfg['username'])) {
1824
					$item = explode(" ", $pppoecfg['username']);
1825
					foreach ($item as $userdata) {
1826
						$data = explode(":", $userdata);
1827
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1828
					}
1829
				}
1830

    
1831
				fwrite($fd, $mpdsecret);
1832
				fclose($fd);
1833
				unset($mpdsecret);
1834
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1835
			}
1836

    
1837
			/* Check if previous instance is still up */
1838
			while (file_exists("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid") && isvalidpid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid")) {
1839
				killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1840
			}
1841

    
1842
			/* Get support for netgraph(4) from the nic */
1843
			pfSense_ngctl_attach(".", $pppoe_interface);
1844
			/* fire up mpd */
1845
			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");
1846

    
1847
			break;
1848
	}
1849

    
1850
	if (platform_booting()) {
1851
		echo gettext("done") . "\n";
1852
	}
1853

    
1854
	return 0;
1855
}
1856

    
1857
function vpn_l2tp_configure() {
1858
	global $config, $g;
1859

    
1860
	$syscfg = $config['system'];
1861
	$l2tpcfg = $config['l2tp'];
1862

    
1863
	/* create directory if it does not exist */
1864
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn")) {
1865
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1866
	}
1867

    
1868
	if (platform_booting()) {
1869
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off")) {
1870
			return 0;
1871
		}
1872

    
1873
		echo gettext("Configuring l2tp VPN service... ");
1874
	} else {
1875
		/* kill mpd */
1876
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1877

    
1878
		/* wait for process to die */
1879
		sleep(8);
1880

    
1881
	}
1882

    
1883
	/* make sure l2tp-vpn directory exists */
1884
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn")) {
1885
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1886
	}
1887

    
1888
	switch ($l2tpcfg['mode']) {
1889

    
1890
		case 'server':
1891
			if ($l2tpcfg['paporchap'] == "chap") {
1892
				$paporchap = "set link enable chap";
1893
			} else {
1894
				$paporchap = "set link enable pap";
1895
			}
1896

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

    
1907
EOD;
1908

    
1909
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1910
				$mpdconf .= "	load l2tp{$i}\n";
1911
			}
1912

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

    
1915
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1916

    
1917
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1918
					$issue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1919
				} else {
1920
					$issue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1921
				}
1922

    
1923
				$mpdconf .=<<<EOD
1924

    
1925
l2tp{$i}:
1926
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1927
	{$issue_ip_type}
1928
	load l2tp_standard
1929

    
1930
EOD;
1931
			}
1932

    
1933
			$mpdconf .=<<<EOD
1934

    
1935
l2tp_standard:
1936
	set bundle disable multilink
1937
	set bundle enable compression
1938
	set bundle yes crypt-reqd
1939
	set ipcp yes vjcomp
1940
	# set ipcp ranges 131.188.69.161/32 131.188.69.170/28
1941
	set ccp yes mppc
1942
	set iface disable on-demand
1943
	set iface enable proxy-arp
1944
	set iface up-script /usr/local/sbin/vpn-linkup
1945
	set iface down-script /usr/local/sbin/vpn-linkdown
1946
	set link yes acfcomp protocomp
1947
	set link no pap chap
1948
	{$paporchap}
1949
	set link keep-alive 10 180
1950

    
1951
EOD;
1952

    
1953
			if (is_ipaddr($l2tpcfg['wins'])) {
1954
				$mpdconf .= "	set ipcp nbns {$l2tpcfg['wins']}\n";
1955
			}
1956
			if (is_ipaddr($l2tpcfg['dns1'])) {
1957
				$mpdconf .= "	set ipcp dns " . $l2tpcfg['dns1'];
1958
				if (is_ipaddr($l2tpcfg['dns2'])) {
1959
					$mpdconf .= " " . $l2tpcfg['dns2'];
1960
				}
1961
				$mpdconf .= "\n";
1962
			} elseif (isset ($config['dnsmasq']['enable'])) {
1963
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1964
				if ($syscfg['dnsserver'][0]) {
1965
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1966
				}
1967
				$mpdconf .= "\n";
1968
			} elseif (isset ($config['unbound']['enable'])) {
1969
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1970
				if ($syscfg['dnsserver'][0]) {
1971
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1972
				}
1973
				$mpdconf .= "\n";
1974
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1975
				$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1976
			}
1977

    
1978
			if (isset ($l2tpcfg['radius']['enable'])) {
1979
				$mpdconf .=<<<EOD
1980
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1981
	set radius retries 3
1982
	set radius timeout 10
1983
	set auth enable radius-auth
1984

    
1985
EOD;
1986

    
1987
				if (isset ($l2tpcfg['radius']['accounting'])) {
1988
					$mpdconf .=<<<EOD
1989
	set auth enable radius-acct
1990

    
1991
EOD;
1992
				}
1993
			}
1994

    
1995
			fwrite($fd, $mpdconf);
1996
			fclose($fd);
1997
			unset($mpdconf);
1998

    
1999
			/* write mpd.links */
2000
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.links", "w");
2001
			if (!$fd) {
2002
				printf(gettext("Error: cannot open mpd.links in vpn_l2tp_configure().") . "\n");
2003
				return 1;
2004
			}
2005

    
2006
			$mpdlinks = "";
2007

    
2008
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
2009
				$mpdlinks .=<<<EOD
2010

    
2011
l2tp{$i}:
2012
	set link type l2tp
2013
	set l2tp enable incoming
2014
	set l2tp disable originate
2015

    
2016
EOD;
2017
				if (!empty($l2tpcfg['secret'])) {
2018
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
2019
				}
2020
			}
2021

    
2022
			fwrite($fd, $mpdlinks);
2023
			fclose($fd);
2024
			unset($mpdlinks);
2025

    
2026
			/* write mpd.secret */
2027
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.secret", "w");
2028
			if (!$fd) {
2029
				printf(gettext("Error: cannot open mpd.secret in vpn_l2tp_configure().") . "\n");
2030
				return 1;
2031
			}
2032

    
2033
			$mpdsecret = "\n\n";
2034

    
2035
			if (is_array($l2tpcfg['user'])) {
2036
				foreach ($l2tpcfg['user'] as $user) {
2037
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
2038
				}
2039
			}
2040

    
2041
			fwrite($fd, $mpdsecret);
2042
			fclose($fd);
2043
			unset($mpdsecret);
2044
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
2045

    
2046
			vpn_netgraph_support();
2047

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

    
2051
			break;
2052

    
2053
		case 'redir':
2054
			break;
2055
	}
2056

    
2057
	if (platform_booting()) {
2058
		echo "done\n";
2059
	}
2060

    
2061
	return 0;
2062
}
2063

    
2064
?>
(59-59/68)