Project

General

Profile

Download (58.8 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2

    
3
/*
4
	vpn.inc
5
	Copyright (C) 2004 Scott Ullrich
6
	Copyright (C) 2008 Shrew Soft Inc
7
	Copyright (C) 2008 Ermal Luçi
8
	All rights reserved.
9

    
10
	originally part of m0n0wall (http://m0n0.ch/wall)
11
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
12
	All rights reserved.
13

    
14
	Redistribution and use in source and binary forms, with or without
15
	modification, are permitted provided that the following conditions are met:
16

    
17
	1. Redistributions of source code must retain the above copyright notice,
18
	   this list of conditions and the following disclaimer.
19

    
20
	2. Redistributions in binary form must reproduce the above copyright
21
	   notice, this list of conditions and the following disclaimer in the
22
	   documentation and/or other materials provided with the distribution.
23

    
24
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
25
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
26
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
28
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33
	POSSIBILITY OF SUCH DAMAGE.
34
*/
35

    
36
/*
37
	pfSense_BUILDER_BINARIES:	/sbin/ifconfig
38
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/ipsec	/usr/local/libexec/ipsec/charon /usr/local/libexec/ipsec/starter
39
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/filterdns	/usr/local/sbin/mpd4
40
	pfSense_MODULE:	vpn
41
*/
42

    
43
require_once("ipsec.inc");
44
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 '22':
103
			$convertion = "modp1024s160";
104
			break;
105
		case '23':
106
			$convertion = "modp2048s224";
107
			break;
108
		case '24':
109
			$convertion = "modp2048s256";
110
			break;
111
		case '28':
112
			$convertion = "ecp256bp";
113
			break;
114
		case '29':
115
			$convertion = "ecp384bp";
116
			break;
117
		case '30':
118
			$convertion = "ecp512bp";
119
			break;
120
	}
121

    
122
	return $convertion;
123
}
124

    
125
function vpn_ipsec_configure($restart = false) {
126
	global $config, $g, $sa, $sn, $p1_ealgos, $p2_ealgos, $ipsec_idhandling;
127

    
128
	if ($g['platform'] == 'jail') {
129
		return;
130
	}
131

    
132
	/* get the automatic ping_hosts.sh ready */
133
	unlink_if_exists("{$g['vardb_path']}/ipsecpinghosts");
134
	touch("{$g['vardb_path']}/ipsecpinghosts");
135

    
136
	/* service may have been enabled, disabled, or otherwise changed in a way requiring rule updates */
137
	filter_configure();
138

    
139
	$syscfg = $config['system'];
140
	$ipseccfg = $config['ipsec'];
141
	if (!isset($ipseccfg['enable'])) {
142
		/* try to stop charon */
143
		mwexec("/usr/local/sbin/ipsec stop");
144
		/* Stop dynamic monitoring */
145
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
146

    
147
		/* wait for process to die */
148
		sleep(2);
149

    
150
		/* disallow IPSEC, it is off */
151
		mwexec("/sbin/ifconfig enc0 down");
152
		set_single_sysctl("net.inet.ip.ipsec_in_use", "0");
153

    
154
		return 0;
155
	}
156

    
157
	$a_phase1 = $config['ipsec']['phase1'];
158
	$a_phase2 = $config['ipsec']['phase2'];
159
	$a_client = $config['ipsec']['client'];
160

    
161
	$certpath = "{$g['varetc_path']}/ipsec/ipsec.d/certs";
162
	$capath = "{$g['varetc_path']}/ipsec/ipsec.d/cacerts";
163
	$keypath = "{$g['varetc_path']}/ipsec/ipsec.d/private";
164
	$crlpath = "{$g['varetc_path']}/ipsec/ipsec.d/crls";
165

    
166
	mwexec("/sbin/ifconfig enc0 up");
167
	set_single_sysctl("net.inet.ip.ipsec_in_use", "1");
168
	if (php_uname('m') != "amd64") {
169
		set_single_sysctl("net.inet.ipsec.directdispatch", "0");
170
	}
171

    
172
	/* needed for config files */
173
	if (!is_dir("{$g['varetc_path']}/ipsec")) {
174
		mkdir("{$g['varetc_path']}/ipsec");
175
	}
176
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d")) {
177
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d");
178
	}
179
	if (!is_dir($capath)) {
180
		mkdir($capath);
181
	}
182
	if (!is_dir($keypath)) {
183
		mkdir($keypath);
184
	}
185
	if (!is_dir($crlpath)) {
186
		mkdir($crlpath);
187
	}
188
	if (!is_dir($certpath)) {
189
		mkdir($certpath);
190
	}
191
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/aacerts")) {
192
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/aacerts");
193
	}
194
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/acerts")) {
195
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/acerts");
196
	}
197
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/ocspcerts")) {
198
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/ocspcerts");
199
	}
200
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/reqs")) {
201
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/reqs");
202
	}
203

    
204

    
205
	if (platform_booting()) {
206
		echo gettext("Configuring IPsec VPN... ");
207
	}
208

    
209
	/* fastforwarding is not compatible with ipsec tunnels */
210
	set_single_sysctl("net.inet.ip.fastforwarding", "0");
211

    
212
	/* resolve all local, peer addresses and setup pings */
213
	$ipmap = array();
214
	$rgmap = array();
215
	$filterdns_list = array();
216
	$listeniflist = array();
217
	$aggressive_mode_psk = false;
218
	unset($iflist);
219
	$ifacesuse = array();
220
	if (is_array($a_phase1) && count($a_phase1)) {
221

    
222
		$ipsecpinghosts = "";
223
		/* step through each phase1 entry */
224
		foreach ($a_phase1 as $ph1ent) {
225
			if (isset($ph1ent['disabled'])) {
226
				continue;
227
			}
228

    
229
			if (strpos($ph1ent['interface'], '_vip')) {
230
				$vpninterface = explode('_vip', $ph1ent['interface']);
231
				$ifacesuse[] = get_real_interface($vpninterface[0]);
232
			} else {
233
				$vpninterface = get_failover_interface($ph1ent['interface']);
234
				if (strpos($vpninterface, '_vip')) {
235
					$vpninterface = explode('_vip', $vpninterface);
236
					$ifacesuse[] = get_real_interface($vpninterface[0]);
237
				} elseif (!empty($vpninterface)) {
238
					$ifacesuse[] = $vpninterface;
239
				}
240
			}
241

    
242
			if ($ph1ent['mode'] == "aggressive" && ($ph1ent['authentication_method'] == "pre_shared_key" || $ph1ent['authentication_method'] == "xauth_psk_server")) {
243
				$aggressive_mode_psk = true;
244
			}
245

    
246
			$ikeid = $ph1ent['ikeid'];
247
			$listeniflist = get_real_interface($a_phase1['interface']);
248

    
249
			$ep = ipsec_get_phase1_src($ph1ent);
250
			if (!is_ipaddr($ep)) {
251
				log_error("IPsec ERROR: Could not find phase 1 source for connection {$ph1ent['descr']}. Omitting from configuration file.");
252
				continue;
253
			}
254

    
255
			if (!in_array($ep, $ipmap)) {
256
				$ipmap[] = $ep;
257
			}
258

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

    
262
			if (isset ($ph1ent['mobile'])) {
263
				continue;
264
			}
265

    
266
			$rg = $ph1ent['remote-gateway'];
267

    
268
			if (!is_ipaddr($rg)) {
269
				$filterdns_list[] = "{$rg}";
270
				add_hostname_to_watch($rg);
271
				if (!platform_booting()) {
272
					$rg = resolve_retry($rg);
273
				}
274
				if (!is_ipaddr($rg)) {
275
					continue;
276
				}
277
			}
278
			if (array_search($rg, $rgmap)) {
279
				log_error("The remote gateway {$rg} already exists on another phase 1 entry");
280
				continue;
281
			}
282
			$rgmap[$ph1ent['remote-gateway']] = $rg;
283

    
284
			if (is_array($a_phase2)) {
285
				/* step through each phase2 entry */
286
				foreach ($a_phase2 as $ph2ent) {
287
					if (isset($ph2ent['disabled'])) {
288
						continue;
289
					}
290

    
291
					if ($ikeid != $ph2ent['ikeid']) {
292
						continue;
293
					}
294

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

    
353
	$accept_unencrypted = "";
354
	if (isset($config['ipsec']['acceptunencryptedmainmode'])) {
355
		$accept_unencrypted = "accept_unencrypted_mainmode_messages = yes";
356
	}
357

    
358
	$stronconf = '';
359
	if (file_exists("{$g['varetc_path']}/ipsec/strongswan.conf")) {
360
		$stronconf = file_get_contents("{$g['varetc_path']}/ipsec/strongswan.conf");
361
	}
362

    
363
	$i_dont_care_about_security_and_use_aggressive_mode_psk = "";
364
	if ($aggressive_mode_psk) {
365
		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.");
366
		if (!empty($stronconf) && strpos($stronconf, 'i_dont_care_about_security_and_use_aggressive_mode_psk') === FALSE) {
367
			$restart = true;
368
		}
369
		$i_dont_care_about_security_and_use_aggressive_mode_psk = "i_dont_care_about_security_and_use_aggressive_mode_psk=yes";
370
	}
371

    
372
	$unity_enabled = 'yes';
373
	if (isset($config['ipsec']['unityplugin'])) {
374
		$unity_enabled = 'no';
375
		if (file_exists("/usr/local/lib/ipsec/plugins/libstrongswan-unity.so")) {
376
			conf_mount_rw();
377
			mwexec("mv /usr/local/lib/ipsec/plugins/libstrongswan-unity.so /usr/local/lib/ipsec/plugins/libstrongswan-unity.MOVED");
378
			conf_mount_ro();
379
		}
380
	} else if (file_exists("/usr/local/lib/ipsec/plugins/libstrongswan-unity.MOVED")) {
381
		conf_mount_rw();
382
		mwexec("mv /usr/local/lib/ipsec/plugins/libstrongswan-unity.MOVED /usr/local/lib/ipsec/plugins/libstrongswan-unity.so");
383
		conf_mount_ro();
384
	}
385

    
386
	$makebeforebreak = '';
387
	if (isset($config['ipsec']['makebeforebreak'])) {
388
		$makebeforebreak = 'make_before_break = yes';
389
	}
390

    
391
	if (isset($config['ipsec']['enableinterfacesuse'])) {
392
		if (!empty($ifacesuse)) {
393
			$ifacesuse = 'interfaces_use = ' . implode(',', array_unique($ifacesuse));
394
		} else {
395
			$ifacesuse = '';
396
		}
397
	} else {
398
		$ifacesuse = '';
399
	}
400

    
401
	unset($stronconf);
402

    
403
	$strongswan = <<<EOD
404

    
405
# Automatically generated config file - DO NOT MODIFY. Changes will be overwritten.
406
starter {
407
load_warning = no
408
}
409

    
410
charon {
411
# number of worker threads in charon
412
threads = 16
413
ikesa_table_size = 32
414
ikesa_table_segments = 4
415
init_limit_half_open = 1000
416
install_routes = no
417
{$i_dont_care_about_security_and_use_aggressive_mode_psk}
418
{$accept_unencrypted}
419
cisco_unity = {$unity_enabled}
420
{$ifacesuse}
421
{$makebeforebreak}
422

    
423
# And two loggers using syslog. The subsections define the facility to log
424
# to, currently one of: daemon, auth.
425
syslog {
426
	identifier = charon
427
	# default level to the LOG_DAEMON facility
428
	daemon {
429
		ike_name = yes
430
	}
431
	# very minimalistic IKE auditing logs to LOG_AUTHPRIV
432
	auth {
433
		default = -1
434
		ike = 1
435
		ike_name = yes
436
	}
437
}
438

    
439
EOD;
440

    
441
	$strongswan .= "\tplugins {\n";
442

    
443
	$a_servers = auth_get_authserver_list();
444
	foreach ($a_servers as $id => $pconfig) {
445
		if ($id == $config['ipsec']['client']['user_source'] && $pconfig['type'] == "radius") {
446
			$strongswan .= <<<EOD
447
		eap-radius {
448
			class_group = yes
449
			eap_start = no
450
			servers {
451
				primary {
452
					address = {$pconfig['host']}
453
					secret = {$pconfig['radius_secret']}
454
					auth_port = {$pconfig['radius_auth_port']}
455
					acct_port = {$pconfig['radius_acct_port']}
456
				}
457
			}
458
		}
459

    
460
EOD;
461
			break;
462
		}
463
	}
464

    
465
	if (is_array($a_client) && isset($a_client['enable'])) {
466
		$strongswan .= "\t\tattr {\n";
467
		if ($a_client['pool_address'] && $a_client['pool_netbits']) {
468
			$strongswan .= "\t\t\tsubnet = {$a_client['pool_address']}/{$a_client['pool_netbits']}\n";
469
		}
470

    
471
		$cfgservers = array();
472
		if (!empty($a_client['dns_server1'])) {
473
			$cfgservers[] = $a_client['dns_server1'];
474
		}
475
		if (!empty($a_client['dns_server2'])) {
476
			$cfgservers[] = $a_client['dns_server2'];
477
		}
478
		if (!empty($a_client['dns_server3'])) {
479
			$cfgservers[] = $a_client['dns_server3'];
480
		}
481
		if (!empty($a_client['dns_server4'])) {
482
			$cfgservers[] = $a_client['dns_server4'];
483
		}
484

    
485
		if (!empty($cfgservers)) {
486
			$strongswan .= "\t\t\tdns = " . implode(",", $cfgservers) . "\n";
487
		}
488
		unset($cfgservers);
489
		$cfgservers = array();
490
		if (!empty($a_client['wins_server1'])) {
491
			$cfgservers[] = $a_client['wins_server1'];
492
		}
493
		if (!empty($a_client['wins_server2'])) {
494
			$cfgservers[] = $a_client['wins_server2'];
495
		}
496
		if (!empty($cfgservers)) {
497
			$strongswan .= "\t\t\tnbns = " . implode(",", $cfgservers) . "\n";
498
		}
499
		unset($cfgservers);
500

    
501
		if (isset($a_client['net_list']) && is_array($a_phase2)) {
502
			$net_list = '';
503
			foreach ($a_phase2 as $ph2ent) {
504
				if (isset($ph2ent['disabled'])) {
505
					continue;
506
				}
507

    
508
				if (!isset($ph2ent['mobile'])) {
509
					continue;
510
				}
511

    
512
				$localid = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
513

    
514
				if (!empty($net_list)) {
515
					$net_list .= ",";
516
				}
517
				$net_list .= $localid;
518
			}
519

    
520
			if (!empty($net_list)) {
521
				$strongswan .= "\t\t\tsplit-include = {$net_list}\n";
522
				unset($net_list);
523
			}
524
		}
525

    
526
		if (!empty($a_client['dns_domain'])) {
527
			$strongswan .= "\t\t\t# Search domain and default domain\n";
528
			$strongswan .= "\t\t\t28674 = \"{$a_client['dns_domain']}\"\n";
529
			if (empty($a_client['dns_split'])) {
530
				$strongswan .= "\t\t\t28675 = \"{$a_client['dns_domain']}\"";
531
			}
532
			$strongswan .= "\n";
533
		}
534

    
535
		if (!empty($a_client['dns_split'])) {
536
			$strongswan .= "\t\t\t28675 = {$a_client['dns_split']}\n";
537
		}
538

    
539
		if (!empty($a_client['login_banner'])) {
540
			$strongswan .= "\t\t\t28672 = \"{$a_client['login_banner']}\"\n";
541
		}
542

    
543
		if (isset($a_client['save_passwd'])) {
544
			$strongswan .= "\t\t\t28673 = 1\n";
545
		}
546

    
547
		if ($a_client['pfs_group']) {
548
			$strongswan .= "\t\t\t28679 = \"{$a_client['pfs_group']}\"\n";
549
		}
550
		$strongswan .= "\t\t}\n";
551

    
552
		if ($a_client['user_source'] != "none") {
553
			$strongswan .= "\t\txauth-generic {\n";
554
			$strongswan .= "\t\t\tscript = /etc/inc/ipsec.auth-user.php\n";
555
			$strongswan .= "\t\t\tauthcfg = ";
556
			$firstsed = 0;
557
			$authcfgs = explode(",", $a_client['user_source']);
558
			foreach ($authcfgs as $authcfg) {
559
				if ($firstsed > 0) {
560
					$strongswan .= ",";
561
				}
562
				if ($authcfg == "system") {
563
					$authcfg = "Local Database";
564
				}
565
				$strongswan .= $authcfg;
566
				$firstsed = 1;
567
			}
568
			$strongswan .= "\n";
569
			$strongswan .= "\t\t}\n";
570
		}
571
	}
572

    
573
	$strongswan .= "\t}\n}\n";
574
	@file_put_contents("{$g['varetc_path']}/ipsec/strongswan.conf", $strongswan);
575
	unset($strongswan);
576

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

    
614
	$pskconf = "";
615

    
616
	if (is_array($a_phase1) && count($a_phase1)) {
617
		foreach ($a_phase1 as $ph1ent) {
618

    
619
			if (isset($ph1ent['disabled'])) {
620
				continue;
621
			}
622

    
623
			if (strstr($ph1ent['authentication_method'], 'rsa') ||
624
			    in_array($ph1ent['authentication_method'], array('eap-mschapv2', 'eap-tls', 'eap-radius'))) {
625
				$certline = '';
626

    
627
				$ikeid = $ph1ent['ikeid'];
628
				$cert = lookup_cert($ph1ent['certref']);
629

    
630
				if (!$cert) {
631
					log_error(sprintf(gettext("Error: Invalid phase1 certificate reference for %s"), $ph1ent['name']));
632
					continue;
633
				}
634

    
635
				@chmod($certpath, 0600);
636

    
637
				$ph1keyfile = "{$keypath}/cert-{$ikeid}.key";
638
				if (!file_put_contents($ph1keyfile, base64_decode($cert['prv']))) {
639
					log_error(sprintf(gettext("Error: Cannot write phase1 key file for %s"), $ph1ent['name']));
640
					continue;
641
				}
642
				@chmod($ph1keyfile, 0600);
643

    
644
				$ph1certfile = "{$certpath}/cert-{$ikeid}.crt";
645
				if (!file_put_contents($ph1certfile, base64_decode($cert['crt']))) {
646
					log_error(sprintf(gettext("Error: Cannot write phase1 certificate file for %s"), $ph1ent['name']));
647
					@unlink($ph1keyfile);
648
					continue;
649
				}
650
				@chmod($ph1certfile, 0600);
651

    
652
				/* XXX" Traffic selectors? */
653
				$pskconf .= " : RSA {$ph1keyfile}\n";
654
			} else {
655
				list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, 'local');
656
				list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, 'peer', $rgmap);
657
				
658
				$myid = trim($myid_data);
659

    
660
				if (empty($peerid_data)) {
661
					continue;
662
				}
663

    
664
				if ($myid_type == 'fqdn' && !empty($myid)) {
665
					$myid = "@{$myid}";
666
				}
667
				
668
				$myid = isset($ph1ent['mobile']) ? trim($myid_data) : "%any";
669

    
670
				$peerid = ($peerid_data != 'allusers') ? trim($peerid_data) : '';
671

    
672
				if ($peerid_type == 'fqdn' && !empty($peerid)) {
673
					$peerid = "@{$peerid}";
674
				}
675

    
676
				if (!empty($ph1ent['pre-shared-key'])) {
677
					$pskconf .= "{$myid} {$peerid} : PSK 0s" . base64_encode(trim($ph1ent['pre-shared-key'])) . "\n";
678
				}
679
			}
680
		}
681
	}
682

    
683
	/* Add user PSKs */
684
	if (is_array($config['system']) && is_array($config['system']['user'])) {
685
		foreach ($config['system']['user'] as $user) {
686
			if (!empty($user['ipsecpsk'])) {
687
				$pskconf .= "{$myid} {$user['name']} : PSK 0s" . base64_encode($user['ipsecpsk']) . "\n";
688
			}
689
		}
690
		unset($user);
691
	}
692

    
693
	/* add PSKs for mobile clients */
694
	if (is_array($ipseccfg['mobilekey'])) {
695
		foreach ($ipseccfg['mobilekey'] as $key) {
696
			if ($key['ident'] == "allusers") {
697
				$key['ident'] = '%any';
698
			}
699
			if (empty($key['type'])) {
700
				$key['type'] = 'PSK';
701
			}
702
			$pskconf .= "{$myid} {$key['ident']} : {$key['type']} 0s" . base64_encode($key['pre-shared-key']) . "\n";
703
		}
704
		unset($key);
705
	}
706

    
707
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.secrets", $pskconf);
708
	chmod("{$g['varetc_path']}/ipsec/ipsec.secrets", 0600);
709
	unset($pskconf);
710

    
711
	$uniqueids = 'yes';
712
	if (!empty($config['ipsec']['uniqueids'])) {
713
		if (array_key_exists($config['ipsec']['uniqueids'], $ipsec_idhandling)) {
714
			$uniqueids = $config['ipsec']['uniqueids'];
715
		}
716
	}
717
	$natfilterrules = false;
718
	/* begin ipsec.conf */
719
	$ipsecconf = "";
720
	$enablecompression = false;
721
	if (is_array($a_phase1) && count($a_phase1)) {
722

    
723
		$ipsecconf .= "# This file is automatically generated. Do not edit\n";
724
		$ipsecconf .= "config setup\n\tuniqueids = {$uniqueids}\n";
725
		$ipsecconf .= "\tcharondebug=\"" . vpn_ipsec_configure_loglevels(true) . "\"\n";
726
		
727
		if (isset($config['ipsec']['strictcrlpolicy'])) {
728
			$ipsecconf .= "\tstrictcrlpolicy = yes \n";
729
		}
730

    
731
		if (!isset($config['ipsec']['noshuntlaninterfaces'])) {
732
			if ($config['interfaces']['lan']) {
733
				$lanip = get_interface_ip("lan");
734
				if (!empty($lanip) && is_ipaddrv4($lanip)) {
735
					$lansn = get_interface_subnet("lan");
736
					$lansa = gen_subnet($lanip, $lansn);
737
					$ipsecconf .= <<<EOD
738

    
739
conn bypasslan
740
	leftsubnet = {$lansa}/{$lansn}
741
	rightsubnet = {$lansa}/{$lansn}
742
	authby = never
743
	type = passthrough
744
	auto = route
745

    
746
EOD;
747
				}
748
			}
749
		}
750

    
751
		foreach ($a_phase1 as $ph1ent) {
752
			if (isset($ph1ent['disabled'])) {
753
				continue;
754
			}
755

    
756
			if ($ph1ent['mode'] == "aggressive") {
757
				$aggressive = "yes";
758
			} else {
759
				$aggressive = "no";
760
			}
761

    
762
			$ep = ipsec_get_phase1_src($ph1ent);
763
			if (!$ep) {
764
				continue;
765
			}
766

    
767
			$ikeid = $ph1ent['ikeid'];
768
			$keyexchange = "ikev1";
769
			$passive = "route";
770
			if (!empty($ph1ent['iketype'])) {
771
				if ($ph1ent['iketype'] == "ikev2") {
772
					$keyexchange = "ikev2";
773
					//$passive = "start";
774
				} 
775
			}
776

    
777
			if (isset($ph1ent['mobile'])) {
778
				$right_spec = "%any";
779
				$passive = 'add';
780
			} else {
781
				if (isset($ph1ent['responderonly'])) {
782
					$passive = 'add';
783
				}
784

    
785
				$right_spec = $ph1ent['remote-gateway'];
786
				if (is_ipaddr($right_spec)) {
787
					$sourcehost = $right_spec;
788
				} else {
789
					$sourcehost = $rgmap['remote-gateway'];
790
				}
791

    
792
				if ($ph1ent['protocol'] == 'inet') {
793
					if (strpos($ph1ent['interface'], '_vip')) {
794
						$vpninterface = explode('_vip', $ph1ent['interface']);
795
						$ifacesuse = get_real_interface($vpninterface[0]);
796
						$vpninterface = $vpninterface[0];
797
					} else {
798
						$ifacesuse = get_failover_interface($ph1ent['interface']);
799
						if (strpos($ifacesuse, '_vip')) {
800
							$vpninterface = explode('_vip', $ifacesuse);
801
							$ifacesuse = get_real_interface($vpninterface[0]);
802
							$vpninterface = $vpninterface[0];
803
						} else {
804
							$vpninterface = convert_real_interface_to_friendly_interface_name($ifacesuse);
805
						}
806
					}
807

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

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

    
853
			list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, 'local');
854
			if ($myid_type != 'address' && $myid_type != 'keyid' && $myid_type != 'asn1dn') {
855
				$myid_data = "{$myid_type}:{$myid_data}";
856
			} elseif ($myid_type == "asn1dn" && !empty($myid_data)) {
857
				if ($myid_data[0] == '#') {
858
				/* asn1dn needs double quotes */
859
					$myid_data = "\"{$myid_type}:{$myid_data}\"";
860
				} else {
861
					$myid_data = "\"{$myid_data}\"";
862
				}
863
			}
864
			$leftid = '';
865
			if (!empty($myid_data)) {
866
				$leftid = "leftid = {$myid_data}";
867
			}
868

    
869
			$peerid_spec = '';
870
			if (isset($ph1ent['mobile']) && ($ph1ent['authentication_method'] == "pre_shared_key" || $ph1ent['authentication_method'] == "xauth_psk_server")) {
871
				// Only specify peer ID if we are not dealing with mobile PSK
872
			} else {
873
				list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, 'peer', $rgmap);
874
				if ($peerid_type == 'any') {
875
					$peerid_spec = '';
876
				} elseif ($peerid_type != 'address' && $peerid_type != 'keyid' && $peerid_type != 'asn1dn') {
877
					$peerid_spec = "{$peerid_type}:{$peerid_data}";
878
				} elseif ($peerid_type == "asn1dn") {
879
					/* asn1dn needs double quotes */
880
					if ($peerid_data[0] == '#') {
881
						$peerid_spec = "\"{$peerid_type}:{$peerid_data}\"";
882
					} elseif (!empty($peerid_data)) {
883
						$peerid_spec = "\"{$peerid_data}\"";
884
					}
885
				} else {
886
					$peerid_spec = $peerid_data;
887
				}
888
			}
889

    
890
			if (is_array($ph1ent['encryption-algorithm']) && !empty($ph1ent['encryption-algorithm']['name']) && !empty($ph1ent['hash-algorithm'])) {
891
				$ealgosp1 = '';
892
				$ealg_id = $ph1ent['encryption-algorithm']['name'];
893
				$ealg_kl = $ph1ent['encryption-algorithm']['keylen'];
894
				if ($ealg_kl) {
895
					$ealgosp1 = "ike = {$ealg_id}{$ealg_kl}-{$ph1ent['hash-algorithm']}";
896
				} else {
897
					$ealgosp1 = "ike = {$ealg_id}-{$ph1ent['hash-algorithm']}";
898
				}
899

    
900
				$modp = vpn_ipsec_convert_to_modp($ph1ent['dhgroup']);
901
				if (!empty($modp)) {
902
					$ealgosp1 .= "-{$modp}";
903
				}
904

    
905
				$ealgosp1 .= "!";
906
			}
907

    
908
			if ($ph1ent['dpd_delay'] && $ph1ent['dpd_maxfail']) {
909
				if ($passive == "route") {
910
					$dpdline = "dpdaction = restart";
911
				} else {
912
					$dpdline = "dpdaction = clear";
913
				}
914
				$dpdline .= "\n\tdpddelay = {$ph1ent['dpd_delay']}s";
915
				$dpdtimeout = $ph1ent['dpd_delay'] * ($ph1ent['dpd_maxfail'] + 1);
916
				$dpdline .= "\n\tdpdtimeout = {$dpdtimeout}s";
917
			} else {
918
				$dpdline = "dpdaction = none";
919
			}
920

    
921
			$ikelifeline = '';
922
			if ($ph1ent['lifetime']) {
923
				$ikelifeline = "ikelifetime = {$ph1ent['lifetime']}s";
924
			}
925

    
926
			$rightsourceip = NULL;
927
			if (isset($ph1ent['mobile']) && !empty($a_client['pool_address'])) {
928
				$rightsourceip = "\trightsourceip = {$a_client['pool_address']}/{$a_client['pool_netbits']}\n";
929
			}
930

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

    
999
			$left_spec = $ep;
1000

    
1001
			if (isset($ph1ent['reauth_enable'])) {
1002
				$reauth = "reauth = no";
1003
			} else {
1004
				$reauth = "reauth = yes";
1005
			}
1006
			if (isset($ph1ent['rekey_enable'])) {
1007
				$rekey = "rekey = no";
1008
			} else {
1009
				$rekey = "rekey = yes";
1010
			}
1011

    
1012
			if ($ph1ent['nat_traversal'] == 'off') {
1013
				$forceencaps = 'forceencaps = no';
1014
			} else if ($ph1ent['nat_traversal'] == 'force') {
1015
				$forceencaps = 'forceencaps = yes';
1016
			} else {
1017
				$forceencaps = 'forceencaps = no';
1018
			}
1019

    
1020
			if ($ph1ent['mobike'] == 'on') {
1021
				$mobike = 'mobike = yes';
1022
			} else {
1023
				$mobike = 'mobike = no';
1024
			}
1025

    
1026
			$ipseclifetime = 0;
1027
			$rightsubnet_spec = array();
1028
			$leftsubnet_spec = array();
1029
			$reqids = array();
1030
			$ealgoAHsp2arr = array();
1031
			$ealgoESPsp2arr = array();
1032
		if (is_array($a_phase2) && count($a_phase2)) {
1033
			foreach ($a_phase2 as $ph2ent) {
1034
				if ($ikeid != $ph2ent['ikeid']) {
1035
					continue;
1036
				}
1037

    
1038
				if (isset($ph2ent['disabled'])) {
1039
					continue;
1040
				}
1041

    
1042
				if (isset($ph2ent['mobile']) && !isset($a_client['enable'])) {
1043
					continue;
1044
				}
1045

    
1046
				if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
1047
					$tunneltype = "type = tunnel";
1048

    
1049
					$localid_type = $ph2ent['localid']['type'];
1050
					$leftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['localid'], false, $ph2ent['mode']);
1051

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

    
1080
					$leftsubnet_spec[] = $leftsubnet_data;
1081

    
1082
					if (!isset($ph2ent['mobile'])) {
1083
						$tmpsubnet = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']);
1084
						$rightsubnet_spec[] = $tmpsubnet;
1085
					} else if (!empty($a_client['pool_address'])) {
1086
						$rightsubnet_spec[] = "{$a_client['pool_address']}/{$a_client['pool_netbits']}";
1087
					}
1088
				} else {
1089
					$tunneltype = "type = transport";
1090

    
1091
					if ((($ph1ent['authentication_method'] == "xauth_psk_server") ||
1092
					    ($ph1ent['authentication_method'] == "pre_shared_key")) && isset($ph1ent['mobile'])) {
1093
						$left_spec = "%any";
1094
					} else {
1095
						$tmpsubnet = ipsec_get_phase1_src($ph1ent);
1096
						$leftsubnet_spec[] = $tmpsubnet;
1097
					}
1098

    
1099
					if (!isset($ph2ent['mobile'])) {
1100
						$rightsubnet_spec[] = $right_spec;
1101
					}
1102
				}
1103

    
1104
				if (isset($a_client['pfs_group']) && isset($ph2ent['mobile'])) {
1105
					$ph2ent['pfsgroup'] = $a_client['pfs_group'];
1106
				}
1107

    
1108
				if ($ph2ent['protocol'] == 'esp') {
1109
					if (is_array($ph2ent['encryption-algorithm-option'])) {
1110
						foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
1111
							$ealg_id = $ealg['name'];
1112
							$ealg_kl = $ealg['keylen'];
1113

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

    
1181
				$reqids[] = $ph2ent['reqid'];
1182

    
1183
				if (!empty($ph2ent['lifetime'])) {
1184
					if ($ipseclifetime == 0 || intval($ipseclifetime) > intval($ph2ent['lifetime'])) {
1185
						$ipseclifetime = intval($ph2ent['lifetime']);
1186
					}
1187
				}
1188

    
1189
			}
1190
		}
1191

    
1192
			$ipsecconnect =<<<EOD
1193
	fragmentation = yes
1194
	keyexchange = {$keyexchange}
1195
	{$reauth}
1196
	{$forceencaps}
1197
	{$mobike}
1198
	{$rekey}
1199
	installpolicy = yes
1200
	{$tunneltype}
1201
	{$dpdline}
1202
	auto = {$passive}
1203
	left = {$left_spec}
1204
	right = {$right_spec}
1205
	{$leftid}
1206

    
1207
EOD;
1208

    
1209
			if (isset($config['ipsec']['compression'])) {
1210
				$ipsecconnect .= "\tcompress = yes\n";
1211
				$enablecompression = true;
1212
			}
1213
			if (!empty($ikelifeline)) {
1214
				$ipsecconnect .= "\t{$ikelifeline}\n";
1215
			}
1216
			if ($ipseclifetime > 0) {
1217
				$ipsecconnect .= "\tlifetime = {$ipseclifetime}s\n";
1218
			}
1219
			if (!empty($rightsourceip)) {
1220
				$ipsecconnect .= "{$rightsourceip}";
1221
			}
1222
			if (!empty($ealgosp1)) {
1223
				$ipsecconnect .= "\t{$ealgosp1}\n";
1224
			}
1225
			if (!empty($ealgoAHsp2arr)) {
1226
				$ipsecconnect .= "\tah = " . join(',', $ealgoAHsp2arr) . "!\n";
1227
			}
1228
			if (!empty($ealgoESPsp2arr)) {
1229
				$ipsecconnect .= "\tesp = " . join(',', $ealgoESPsp2arr) . "!\n";
1230
			}
1231
			if (!empty($authentication)) {
1232
				$ipsecconnect .= "\t{$authentication}\n";
1233
			}
1234
			if (!empty($peerid_spec)) {
1235
				$ipsecconnect .= "\trightid = {$peerid_spec}\n";
1236
			}
1237
			if ($keyexchange == 'ikev1') {
1238
				$ipsecconnect .= "\taggressive = {$aggressive}\n";
1239
			}
1240

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

    
1284
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.conf", $ipsecconf);
1285
	unset($ipsecconf);
1286
	/* end ipsec.conf */
1287

    
1288
	if ($enablecompression === true) {
1289
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 1);
1290
	} else {
1291
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 0);
1292
	}
1293

    
1294
	/* manage process */
1295
	if ($restart === true) {
1296
		mwexec("/usr/local/sbin/ipsec restart", false);
1297
	} else {
1298
		if (isvalidpid("{$g['varrun_path']}/starter.charon.pid")) {
1299
			/* Update configuration changes */
1300
			/* Read secrets */
1301
			mwexec("/usr/local/sbin/ipsec rereadall", false);
1302
			mwexec("/usr/local/sbin/ipsec reload", false);
1303
		} else {
1304
			mwexec("/usr/local/sbin/ipsec start", false);
1305
		}
1306
	}
1307

    
1308
	if ($natfilterrules == true) {
1309
		filter_configure();
1310
	}
1311
	/* start filterdns, if necessary */
1312
	if (count($filterdns_list) > 0) {
1313
		$interval = 60;
1314
		if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval'])) {
1315
			$interval = $ipseccfg['dns-interval'];
1316
		}
1317

    
1318
		$hostnames = "";
1319
		array_unique($filterdns_list);
1320
		foreach ($filterdns_list as $hostname) {
1321
			$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload ipsecdns\"'\n";
1322
		}
1323
		file_put_contents("{$g['varetc_path']}/ipsec/filterdns-ipsec.hosts", $hostnames);
1324
		unset($hostnames);
1325

    
1326
		if (isvalidpid("{$g['varrun_path']}/filterdns-ipsec.pid")) {
1327
			sigkillbypid("{$g['varrun_path']}/filterdns-ipsec.pid", "HUP");
1328
		} else {
1329
			mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/ipsec/filterdns-ipsec.hosts -d 1");
1330
		}
1331
	} else {
1332
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
1333
		@unlink("{$g['varrun_path']}/filterdns-ipsec.pid");
1334
	}
1335

    
1336
	if (platform_booting()) {
1337
		echo "done\n";
1338
	}
1339

    
1340
	return count($filterdns_list);
1341
}
1342

    
1343
/*
1344
 * Forcefully restart IPsec
1345
 * This is required for when dynamic interfaces reload
1346
 * For all other occasions the normal vpn_ipsec_configure()
1347
 * will gracefully reload the settings without restarting
1348
 */
1349
function vpn_ipsec_force_reload($interface = "") {
1350
	global $g, $config;
1351

    
1352
	$ipseccfg = $config['ipsec'];
1353

    
1354
	if (!empty($interface) && is_array($ipseccfg['phase1'])) {
1355
		$found = false;
1356
		foreach ($ipseccfg['phase1'] as $ipsec) {
1357
			if (!isset($ipsec['disabled']) && ($ipsec['interface'] == $interface)) {
1358
				$found = true;
1359
				break;
1360
			}
1361
		}
1362
		if (!$found) {
1363
			log_error(sprintf(gettext("Ignoring IPsec reload since there are no tunnels on interface %s"), $interface));
1364
			return;
1365
		}
1366
	}
1367

    
1368
	/* if ipsec is enabled, start up again */
1369
	if (isset($ipseccfg['enable'])) {
1370
		log_error(gettext("Forcefully reloading IPsec"));
1371
		vpn_ipsec_configure();
1372
	}
1373
}
1374

    
1375
/* master setup for vpn (mpd) */
1376
function vpn_setup() {
1377
	global $g;
1378

    
1379
	if ($g['platform'] == 'jail') {
1380
		return;
1381
	}
1382

    
1383
	/* start pptpd */
1384
	vpn_pptpd_configure();
1385

    
1386
	/* start pppoe server */
1387
	vpn_pppoes_configure();
1388

    
1389
	/* setup l2tp */
1390
	vpn_l2tp_configure();
1391
}
1392

    
1393
function vpn_netgraph_support() {
1394
	$iflist = get_configured_interface_list();
1395
	foreach ($iflist as $iface) {
1396
		$realif = get_real_interface($iface);
1397
		/* Get support for netgraph(4) from the nic */
1398
		$ifinfo = pfSense_get_interface_addresses($realif);
1399
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge"))) {
1400
			pfSense_ngctl_attach(".", $realif);
1401
		}
1402
	}
1403
}
1404

    
1405
function vpn_pptpd_configure() {
1406
	global $config, $g;
1407

    
1408
	$syscfg = $config['system'];
1409
	$pptpdcfg = $config['pptpd'];
1410

    
1411
	if (platform_booting()) {
1412
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off")) {
1413
			return 0;
1414
		}
1415

    
1416
		if (platform_booting(true)) {
1417
			echo gettext("Configuring PPTP VPN service... ");
1418
		}
1419
	} else {
1420
		/* kill mpd */
1421
		killbypid("{$g['varrun_path']}/pptp-vpn.pid");
1422

    
1423
		/* wait for process to die */
1424
		sleep(3);
1425

    
1426
		if (is_process_running("mpd -b")) {
1427
			killbypid("{$g['varrun_path']}/pptp-vpn.pid");
1428
			log_error(gettext("Could not kill mpd within 3 seconds.   Trying again."));
1429
		}
1430

    
1431
		/* remove mpd.conf, if it exists */
1432
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.conf");
1433
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.links");
1434
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.secret");
1435
	}
1436

    
1437
	if (empty($pptpdcfg['n_pptp_units'])) {
1438
		log_error("Something wrong in the PPTPd configuration. Preventing starting the daemon because issues would arise.");
1439
		return;
1440
	}
1441

    
1442
	/* make sure pptp-vpn directory exists */
1443
	if (!file_exists("{$g['varetc_path']}/pptp-vpn")) {
1444
		mkdir("{$g['varetc_path']}/pptp-vpn");
1445
	}
1446

    
1447
	switch ($pptpdcfg['mode']) {
1448
		case 'server':
1449
			/* write mpd.conf */
1450
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.conf", "w");
1451
			if (!$fd) {
1452
				printf(gettext("Error: cannot open mpd.conf in vpn_pptpd_configure().") . "\n");
1453
				return 1;
1454
			}
1455

    
1456
			$mpdconf = <<<EOD
1457
pptps:
1458

    
1459
EOD;
1460

    
1461
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1462
				$mpdconf .= "	load pt{$i}\n";
1463
			}
1464

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

    
1467
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
1468

    
1469
				$mpdconf .= <<<EOD
1470

    
1471
pt{$i}:
1472
	new -i pptpd{$i} pt{$i} pt{$i}
1473
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
1474
	load pts
1475

    
1476
EOD;
1477
			}
1478

    
1479
			$mpdconf .=<<<EOD
1480

    
1481
pts:
1482
	set iface disable on-demand
1483
	set iface enable proxy-arp
1484
	set iface enable tcpmssfix
1485
	set iface idle 1800
1486
	set iface up-script /usr/local/sbin/vpn-linkup
1487
	set iface down-script /usr/local/sbin/vpn-linkdown
1488
	set bundle enable multilink
1489
	set bundle enable crypt-reqd
1490
	set link yes acfcomp protocomp
1491
	set link no pap chap
1492
	set link enable chap-msv2
1493
	set link mtu 1460
1494
	set link keep-alive 10 60
1495
	set ipcp yes vjcomp
1496
	set bundle enable compression
1497
	set ccp yes mppc
1498
	set ccp yes mpp-e128
1499
	set ccp yes mpp-stateless
1500

    
1501
EOD;
1502

    
1503
			if (!isset ($pptpdcfg['req128'])) {
1504
				$mpdconf .=<<<EOD
1505
	set ccp yes mpp-e40
1506
	set ccp yes mpp-e56
1507

    
1508
EOD;
1509
			}
1510

    
1511
			if (isset($pptpdcfg["wins"]) && $pptpdcfg['wins'] != "") {
1512
				$mpdconf .= "	set ipcp nbns {$pptpdcfg['wins']}\n";
1513
			}
1514

    
1515
			if (!empty($pptpdcfg['dns1'])) {
1516
				$mpdconf .= "	set ipcp dns " . $pptpdcfg['dns1'];
1517
				if (!empty($pptpdcfg['dns2'])) {
1518
					$mpdconf .= " " . $pptpdcfg['dns2'];
1519
				}
1520
				$mpdconf .= "\n";
1521
			} elseif (isset ($config['dnsmasq']['enable'])) {
1522
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1523
				if ($syscfg['dnsserver'][0]) {
1524
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1525
				}
1526
				$mpdconf .= "\n";
1527
			} elseif (isset($config['unbound']['enable'])) {
1528
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1529
				if ($syscfg['dnsserver'][0]) {
1530
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1531
				}
1532
				$mpdconf .= "\n";
1533
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1534
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1535
			}
1536

    
1537
			if (isset ($pptpdcfg['radius']['server']['enable'])) {
1538
				$authport = (isset($pptpdcfg['radius']['server']['port']) && strlen($pptpdcfg['radius']['server']['port']) > 1) ? $pptpdcfg['radius']['server']['port'] : 1812;
1539
				$acctport = $authport + 1;
1540
				$mpdconf .=<<<EOD
1541
	set radius server {$pptpdcfg['radius']['server']['ip']} "{$pptpdcfg['radius']['server']['secret']}" {$authport} {$acctport}
1542

    
1543
EOD;
1544
				if (isset ($pptpdcfg['radius']['server2']['enable'])) {
1545
					$authport = (isset($pptpdcfg['radius']['server2']['port']) && strlen($pptpdcfg['radius']['server2']['port']) > 1) ? $pptpdcfg['radius']['server2']['port'] : 1812;
1546
					$acctport = $authport + 1;
1547
					$mpdconf .=<<<EOD
1548
	set radius server {$pptpdcfg['radius']['server2']['ip']} "{$pptpdcfg['radius']['server2']['secret2']}" {$authport} {$acctport}
1549

    
1550
EOD;
1551
				}
1552
				$mpdconf .=<<<EOD
1553
	set radius retries 3
1554
	set radius timeout 10
1555
	set auth enable radius-auth
1556

    
1557
EOD;
1558

    
1559
				if (isset ($pptpdcfg['radius']['accounting'])) {
1560
					$mpdconf .=<<<EOD
1561
	set auth enable radius-acct
1562
	set radius acct-update 300
1563

    
1564
EOD;
1565
				}
1566
			}
1567

    
1568
			fwrite($fd, $mpdconf);
1569
			fclose($fd);
1570
			unset($mpdconf);
1571

    
1572
			/* write mpd.links */
1573
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.links", "w");
1574
			if (!$fd) {
1575
				printf(gettext("Error: cannot open mpd.links in vpn_pptpd_configure().") . "\n");
1576
				return 1;
1577
			}
1578

    
1579
			$mpdlinks = "";
1580

    
1581
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1582
				$mpdlinks .=<<<EOD
1583

    
1584
pt{$i}:
1585
	set link type pptp
1586
	set pptp enable incoming
1587
	set pptp disable originate
1588
	set pptp disable windowing
1589

    
1590
EOD;
1591
			}
1592

    
1593
			fwrite($fd, $mpdlinks);
1594
			fclose($fd);
1595
			unset($mpdlinks);
1596

    
1597
			/* write mpd.secret */
1598
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.secret", "w");
1599
			if (!$fd) {
1600
				printf(gettext("Error: cannot open mpd.secret in vpn_pptpd_configure().") . "\n");
1601
				return 1;
1602
			}
1603

    
1604
			$mpdsecret = "";
1605

    
1606
			if (is_array($pptpdcfg['user'])) {
1607
				foreach ($pptpdcfg['user'] as $user) {
1608
					$pass = str_replace('\\', '\\\\', $user['password']);
1609
					$pass = str_replace('"', '\"', $pass);
1610
					$mpdsecret .= "{$user['name']} \"{$pass}\" {$user['ip']}\n";
1611
				}
1612
			}
1613

    
1614
			fwrite($fd, $mpdsecret);
1615
			fclose($fd);
1616
			unset($mpdsecret);
1617
			chmod("{$g['varetc_path']}/pptp-vpn/mpd.secret", 0600);
1618

    
1619
			vpn_netgraph_support();
1620

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

    
1624
			break;
1625

    
1626
		case 'redir':
1627
			break;
1628
	}
1629

    
1630
	if (platform_booting()) {
1631
		echo "done\n";
1632
	}
1633

    
1634
	return 0;
1635
}
1636

    
1637
function vpn_pppoes_configure() {
1638
	global $config;
1639

    
1640
	if (is_array($config['pppoes']['pppoe'])) {
1641
		foreach ($config['pppoes']['pppoe'] as $pppoe) {
1642
			vpn_pppoe_configure($pppoe);
1643
		}
1644
	}
1645
}
1646

    
1647
function vpn_pppoe_configure(&$pppoecfg) {
1648
	global $config, $g;
1649

    
1650
	$syscfg = $config['system'];
1651

    
1652
	/* create directory if it does not exist */
1653
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn")) {
1654
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1655
	}
1656

    
1657
	if (platform_booting()) {
1658
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off")) {
1659
			return 0;
1660
		}
1661

    
1662
		echo gettext("Configuring PPPoE Server service... ");
1663
	} else {
1664
		/* kill mpd */
1665
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1666

    
1667
		/* wait for process to die */
1668
		sleep(2);
1669

    
1670
	}
1671

    
1672
	switch ($pppoecfg['mode']) {
1673

    
1674
		case 'server':
1675

    
1676
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1677

    
1678
			if ($pppoecfg['paporchap'] == "chap") {
1679
				$paporchap = "set link enable chap";
1680
			} else {
1681
				$paporchap = "set link enable pap";
1682
			}
1683

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

    
1693
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1694
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1695
			}
1696

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

    
1699
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1700

    
1701
				if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1702
					$issue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1703
				} else {
1704
					$issue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1705
				}
1706

    
1707
				$mpdconf .=<<<EOD
1708

    
1709
poes{$pppoecfg['pppoeid']}{$i}:
1710
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1711
	{$issue_ip_type}
1712
	load pppoe_standard
1713

    
1714
EOD;
1715
			}
1716

    
1717
			$mpdconf .=<<<EOD
1718

    
1719
pppoe_standard:
1720
	set bundle no multilink
1721
	set bundle enable compression
1722
	set auth max-logins 1
1723
	set iface up-script /usr/local/sbin/vpn-linkup
1724
	set iface down-script /usr/local/sbin/vpn-linkdown
1725
	set iface idle 0
1726
	set iface disable on-demand
1727
	set iface disable proxy-arp
1728
	set iface enable tcpmssfix
1729
	set iface mtu 1500
1730
	set link no pap chap
1731
	{$paporchap}
1732
	set link keep-alive 60 180
1733
	set ipcp yes vjcomp
1734
	set ipcp no vjcomp
1735
	set link max-redial -1
1736
	set link mtu 1492
1737
	set link mru 1492
1738
	set ccp yes mpp-e40
1739
	set ccp yes mpp-e128
1740
	set ccp yes mpp-stateless
1741
	set link latency 1
1742
	#set ipcp dns 10.10.1.3
1743
	#set bundle accept encryption
1744

    
1745
EOD;
1746

    
1747
			if (!empty($pppoecfg['dns1'])) {
1748
				$mpdconf .= "	set ipcp dns " . $pppoecfg['dns1'];
1749
				if (!empty($pppoecfg['dns2'])) {
1750
					$mpdconf .= " " . $pppoecfg['dns2'];
1751
				}
1752
				$mpdconf .= "\n";
1753
			} elseif (isset ($config['dnsmasq']['enable'])) {
1754
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1755
				if ($syscfg['dnsserver'][0]) {
1756
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1757
				}
1758
				$mpdconf .= "\n";
1759
			} elseif (isset ($config['unbound']['enable'])) {
1760
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1761
				if ($syscfg['dnsserver'][0]) {
1762
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1763
				}
1764
				$mpdconf .= "\n";
1765
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1766
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1767
			}
1768

    
1769
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1770
				$radiusport = "";
1771
				$radiusacctport = "";
1772
				if (isset($pppoecfg['radius']['server']['port'])) {
1773
					$radiusport = $pppoecfg['radius']['server']['port'];
1774
				}
1775
				if (isset($pppoecfg['radius']['server']['acctport'])) {
1776
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1777
				}
1778
				$mpdconf .=<<<EOD
1779
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
1780
	set radius retries 3
1781
	set radius timeout 10
1782
	set auth enable radius-auth
1783

    
1784
EOD;
1785

    
1786
				if (isset ($pppoecfg['radius']['accounting'])) {
1787
					$mpdconf .=<<<EOD
1788
	set auth enable radius-acct
1789

    
1790
EOD;
1791
				}
1792
			}
1793

    
1794
			fwrite($fd, $mpdconf);
1795
			fclose($fd);
1796
			unset($mpdconf);
1797

    
1798
			/* write mpd.links */
1799
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.links", "w");
1800
			if (!$fd) {
1801
				printf(gettext("Error: cannot open mpd.links in vpn_pppoe_configure().") . "\n");
1802
				return 1;
1803
			}
1804

    
1805
			$mpdlinks = "";
1806

    
1807
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1808
				$mpdlinks .=<<<EOD
1809

    
1810
poes{$pppoecfg['pppoeid']}{$i}:
1811
	set phys type pppoe
1812
	set pppoe iface {$pppoe_interface}
1813
	set pppoe service "*"
1814
	set pppoe disable originate
1815
	set pppoe enable incoming
1816

    
1817
EOD;
1818
			}
1819

    
1820
			fwrite($fd, $mpdlinks);
1821
			fclose($fd);
1822
			unset($mpdlinks);
1823

    
1824
			if ($pppoecfg['username']) {
1825
				/* write mpd.secret */
1826
				$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
1827
				if (!$fd) {
1828
					printf(gettext("Error: cannot open mpd.secret in vpn_pppoe_configure().") . "\n");
1829
					return 1;
1830
				}
1831

    
1832
				$mpdsecret = "\n\n";
1833

    
1834
				if (!empty($pppoecfg['username'])) {
1835
					$item = explode(" ", $pppoecfg['username']);
1836
					foreach ($item as $userdata) {
1837
						$data = explode(":", $userdata);
1838
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1839
					}
1840
				}
1841

    
1842
				fwrite($fd, $mpdsecret);
1843
				fclose($fd);
1844
				unset($mpdsecret);
1845
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1846
			}
1847

    
1848
			/* Check if previous instance is still up */
1849
			while (file_exists("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid") && isvalidpid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid")) {
1850
				killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1851
			}
1852

    
1853
			/* Get support for netgraph(4) from the nic */
1854
			pfSense_ngctl_attach(".", $pppoe_interface);
1855
			/* fire up mpd */
1856
			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");
1857

    
1858
			break;
1859
	}
1860

    
1861
	if (platform_booting()) {
1862
		echo gettext("done") . "\n";
1863
	}
1864

    
1865
	return 0;
1866
}
1867

    
1868
function vpn_l2tp_configure() {
1869
	global $config, $g;
1870

    
1871
	$syscfg = $config['system'];
1872
	$l2tpcfg = $config['l2tp'];
1873

    
1874
	/* create directory if it does not exist */
1875
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn")) {
1876
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1877
	}
1878

    
1879
	if (platform_booting()) {
1880
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off")) {
1881
			return 0;
1882
		}
1883

    
1884
		echo gettext("Configuring l2tp VPN service... ");
1885
	} else {
1886
		/* kill mpd */
1887
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1888

    
1889
		/* wait for process to die */
1890
		sleep(8);
1891

    
1892
	}
1893

    
1894
	/* make sure l2tp-vpn directory exists */
1895
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn")) {
1896
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1897
	}
1898

    
1899
	switch ($l2tpcfg['mode']) {
1900

    
1901
		case 'server':
1902
			$l2tp_listen="";
1903
			$ipaddr = get_interface_ip(get_failover_interface($l2tpcfg['interface']));
1904
			if (is_ipaddrv4($ipaddr)) {
1905
				$l2tp_listen="set l2tp self $ipaddr";
1906
			}
1907

    
1908
			if ($l2tpcfg['paporchap'] == "chap") {
1909
				$paporchap = "set link enable chap";
1910
			} else {
1911
				$paporchap = "set link enable pap";
1912
			}
1913

    
1914
			/* write mpd.conf */
1915
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1916
			if (!$fd) {
1917
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
1918
				return 1;
1919
			}
1920
			$mpdconf = "\n\n";
1921
			$mpdconf .=<<<EOD
1922
l2tps:
1923

    
1924
EOD;
1925

    
1926
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1927
				$mpdconf .= "	load l2tp{$i}\n";
1928
			}
1929

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

    
1932
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1933

    
1934
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1935
					$issue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1936
				} else {
1937
					$issue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1938
				}
1939

    
1940
				$mpdconf .=<<<EOD
1941

    
1942
l2tp{$i}:
1943
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1944
	{$issue_ip_type}
1945
	load l2tp_standard
1946

    
1947
EOD;
1948
			}
1949

    
1950
			$mpdconf .=<<<EOD
1951

    
1952
l2tp_standard:
1953
	set bundle disable multilink
1954
	set bundle enable compression
1955
	set bundle yes crypt-reqd
1956
	set ipcp yes vjcomp
1957
	# set ipcp ranges 131.188.69.161/32 131.188.69.170/28
1958
	set ccp yes mppc
1959
	set iface disable on-demand
1960
	set iface enable proxy-arp
1961
	set iface up-script /usr/local/sbin/vpn-linkup
1962
	set iface down-script /usr/local/sbin/vpn-linkdown
1963
	set link yes acfcomp protocomp
1964
	set link no pap chap
1965
	{$paporchap}
1966
	{$l2tp_listen}
1967
	set link keep-alive 10 180
1968

    
1969
EOD;
1970

    
1971
			if (is_ipaddr($l2tpcfg['wins'])) {
1972
				$mpdconf .= "	set ipcp nbns {$l2tpcfg['wins']}\n";
1973
			}
1974
			if (is_ipaddr($l2tpcfg['dns1'])) {
1975
				$mpdconf .= "	set ipcp dns " . $l2tpcfg['dns1'];
1976
				if (is_ipaddr($l2tpcfg['dns2'])) {
1977
					$mpdconf .= " " . $l2tpcfg['dns2'];
1978
				}
1979
				$mpdconf .= "\n";
1980
			} elseif (isset ($config['dnsmasq']['enable'])) {
1981
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1982
				if ($syscfg['dnsserver'][0]) {
1983
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1984
				}
1985
				$mpdconf .= "\n";
1986
			} elseif (isset ($config['unbound']['enable'])) {
1987
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1988
				if ($syscfg['dnsserver'][0]) {
1989
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1990
				}
1991
				$mpdconf .= "\n";
1992
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1993
				$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1994
			}
1995

    
1996
			if (isset ($l2tpcfg['radius']['enable'])) {
1997
				$mpdconf .=<<<EOD
1998
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1999
	set radius retries 3
2000
	set radius timeout 10
2001
	set auth enable radius-auth
2002

    
2003
EOD;
2004

    
2005
				if (isset ($l2tpcfg['radius']['accounting'])) {
2006
					$mpdconf .=<<<EOD
2007
	set auth enable radius-acct
2008

    
2009
EOD;
2010
				}
2011
			}
2012

    
2013
			fwrite($fd, $mpdconf);
2014
			fclose($fd);
2015
			unset($mpdconf);
2016

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

    
2024
			$mpdlinks = "";
2025

    
2026
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
2027
				$mpdlinks .=<<<EOD
2028

    
2029
l2tp{$i}:
2030
	set link type l2tp
2031
	set l2tp enable incoming
2032
	set l2tp disable originate
2033

    
2034
EOD;
2035
				if (!empty($l2tpcfg['secret'])) {
2036
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
2037
				}
2038
			}
2039

    
2040
			fwrite($fd, $mpdlinks);
2041
			fclose($fd);
2042
			unset($mpdlinks);
2043

    
2044
			/* write mpd.secret */
2045
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.secret", "w");
2046
			if (!$fd) {
2047
				printf(gettext("Error: cannot open mpd.secret in vpn_l2tp_configure().") . "\n");
2048
				return 1;
2049
			}
2050

    
2051
			$mpdsecret = "\n\n";
2052

    
2053
			if (is_array($l2tpcfg['user'])) {
2054
				foreach ($l2tpcfg['user'] as $user) {
2055
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
2056
				}
2057
			}
2058

    
2059
			fwrite($fd, $mpdsecret);
2060
			fclose($fd);
2061
			unset($mpdsecret);
2062
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
2063

    
2064
			vpn_netgraph_support();
2065

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

    
2069
			break;
2070

    
2071
		case 'redir':
2072
			break;
2073
	}
2074

    
2075
	if (platform_booting()) {
2076
		echo "done\n";
2077
	}
2078

    
2079
	return 0;
2080
}
2081

    
2082
?>
(59-59/68)