Project

General

Profile

Download (46.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

    
45
function vpn_ipsec_configure_loglevels($forconfig = false)
46
{
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
	if ($forconfig)
59
		return implode(',', $cfgtext);
60
}
61

    
62
/* include all configuration functions */
63
function vpn_ipsec_convert_to_modp($index)
64
{
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
	}
93

    
94
	return $convertion;
95
}
96

    
97
function vpn_ipsec_configure($ipchg = false)
98
{
99
	global $config, $g, $sa, $sn, $p1_ealgos, $p2_ealgos;
100

    
101
	if ($g['platform'] == 'jail')
102
		return;
103

    
104
	/* get the automatic ping_hosts.sh ready */
105
	unlink_if_exists("{$g['vardb_path']}/ipsecpinghosts");
106
	touch("{$g['vardb_path']}/ipsecpinghosts");
107

    
108
	vpn_ipsec_configure_preferoldsa();
109

    
110
	$syscfg = $config['system'];
111
	$ipseccfg = $config['ipsec'];
112
	$a_phase1 = $config['ipsec']['phase1'];
113
	$a_phase2 = $config['ipsec']['phase2'];
114
	$a_client = $config['ipsec']['client'];
115

    
116
	if (!isset($ipseccfg['enable'])) {
117
		/* try to stop charon */
118
		mwexec("/usr/local/sbin/ipsec stop");
119
		/* Stop dynamic monitoring */
120
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
121

    
122
		/* wait for process to die */
123
		sleep(2);
124

    
125
		/* disallow IPSEC, it is off */
126
		mwexec("/sbin/ifconfig enc0 down");
127
		set_single_sysctl("net.inet.ip.ipsec_in_use", "0");
128

    
129
		return 0;
130
	}
131

    
132
	$certpath = "{$g['varetc_path']}/ipsec/ipsec.d/certs";
133
	$capath = "{$g['varetc_path']}/ipsec/ipsec.d/cacerts";
134
	$keypath = "{$g['varetc_path']}/ipsec/ipsec.d/private";
135

    
136
	mwexec("/sbin/ifconfig enc0 up");
137
	set_single_sysctl("net.inet.ip.ipsec_in_use", "1");
138
	/* needed for config files */
139
	if (!is_dir("{$g['varetc_path']}/ipsec"))
140
		mkdir("{$g['varetc_path']}/ipsec");
141
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d"))
142
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d");
143
	if (!is_dir($capath))
144
		mkdir($capath);
145
	if (!is_dir($keypath))
146
		mkdir($keypath);
147
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/crls"))
148
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/crls");
149
	if (!is_dir($certpath))
150
		mkdir($certpath);
151
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/aacerts"))
152
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/aacerts");
153
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/acerts"))
154
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/acerts");
155
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/ocspcerts"))
156
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/ocspcerts");
157
	if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/reqs"))
158
		mkdir("{$g['varetc_path']}/ipsec/ipsec.d/reqs");
159
	
160

    
161
	if (platform_booting())
162
		echo gettext("Configuring IPsec VPN... ");
163

    
164
	/* fastforwarding is not compatible with ipsec tunnels */
165
	set_single_sysctl("net.inet.ip.fastforwarding", "0");
166

    
167
	/* resolve all local, peer addresses and setup pings */
168
	$ipmap = array();
169
	$rgmap = array();
170
	$filterdns_list = array();
171
	$listeniflist = array();
172
	$aggressive_mode_psk = false;
173
	unset($iflist);
174
	if (is_array($a_phase1) && count($a_phase1)) {
175

    
176
		$ipsecpinghosts = "";
177
		/* step through each phase1 entry */
178
		foreach ($a_phase1 as $ph1ent) {
179
			if (isset($ph1ent['disabled']))
180
				continue;
181

    
182
			if ($ph1ent['mode'] == "aggressive" && ($ph1ent['authentication_method'] == "pre_shared_key" || $ph1ent['authentication_method'] == "xauth_psk_server")) 
183
				$aggressive_mode_psk = true;
184

    
185
			$ikeid = $ph1ent['ikeid'];
186
			$listeniflist = get_real_interface($a_phase1['interface']);
187

    
188
			$ep = ipsec_get_phase1_src($ph1ent);
189
			if (!is_ipaddr($ep))
190
				continue;
191

    
192
			if(!in_array($ep,$ipmap))
193
				$ipmap[] = $ep;
194

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

    
198
			if (isset ($ph1ent['mobile']))
199
				continue;
200

    
201
			$rg = $ph1ent['remote-gateway'];
202

    
203
			if (!is_ipaddr($rg)) {
204
				$filterdns_list[] = "{$rg}";
205
				add_hostname_to_watch($rg);
206
				if (!platform_booting())
207
					$rg = resolve_retry($rg);
208
				if (!is_ipaddr($rg))
209
					continue;
210
			}
211
			if(array_search($rg, $rgmap)) {
212
				log_error("The remote gateway {$rg} already exists on another phase 1 entry");
213
				continue;
214
			}
215
			$rgmap[$ph1ent['remote-gateway']] = $rg;
216

    
217
			if (is_array($a_phase2)) {
218
				/* step through each phase2 entry */
219
				foreach ($a_phase2 as $ph2ent) {
220
					if (isset($ph2ent['disabled']))
221
						continue;
222

    
223
					if ($ikeid != $ph2ent['ikeid'])
224
						continue;
225

    
226
					/* add an ipsec pinghosts entry */
227
					if ($ph2ent['pinghost']) {
228
						if (!is_array($iflist))
229
							$iflist = get_configured_interface_list();
230
						$viplist = get_configured_vips_list();
231
						$srcip = null;
232
						$local_subnet = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
233
						if(is_ipaddrv6($ph2ent['pinghost'])) {
234
							foreach ($iflist as $ifent => $ifname) {
235
								$interface_ip = get_interface_ipv6($ifent);
236
								if(!is_ipaddrv6($interface_ip))
237
									continue;
238
								if (ip_in_subnet($interface_ip, $local_subnet)) {
239
									$srcip = $interface_ip;
240
									break;
241
								}
242
							}
243
						} else {
244
							foreach ($iflist as $ifent => $ifname) {
245
								$interface_ip = get_interface_ip($ifent);
246
								if(!is_ipaddrv4($interface_ip))
247
									continue;
248
								if ($local_subnet == "0.0.0.0/0" || ip_in_subnet($interface_ip, $local_subnet)) {
249
									$srcip = $interface_ip;
250
									break;
251
								}
252
							}
253
						}
254
						/* if no valid src IP was found in configured interfaces, try the vips */
255
						if (is_null($srcip)) {
256
							foreach ($viplist as $vip) {
257
								if (ip_in_subnet($vip['ipaddr'], $local_subnet)) {
258
									$srcip = $vip['ipaddr'];
259
									break;
260
								}
261
							}
262
						}
263
						$dstip = $ph2ent['pinghost'];
264
						if(is_ipaddrv6($dstip)) {
265
							$family = "inet6";
266
						} else {
267
							$family = "inet";
268
						}
269
						if (is_ipaddr($srcip))
270
							$ipsecpinghosts[] = "{$srcip}|{$dstip}|3|||||{$family}|\n";
271
					}
272
				}
273
			}
274
		}
275
		@file_put_contents("{$g['vardb_path']}/ipsecpinghosts", $ipsecpinghosts);
276
		unset($ipsecpinghosts);
277
	}
278
	unset($iflist);
279

    
280
	$accept_unencrypted = "";
281
	if (isset($config['ipsec']['acceptunencryptedmainmode']))
282
		$accept_unencrypted = "accept_unencrypted_mainmode_messages = yes";
283

    
284
	$i_dont_care_about_security_and_use_aggressive_mode_psk = "";
285
	if ($aggressive_mode_psk) {
286
		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.");
287
		$i_dont_care_about_security_and_use_aggressive_mode_psk = "i_dont_care_about_security_and_use_aggressive_mode_psk=yes";
288
	} 
289
	$strongswan = <<<EOD
290

    
291
# Automatically generated config file - DO NOT MODIFY. Changes will be overwritten. 
292
starter {
293
load_warning = no
294
}
295

    
296
charon {
297
# number of worker threads in charon
298
threads = 16
299
ikesa_table_size = 32
300
ikesa_table_segments = 4
301
init_limit_half_open = 1000
302
install_routes = no
303
{$i_dont_care_about_security_and_use_aggressive_mode_psk}
304
{$accept_unencrypted}
305
cisco_unity = yes
306

    
307
# And two loggers using syslog. The subsections define the facility to log
308
# to, currently one of: daemon, auth.
309
syslog {
310
	identifier = charon
311
	# default level to the LOG_DAEMON facility
312
	daemon {
313
	}
314
	# very minimalistic IKE auditing logs to LOG_AUTHPRIV
315
	auth {
316
		default = -1
317
		ike = 1
318
		ike_name = yes
319
	}
320
}
321

    
322
EOD;
323

    
324
	$strongswan .= "\tplugins {\n";
325

    
326
	if (is_array($a_client) && isset($a_client['enable'])) {
327
		$strongswan .= "\t\tattr {\n";
328
		if ($a_client['pool_address'] && $a_client['pool_netbits'])
329
			$strongswan .= "\t\t\tsubnet = {$a_client['pool_address']}/{$a_client['pool_netbits']}\n";
330

    
331
		$cfgservers = array();
332
		if (!empty($a_client['dns_server1']))
333
			$cfgservers[] = $a_client['dns_server1'];
334
		if (!empty($a_client['dns_server2']))
335
			$cfgservers[] = $a_client['dns_server2'];
336
		if (!empty($a_client['dns_server3']))
337
			$cfgservers[] = $a_client['dns_server3'];
338
		if (!empty($a_client['dns_server4']))
339
			$cfgservers[] = $a_client['dns_server4'];
340

    
341
		if (!empty($cfgservers))
342
			$strongswan .= "\t\t\tdns = " . implode(",", $cfgservers) . "\n";
343
		unset($cfgservers);
344
		$cfgservers = array();
345
		if (!empty($a_client['wins_server1']))
346
			$cfgservers[] = $a_client['wins_server1'];
347
		if (!empty($a_client['wins_server2']))
348
			$cfgservers[] = $a_client['wins_server2'];
349
		if (!empty($cfgservers))
350
			$strongswan .= "\t\t\tnbns = " . implode(",", $cfgservers) . "\n";
351
		unset($cfgservers);
352

    
353
		if (isset($a_client['net_list'])) {
354
			$net_list = '';
355
			foreach ($a_phase2 as $ph2ent) {
356
				if (isset($ph2ent['disabled']))
357
					continue;
358

    
359
				if (!isset($ph2ent['mobile']))
360
					continue;
361

    
362
				$localid = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
363

    
364
				if (!empty($net_list))
365
					$net_list .= ",";
366
				$net_list .= $localid;
367
			}
368

    
369
			if (!empty($net_list)) {
370
				$strongswan .= "\t\t\tsplit-include = {$net_list}\n";
371
				unset($net_list);
372
			}
373
		}
374

    
375
		if (!empty($a_client['dns_domain'])) {
376
			$strongswan .= "\t\t\t# Search domain and default domain\n";
377
			$strongswan .= "\t\t\t28674 = {$a_client['dns_domain']}\n";
378
			if (empty($a_client['dns_split']))
379
				$strongswan .= "\t\t\t28675 = {$a_client['dns_domain']}";
380
			$strongswan .= "\n";
381
		}
382

    
383
		if (!empty($a_client['dns_split'])) {
384
			$strongswan .= "\t\t\t28675 = {$a_client['dns_split']}\n";
385
		}
386

    
387
		if (!empty($a_client['login_banner']))
388
			$strongswan .= "\t\t\t28672 = {$a_client['login_banner']}\n";
389

    
390
		if (isset($a_client['save_passwd']))
391
			$strongswan .= "\t\t\t28673 = 1\n";
392

    
393
		if ($a_client['pfs_group'])
394
			$strongswan .= "\t\t\t28679 = {$a_client['pfs_group']}\n";
395
		$strongswan .= "\t\t}\n";
396

    
397
		if ($a_client['user_source'] != "none") {
398
			$strongswan .= "\t\txauth-generic {\n";
399
			$strongswan .= "\t\t\tscript = /etc/inc/ipsec.auth-user.php\n";
400
			$strongswan .= "\t\t\tauthcfg = ";
401
			$firstsed = 0;
402
			$authcfgs = explode(",", $a_client['user_source']);
403
			foreach ($authcfgs as $authcfg) {
404
				if ($firstsed > 0)
405
					$strongswan .= ",";
406
				if ($authcfg == "system")
407
					$authcfg = "Local Database";
408
				$strongswan .= $authcfg;
409
				$firstsed = 1;
410
			}
411
			$strongswan .= "\n";
412
			$strongswan .= "\t\t}\n";
413
		}
414
	}
415

    
416
	$strongswan .= "\t}\n}\n";
417
	@file_put_contents("{$g['varetc_path']}/ipsec/strongswan.conf", $strongswan);
418
	unset($strongswan);
419

    
420
	/* generate CA certificates files */
421
	if (is_array($config['ca']) && count($config['ca'])) {
422
		foreach ($config['ca'] as $ca) {
423
			if (!isset($ca['crt'])) {
424
				log_error(sprintf(gettext("Error: Invalid certificate info for %s"), $ca['descr']));
425
				continue;
426
			}
427
			$cert = base64_decode($ca['crt']);
428
			$x509cert = openssl_x509_parse(openssl_x509_read($cert));
429
			if (!is_array($x509cert) || !isset($x509cert['hash'])) {
430
				log_error(sprintf(gettext("Error: Invalid certificate hash info for %s"), $ca['descr']));
431
				continue;
432
			}
433
			$fname = "{$capath}/{$x509cert['hash']}.0.crt";
434
			if (!@file_put_contents($fname, $cert)) {
435
				log_error(sprintf(gettext("Error: Cannot write IPsec CA file for %s"), $ca['descr']));
436
				continue;
437
			}
438
			unset($cert);
439
		}
440
	}
441

    
442
	$pskconf = "";
443

    
444
	if (is_array($a_phase1) && count($a_phase1)) {
445
		foreach ($a_phase1 as $ph1ent) {
446

    
447
			if (isset($ph1ent['disabled']))
448
				continue;
449

    
450
			if (strstr($ph1ent['authentication_method'], 'rsa') || $ph1ent['authentication_method'] == 'eap-tls') {
451
				$certline = '';
452

    
453
				$ikeid = $ph1ent['ikeid'];
454
				$cert = lookup_cert($ph1ent['certref']);
455

    
456
				if (!$cert) {
457
					log_error(sprintf(gettext("Error: Invalid phase1 certificate reference for %s"), $ph1ent['name']));
458
					continue;
459
				}
460

    
461
				@chmod($certpath, 0600);
462

    
463
				$ph1keyfile = "{$keypath}/cert-{$ikeid}.key";
464
				if (!file_put_contents($ph1keyfile, base64_decode($cert['prv']))) {
465
					log_error(sprintf(gettext("Error: Cannot write phase1 key file for %s"), $ph1ent['name']));
466
					continue;
467
				}
468
				@chmod($ph1keyfile, 0600);
469

    
470
				$ph1certfile = "{$certpath}/cert-{$ikeid}.crt";
471
				if (!file_put_contents($ph1certfile, base64_decode($cert['crt']))) {
472
					log_error(sprintf(gettext("Error: Cannot write phase1 certificate file for %s"), $ph1ent['name']));
473
					@unlink($ph1keyfile);
474
					continue;
475
				}
476
				@chmod($ph1certfile, 0600);
477

    
478
				/* XXX" Traffic selectors? */
479
				$pskconf .= " : RSA {$ph1keyfile}\n";
480
			} else {
481
				list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, "local");
482
				list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, "peer", $rgmap);
483

    
484
				if (empty($peerid_data))
485
					continue;
486

    
487
				$myid = isset($ph1ent['mobile']) ? trim($myid_data) . " " : "";
488
				$peerid = ($peerid_data != "allusers") ? trim($peerid_data) : "";
489
				if (!empty($ph1ent['pre-shared-key']))
490
					$pskconf .= $myid . $peerid . " : PSK \"" . trim($ph1ent['pre-shared-key']) . "\"\n";
491
			}
492
		}
493
	}
494

    
495
	/* Add user PSKs */
496
	if (is_array($config['system']) && is_array($config['system']['user'])) {
497
		foreach ($config['system']['user'] as $user) {
498
			if (!empty($user['ipsecpsk'])) {
499
				$pskconf .= "{$myid} {$user['name']} : PSK \"{$user['ipsecpsk']}\"\n";
500
			}
501
		}
502
		unset($user);
503
	}
504

    
505
	/* add PSKs for mobile clients */
506
	if (is_array($ipseccfg['mobilekey'])) {
507
		foreach ($ipseccfg['mobilekey'] as $key) {
508
			if ($key['ident'] == "allusers")
509
				$key['ident'] = '';
510
			$pskconf .= "{$myid} {$key['ident']} : PSK \"{$key['pre-shared-key']}\"\n";
511
		}
512
		unset($key);
513
	}
514

    
515
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.secrets", $pskconf);
516
	chmod("{$g['varetc_path']}/ipsec/ipsec.secrets", 0600);
517
	unset($pskconf);
518

    
519
	$natfilterrules = false;
520
	/* begin ipsec.conf */
521
	$ipsecconf = "";
522
	if (is_array($a_phase1) && count($a_phase1))  {
523

    
524
		$ipsecconf .= "# This file is automatically generated. Do not edit\n";
525
		$ipsecconf .= "config setup\n\tuniqueids = yes\n";
526
		$ipsecconf .= "\tcharondebug=\"" . vpn_ipsec_configure_loglevels(true) . "\"\n";
527

    
528
		foreach ($a_phase1 as $ph1ent) {
529
			if (isset($ph1ent['disabled']))
530
				continue;
531

    
532
			if ($ph1ent['mode'] == "aggressive")
533
				$aggressive = "yes";
534
			else
535
				$aggressive = "no";
536

    
537
			$ep = ipsec_get_phase1_src($ph1ent);
538
			if (!$ep)
539
				continue;
540

    
541
			$ikeid = $ph1ent['ikeid'];
542
			$keyexchange = "ikev1";
543
			$passive = "route";
544
			if (!empty($ph1ent['iketype'])) {
545
				if ($ph1ent['iketype'] == "ikev2") {
546
					$keyexchange = "ikev2";
547
					//$passive = "start";
548
				} else if ($ph1ent['iketype'] == "auto")
549
					$keyexchange = "ike";
550
			}
551

    
552
			if (isset($ph1ent['mobile'])) {
553
				$right_spec = "%any";
554
				$passive = 'add';
555
			} else
556
				$right_spec = $ph1ent['remote-gateway'];
557

    
558
			list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, "local");
559
			list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, "peer", $rgmap);
560

    
561
			/* Only specify peer ID if we are not dealing with a mobile PSK-only tunnel */
562
			$peerid_spec = '';
563
			if (!isset($ph1ent['mobile']))
564
				$peerid_spec = $peerid_data;
565

    
566
			if (is_array($ph1ent['encryption-algorithm']) && !empty($ph1ent['encryption-algorithm']['name']) && !empty($ph1ent['hash-algorithm'])) {
567
				$ealgosp1 = '';
568
				$ealg_id = $ph1ent['encryption-algorithm']['name'];
569
				$ealg_kl = $ph1ent['encryption-algorithm']['keylen'];
570
				if ($ealg_kl)
571
					$ealgosp1 = "ike = {$ealg_id}{$ealg_kl}-{$ph1ent['hash-algorithm']}";
572
				else
573
					$ealgosp1 = "ike = {$ealg_id}-{$ph1ent['hash-algorithm']}";
574

    
575
				$modp = vpn_ipsec_convert_to_modp($ph1ent['dhgroup']);
576
				if (!empty($modp))
577
					$ealgosp1 .= "-{$modp}";
578

    
579
				$ealgosp1 .= "!";
580
			}
581

    
582
			if ($ph1ent['dpd_delay'] && $ph1ent['dpd_maxfail']) {
583
				if ($passive == "route")
584
					$dpdline = "dpdaction = restart";
585
				else
586
					$dpdline = "dpdaction = clear";
587
				$dpdline .= "\n\tdpddelay = {$ph1ent['dpd_delay']}s";
588
				$dpdtimeout = $ph1ent['dpd_delay'] * ($ph1ent['dpd_maxfail'] + 1);
589
				$dpdline .= "\n\tdpdtimeout = {$dpdtimeout}s";
590
			} else
591
				$dpdline = "dpdaction = none";
592

    
593
			$ikelifeline = '';
594
			if ($ph1ent['lifetime'])
595
				$ikelifeline = "ikelifetime = {$ph1ent['lifetime']}s";
596

    
597
			$rightsourceip = NULL;
598
			if (isset($ph1ent['mobile']) && !empty($a_client['pool_address'])) 
599
				$rightsourceip = "\trightsourceip = {$a_client['pool_address']}/{$a_client['pool_netbits']}\n";
600

    
601
			$authentication = "";
602
			switch ($ph1ent['authentication_method']) {
603
			case 'eap-tls':
604
				$authentication = "leftauth=eap-tls\n\trightauth=eap-tls";
605
				if (!empty($ph1ent['certref']))
606
					$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
607
				break;
608
			case 'xauth_rsa_server':
609
				$authentication = "leftauth = pubkey\n\trightauth = pubkey";
610
				$authentication .= "\n\trightauth2 = xauth-generic";
611
				if (!empty($ph1ent['certref']))
612
					$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
613
				break;
614
			case 'xauth_psk_server':
615
				$authentication = "leftauth = psk\n\trightauth = psk";
616
				$authentication .= "\n\trightauth2 = xauth-generic";
617
				break;
618
			case 'pre_shared_key':
619
				$authentication = "leftauth = psk\n\trightauth = psk";
620
				break;
621
			case 'rsasig':
622
				$authentication = "leftauth = pubkey\n\trightauth = pubkey";
623
				if (!empty($ph1ent['certref']))
624
					$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
625
				break;
626
			case 'hybrid_rsa_server':
627
				$authentication = "leftauth = xauth-generic\n\trightauth = pubkey";
628
				$authentication .= "\n\trightauth2 = xauth";
629
				if (!empty($ph1ent['certref']))
630
					$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
631
				break;
632
			}
633

    
634
			$left_spec = $ep;
635

    
636
			if (isset($ph1ent['reauth_enable']))
637
				$reauth = "reauth = no";
638
			else
639
				$reauth = "reauth = yes";
640
			if (isset($ph1ent['rekey_enable']))
641
				$rekey = "rekey = no";
642
			else
643
				$rekey = "rekey = yes";
644

    
645
			if ($ph1ent['nat_traversal'] == 'off')
646
				$forceencaps = 'forceencaps = no';
647
			else if ($ph1ent['nat_traversal'] == 'force')
648
				$forceencaps = 'forceencaps = yes';
649
			else
650
				$forceencaps = 'forceencaps = no';
651

    
652
			$ipseclifetime = 0;
653
			$rightsubnet_spec = array();
654
			$leftsubnet_spec = array();
655
			$ealgoAHsp2arr = array();
656
			$ealgoESPsp2arr = array();
657
		if (is_array($a_phase2) && count($a_phase2)) {
658
			foreach ($a_phase2 as $ph2ent) {
659
				if ($ikeid != $ph2ent['ikeid'])
660
					continue;
661

    
662
				if (isset($ph2ent['disabled']))
663
					continue;
664

    
665
				if (isset($ph2ent['mobile']) && !isset($a_client['enable']))
666
					continue;
667

    
668
				if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
669
					$tunneltype = "type = tunnel";
670

    
671
					$localid_type = $ph2ent['localid']['type'];
672
					$leftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['localid'], false, $ph2ent['mode']);
673
					/* Do not print localid in some cases, such as a pure-psk or psk/xauth single phase2 mobile tunnel */
674
					if (($localid_type == "none" || $localid_type == "mobile")
675
					    && isset($ph1ent['mobile']) && (ipsec_get_number_of_phase2($ikeid)==1)) {
676
						$left_spec = '%any';
677
					} else {
678
						if ($localid_type != "address") {
679
							$localid_type = "subnet";
680
						}
681
						// Don't let an empty subnet into config, it can cause parse errors. Ticket #2201.
682
						if (!is_ipaddr($leftsubnet_data) && !is_subnet($leftsubnet_data) && ($leftsubnet_data != "0.0.0.0/0")) {
683
							log_error("Invalid IPsec Phase 2 \"{$ph2ent['descr']}\" - {$ph2ent['localid']['type']} has no subnet.");
684
							continue;
685
						}
686
						if (!empty($ph2ent['natlocalid'])) {
687
							$natleftsubnet_data =  ipsec_idinfo_to_cidr($ph2ent['natlocalid'], false, $ph2ent['mode']);
688
							if ($ph2ent['natlocalid']['type'] != "address") {
689
								if (is_subnet($natleftsubnet_data))
690
									$leftsubnet_data = "{$natleftsubnet_data}|{$leftsubnet_data}";
691
							} else {
692
								if (is_ipaddr($natleftsubnet_data))
693
									$leftsubnet_data = "{$natleftsubnet_data}|{$leftsubnet_data}";
694
							}
695
							$natfilterrules = true;
696
						}
697
					}
698

    
699
					if (empty($leftsubnet_spec[$leftsubnet_data]))
700
						$leftsubnet_spec[$leftsubnet_data] = $leftsubnet_data;
701

    
702
					if (!isset($ph2ent['mobile'])) {
703
						$tmpsubnet = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']);
704
						if (empty($rightsubnet_spec[$tmpsubnet]))
705
							$rightsubnet_spec[$tmpsubnet] = $tmpsubnet;
706
					} else if (!empty($a_client['pool_address'])) {
707
						if (empty($rightsubnet_spec["{$a_client['pool_address']}/{$a_client['pool_netbits']}"]))
708
							$rightsubnet_spec["{$a_client['pool_address']}/{$a_client['pool_netbits']}"] = "{$a_client['pool_address']}/{$a_client['pool_netbits']}";
709
					}
710
				} else {
711
					$tunneltype = "type = transport";
712

    
713
					if ((($ph1ent['authentication_method'] == "xauth_psk_server") ||
714
					    ($ph1ent['authentication_method'] == "pre_shared_key")) && isset($ph1ent['mobile'])) {
715
						$left_spec = "%any";
716
					} else {
717
						$tmpsubnet = ipsec_get_phase1_src($ph1ent);
718
						if ($leftsubnet_spec[$tmpsubnet])
719
							$leftsubnet_spec[$tmpsubnet] = $tmpsubnet;
720
					}
721

    
722
					if (!isset($ph2ent['mobile'])) {
723
						if (empty($rightsubnet_spec[$right_spec]))
724
							$rightsubnet_spec[$right_spec] = $right_spec;
725
					}
726
				}
727

    
728
				if (isset($a_client['pfs_group']))
729
					$ph2ent['pfsgroup'] = $a_client['pfs_group'];
730

    
731
				if ($ph2ent['protocol'] == 'esp') {
732
					if (is_array($ph2ent['encryption-algorithm-option'])) {
733
						foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
734
							$ealg_id = $ealg['name'];
735
							$ealg_kl = $ealg['keylen'];
736

    
737
							if (!empty($ealg_kl) && $ealg_kl == "auto") {
738
								if (empty($p2_ealgos) || !is_array($p2_ealgos))
739
									require("ipsec.inc");
740
								$key_hi = $p2_ealgos[$ealg_id]['keysel']['hi'];
741
								$key_lo = $p2_ealgos[$ealg_id]['keysel']['lo'];
742
								$key_step = $p2_ealgos[$ealg_id]['keysel']['step'];
743
								/* XXX: in some cases where include ordering is suspect these variables
744
								 * are somehow 0 and we enter this loop forever and timeout after 900
745
								 * seconds wrecking bootup */
746
								if ($key_hi != 0 and $key_lo !=0 and $key_step !=0) {
747
									for ($keylen = $key_hi; $keylen >= $key_lo; $keylen -= $key_step) {
748
										if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
749
											foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
750
												$halgo = str_replace('hmac_', '', $halgo);
751
												$tmpealgo = "{$ealg_id}{$keylen}-{$halgo}";
752
												$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
753
												if (!empty($modp))
754
													$tmpealgo .= "-{$modp}";
755
												$ealgoESPsp2arr[] = $tmpealgo;
756
											}
757
										} else {
758
											$tmpealgo = "{$ealg_id}{$keylen}";
759
											$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
760
											if (!empty($modp))
761
												$tmpealgo .= "-{$modp}";
762
											$ealgoESPsp2arr[] = $tmpealgo;
763
										}
764
									}
765
								}
766
							} else {
767
								if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
768
									foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
769
										$halgo = str_replace('hmac_', '', $halgo);
770
										$tmpealgo = "{$ealg_id}{$ealg_kl}-{$halgo}";
771
										$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
772
										if (!empty($modp))
773
											$tmpealgo .= "-{$modp}";
774
										$ealgoESPsp2arr[] = $tmpealgo;
775
									}
776
								} else {
777
									$tmpealgo = "{$ealg_id}{$ealg_kl}";
778
									$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
779
									if (!empty($modp))
780
										$tmpealgo .= "-{$modp}";
781
									$ealgoESPsp2arr[] = $tmpealgo;
782
								}
783
							}
784
						}
785
					}
786
				} else if ($ph2ent['protocol'] == 'ah') {
787
					if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
788
						$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
789
						foreach ($ph2ent['hash-algorithm-option'] as $tmpAHalgo) {
790
							$tmpAHalgo = str_replace('hmac_', '', $tmpAHalgo);
791
							if (!empty($modp))
792
								$tmpAHalgo = "-{$modp}";
793
							$ealgoAHsp2arr[] = $tmpAHalgo;
794
						}
795
					}
796
				}
797

    
798

    
799
				if (!empty($ph2ent['lifetime'])) {
800
					if ($ipseclifetime == 0 || intval($ipseclifetime) > intval($ph2ent['lifetime']))
801
						$ipseclifetime = intval($ph2ent['lifetime']);
802
				}
803

    
804
			}
805
		}
806

    
807
				$ipsecconf .=<<<EOD
808

    
809
conn con{$ph1ent['ikeid']}
810
	fragmentation = yes
811
	keyexchange = {$keyexchange}
812
	{$reauth}
813
	{$forceencaps}
814
	{$rekey}
815
	reqid = {$ikeid}
816
	installpolicy = yes
817
	{$tunneltype}
818
	{$dpdline}
819
	auto = {$passive}
820
	left = {$left_spec}
821
	right = {$right_spec}
822
	leftid = {$myid_data}
823

    
824
EOD;
825

    
826
				if (!empty($ikelifeline))
827
					$ipsecconf .= "\t{$ikelifeline}\n";
828
				if ($ipseclifetime > 0)
829
					$ipsecconf .= "\tlifetime = {$ipseclifetime}s\n";
830
				if (!empty($rightsourceip))
831
					$ipsecconf .= "{$rightsourceip}";
832
				if (!empty($ealgosp1))
833
					$ipsecconf .= "\t{$ealgosp1}\n";
834
				if (!empty($ealgoAHsp2arr))
835
					$ipsecconf .= "\tah = " . join(',', $ealgoAHsp2arr) . "!\n";
836
				if (!empty($ealgoESPsp2arr))
837
					$ipsecconf .= "\tesp = " . join(',', $ealgoESPsp2arr) . "!\n";
838
				if (!empty($authentication))
839
					$ipsecconf .= "\t{$authentication}\n";
840
				if (!empty($peerid_spec))
841
					$ipsecconf .= "\trightid = {$peerid_spec}\n";
842
				if ($keyexchange == 'ikev1')
843
					$ipsecconf .= "\taggressive = {$aggressive}\n";
844
				if (!empty($rightsubnet_spec))
845
					$ipsecconf .= "\trightsubnet = " . join(",", $rightsubnet_spec) . "\n";
846
				if (!empty($leftsubnet_spec))
847
					$ipsecconf .= "\tleftsubnet = " . join(",", $leftsubnet_spec) . "\n";
848
		}
849
	}
850

    
851
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.conf", $ipsecconf);
852
	unset($ipsecconf);
853
	/* end ipsec.conf */
854

    
855
	/* mange process */
856
	if (isvalidpid("{$g['varrun_path']}/charon.pid")) {
857
		/* Read secrets */
858
		mwexec("/usr/local/sbin/ipsec rereadall", false);
859
		/* Update configuration changes */
860
		mwexec("/usr/local/sbin/ipsec update", false);
861
		mwexec("/usr/local/sbin/ipsec reload", false);
862
	} else {
863
		mwexec("/usr/local/sbin/ipsec start", false); 
864
	}
865

    
866
	if ($natfilterrules == true)
867
		filter_configure();
868
	/* start filterdns, if necessary */
869
	if (count($filterdns_list) > 0) {
870
		$interval = 60;
871
		if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval']))
872
			$interval = $ipseccfg['dns-interval'];
873

    
874
		$hostnames = "";
875
		array_unique($filterdns_list);
876
		foreach ($filterdns_list as $hostname)
877
			$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload ipsecdns\"'\n";
878
		file_put_contents("{$g['varetc_path']}/ipsec/filterdns-ipsec.hosts", $hostnames);
879
		unset($hostnames);
880

    
881
		if (isvalidpid("{$g['varrun_path']}/filterdns-ipsec.pid"))
882
			sigkillbypid("{$g['varrun_path']}/filterdns-ipsec.pid", "HUP");
883
		else {
884
			mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/ipsec/filterdns-ipsec.hosts -d 1");
885
		}
886
	} else {
887
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
888
		@unlink("{$g['varrun_path']}/filterdns-ipsec.pid");
889
	}
890

    
891
	if (platform_booting())
892
		echo "done\n";
893

    
894
	return count($filterdns_list);
895
}
896

    
897
/*
898
 * Forcefully restart IPsec
899
 * This is required for when dynamic interfaces reload
900
 * For all other occasions the normal vpn_ipsec_configure()
901
 * will gracefully reload the settings without restarting
902
 */
903
function vpn_ipsec_force_reload($interface = "") {
904
	global $g, $config;
905

    
906
	$ipseccfg = $config['ipsec'];
907

    
908
	if (!empty($interface) && is_array($ipseccfg['phase1'])) {
909
		$found = false;
910
		foreach ($ipseccfg['phase1'] as $ipsec) {
911
			if (!isset($ipsec['disabled']) && ($ipsec['interface'] == $interface)) {
912
				$found = true;
913
				break;
914
			}
915
		}
916
		if (!$found) {
917
			log_error(sprintf(gettext("Ignoring IPsec reload since there are no tunnels on interface %s"), $interface));
918
			return;
919
		}
920
	}
921

    
922
	/* if ipsec is enabled, start up again */
923
	if (isset($ipseccfg['enable'])) {
924
		log_error(gettext("Forcefully reloading IPsec"));
925
		vpn_ipsec_configure();
926
	}
927
}
928

    
929
/* master setup for vpn (mpd) */
930
function vpn_setup() {
931
	global $g;
932

    
933
	if ($g['platform'] == 'jail')
934
		return;
935

    
936
	/* start pptpd */
937
	vpn_pptpd_configure();
938

    
939
	/* start pppoe server */
940
	vpn_pppoes_configure();
941

    
942
	/* setup l2tp */
943
	vpn_l2tp_configure();
944
}
945

    
946
function vpn_netgraph_support() {
947
	$iflist = get_configured_interface_list();
948
	foreach ($iflist as $iface) {
949
		$realif = get_real_interface($iface);
950
		/* Get support for netgraph(4) from the nic */
951
		$ifinfo = pfSense_get_interface_addresses($realif);
952
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge")))
953
			pfSense_ngctl_attach(".", $realif);
954
	}
955
}
956

    
957
function vpn_pptpd_configure() {
958
	global $config, $g;
959

    
960
	$syscfg = $config['system'];
961
	$pptpdcfg = $config['pptpd'];
962

    
963
	if (platform_booting()) {
964
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
965
			return 0;
966

    
967
		if (platform_booting(true))
968
			echo gettext("Configuring PPTP VPN service... ");
969
	} else {
970
		/* kill mpd */
971
		killbypid("{$g['varrun_path']}/pptp-vpn.pid");
972

    
973
		/* wait for process to die */
974
		sleep(3);
975

    
976
		if (is_process_running("mpd -b")) {
977
			killbypid("{$g['varrun_path']}/pptp-vpn.pid");
978
			log_error(gettext("Could not kill mpd within 3 seconds.   Trying again."));
979
		}
980

    
981
		/* remove mpd.conf, if it exists */
982
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.conf");
983
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.links");
984
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.secret");
985
	}
986

    
987
	if (empty($pptpdcfg['n_pptp_units'])) {
988
		log_error("Something wrong in the PPTPd configuration. Preventing starting the daemon because issues would arise.");
989
		return;
990
	}
991

    
992
	/* make sure pptp-vpn directory exists */
993
	if (!file_exists("{$g['varetc_path']}/pptp-vpn"))
994
		mkdir("{$g['varetc_path']}/pptp-vpn");
995

    
996
	switch ($pptpdcfg['mode']) {
997
		case 'server' :
998
			/* write mpd.conf */
999
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.conf", "w");
1000
			if (!$fd) {
1001
				printf(gettext("Error: cannot open mpd.conf in vpn_pptpd_configure().") . "\n");
1002
				return 1;
1003
			}
1004

    
1005
			$mpdconf = <<<EOD
1006
pptps:
1007

    
1008
EOD;
1009

    
1010
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1011
				$mpdconf .= "	load pt{$i}\n";
1012
			}
1013

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

    
1016
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
1017

    
1018
				$mpdconf .= <<<EOD
1019

    
1020
pt{$i}:
1021
	new -i pptpd{$i} pt{$i} pt{$i}
1022
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
1023
	load pts
1024

    
1025
EOD;
1026
			}
1027

    
1028
			$mpdconf .=<<<EOD
1029

    
1030
pts:
1031
	set iface disable on-demand
1032
	set iface enable proxy-arp
1033
	set iface enable tcpmssfix
1034
	set iface idle 1800
1035
	set iface up-script /usr/local/sbin/vpn-linkup
1036
	set iface down-script /usr/local/sbin/vpn-linkdown
1037
	set bundle enable multilink
1038
	set bundle enable crypt-reqd
1039
	set link yes acfcomp protocomp
1040
	set link no pap chap
1041
	set link enable chap-msv2
1042
	set link mtu 1460
1043
	set link keep-alive 10 60
1044
	set ipcp yes vjcomp
1045
	set bundle enable compression
1046
	set ccp yes mppc
1047
	set ccp yes mpp-e128
1048
	set ccp yes mpp-stateless
1049

    
1050
EOD;
1051

    
1052
			if (!isset ($pptpdcfg['req128'])) {
1053
				$mpdconf .=<<<EOD
1054
	set ccp yes mpp-e40
1055
	set ccp yes mpp-e56
1056

    
1057
EOD;
1058
			}
1059

    
1060
			if  (isset($pptpdcfg["wins"]) && $pptpdcfg['wins'] != "")
1061
				$mpdconf  .=  "	set ipcp nbns {$pptpdcfg['wins']}\n";
1062

    
1063
			if (!empty($pptpdcfg['dns1'])) {
1064
				$mpdconf .= "	set ipcp dns " . $pptpdcfg['dns1'];
1065
				if (!empty($pptpdcfg['dns2']))
1066
					$mpdconf .= " " . $pptpdcfg['dns2'];
1067
				$mpdconf .= "\n";
1068
			} elseif (isset ($config['dnsmasq']['enable'])) {
1069
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1070
				if ($syscfg['dnsserver'][0])
1071
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1072
				$mpdconf .= "\n";
1073
			} elseif (isset($config['unbound']['enable'])) {
1074
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1075
				if ($syscfg['dnsserver'][0])
1076
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1077
				$mpdconf .= "\n";
1078
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1079
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1080
			}
1081

    
1082
			if (isset ($pptpdcfg['radius']['server']['enable'])) {
1083
				$authport = (isset($pptpdcfg['radius']['server']['port']) && strlen($pptpdcfg['radius']['server']['port']) > 1) ? $pptpdcfg['radius']['server']['port'] : 1812;
1084
				$acctport = $authport + 1;
1085
				$mpdconf .=<<<EOD
1086
	set radius server {$pptpdcfg['radius']['server']['ip']} "{$pptpdcfg['radius']['server']['secret']}" {$authport} {$acctport}
1087

    
1088
EOD;
1089
			if (isset ($pptpdcfg['radius']['server2']['enable'])) {
1090
				$authport = (isset($pptpdcfg['radius']['server2']['port']) && strlen($pptpdcfg['radius']['server2']['port']) > 1) ? $pptpdcfg['radius']['server2']['port'] : 1812;
1091
				$acctport = $authport + 1;
1092
				$mpdconf .=<<<EOD
1093
	set radius server {$pptpdcfg['radius']['server2']['ip']} "{$pptpdcfg['radius']['server2']['secret2']}" {$authport} {$acctport}
1094

    
1095
EOD;
1096
			}
1097
			$mpdconf .=<<<EOD
1098
	set radius retries 3
1099
	set radius timeout 10
1100
	set auth enable radius-auth
1101

    
1102
EOD;
1103

    
1104
				if (isset ($pptpdcfg['radius']['accounting'])) {
1105
					$mpdconf .=<<<EOD
1106
	set auth enable radius-acct
1107
	set radius acct-update 300
1108

    
1109
EOD;
1110
				}
1111
			}
1112

    
1113
			fwrite($fd, $mpdconf);
1114
			fclose($fd);
1115
			unset($mpdconf);
1116

    
1117
			/* write mpd.links */
1118
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.links", "w");
1119
			if (!$fd) {
1120
				printf(gettext("Error: cannot open mpd.links in vpn_pptpd_configure().") . "\n");
1121
				return 1;
1122
			}
1123

    
1124
			$mpdlinks = "";
1125

    
1126
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1127
				$mpdlinks .=<<<EOD
1128

    
1129
pt{$i}:
1130
	set link type pptp
1131
	set pptp enable incoming
1132
	set pptp disable originate
1133
	set pptp disable windowing
1134

    
1135
EOD;
1136
			}
1137

    
1138
			fwrite($fd, $mpdlinks);
1139
			fclose($fd);
1140
			unset($mpdlinks);
1141

    
1142
			/* write mpd.secret */
1143
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.secret", "w");
1144
			if (!$fd) {
1145
				printf(gettext("Error: cannot open mpd.secret in vpn_pptpd_configure().") . "\n");
1146
				return 1;
1147
			}
1148

    
1149
			$mpdsecret = "";
1150

    
1151
			if (is_array($pptpdcfg['user'])) {
1152
				foreach ($pptpdcfg['user'] as $user) {
1153
					$pass = str_replace('\\', '\\\\', $user['password']);
1154
					$pass = str_replace('"', '\"', $pass);
1155
					$mpdsecret .= "{$user['name']} \"{$pass}\" {$user['ip']}\n";
1156
				}
1157
			}
1158

    
1159
			fwrite($fd, $mpdsecret);
1160
			fclose($fd);
1161
			unset($mpdsecret);
1162
			chmod("{$g['varetc_path']}/pptp-vpn/mpd.secret", 0600);
1163

    
1164
			vpn_netgraph_support();
1165

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

    
1169
			break;
1170

    
1171
		case 'redir' :
1172
			break;
1173
	}
1174

    
1175
	if (platform_booting())
1176
		echo "done\n";
1177

    
1178
	return 0;
1179
}
1180

    
1181
function vpn_pppoes_configure() {
1182
	global $config;
1183

    
1184
	if (is_array($config['pppoes']['pppoe'])) {
1185
		foreach ($config['pppoes']['pppoe'] as $pppoe)
1186
			vpn_pppoe_configure($pppoe);
1187
	}
1188
}
1189

    
1190
function vpn_pppoe_configure(&$pppoecfg) {
1191
	global $config, $g;
1192

    
1193
	$syscfg = $config['system'];
1194

    
1195
	/* create directory if it does not exist */
1196
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn"))
1197
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1198

    
1199
	if (platform_booting()) {
1200
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
1201
			return 0;
1202

    
1203
		echo gettext("Configuring PPPoE Server service... ");
1204
	} else {
1205
		/* kill mpd */
1206
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1207

    
1208
		/* wait for process to die */
1209
		sleep(2);
1210

    
1211
	}
1212

    
1213
	switch ($pppoecfg['mode']) {
1214

    
1215
		case 'server' :
1216

    
1217
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1218

    
1219
			if ($pppoecfg['paporchap'] == "chap")
1220
				$paporchap = "set link enable chap";
1221
			else
1222
				$paporchap = "set link enable pap";
1223

    
1224
			/* write mpd.conf */
1225
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1226
			if (!$fd) {
1227
				printf(gettext("Error: cannot open mpd.conf in vpn_pppoe_configure().") . "\n");
1228
				return 1;
1229
			}
1230
			$mpdconf = "\n\n";
1231
			$mpdconf .= "poes:\n";
1232

    
1233
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1234
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1235
			}
1236

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

    
1239
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1240

    
1241
				if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1242
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1243
				} else {
1244
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1245
				}
1246

    
1247
				$mpdconf .=<<<EOD
1248

    
1249
poes{$pppoecfg['pppoeid']}{$i}:
1250
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1251
	{$isssue_ip_type}
1252
	load pppoe_standard
1253

    
1254
EOD;
1255
			}
1256

    
1257
			$mpdconf .=<<<EOD
1258

    
1259
pppoe_standard:
1260
	set bundle no multilink
1261
	set bundle enable compression
1262
	set auth max-logins 1
1263
	set iface up-script /usr/local/sbin/vpn-linkup
1264
	set iface down-script /usr/local/sbin/vpn-linkdown
1265
	set iface idle 0
1266
	set iface disable on-demand
1267
	set iface disable proxy-arp
1268
	set iface enable tcpmssfix
1269
	set iface mtu 1500
1270
	set link no pap chap
1271
	{$paporchap}
1272
	set link keep-alive 60 180
1273
	set ipcp yes vjcomp
1274
	set ipcp no vjcomp
1275
	set link max-redial -1
1276
	set link mtu 1492
1277
	set link mru 1492
1278
	set ccp yes mpp-e40
1279
	set ccp yes mpp-e128
1280
	set ccp yes mpp-stateless
1281
	set link latency 1
1282
	#set ipcp dns 10.10.1.3
1283
	#set bundle accept encryption
1284

    
1285
EOD;
1286

    
1287
			if (!empty($pppoecfg['dns1'])) {
1288
				$mpdconf .= "	set ipcp dns " . $pppoecfg['dns1'];
1289
				if (!empty($pppoecfg['dns2']))
1290
					$mpdconf .= " " . $pppoecfg['dns2'];
1291
				$mpdconf .= "\n";
1292
			} elseif (isset ($config['dnsmasq']['enable'])) {
1293
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1294
				if ($syscfg['dnsserver'][0])
1295
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1296
				$mpdconf .= "\n";
1297
			} elseif (isset ($config['unbound']['enable'])) {
1298
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1299
				if ($syscfg['dnsserver'][0])
1300
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1301
				$mpdconf .= "\n";
1302
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1303
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1304
			}
1305

    
1306
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1307
				$radiusport = "";
1308
				$radiusacctport = "";
1309
				if (isset($pppoecfg['radius']['server']['port']))
1310
					$radiusport = $pppoecfg['radius']['server']['port'];
1311
				if (isset($pppoecfg['radius']['server']['acctport']))
1312
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1313
				$mpdconf .=<<<EOD
1314
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
1315
	set radius retries 3
1316
	set radius timeout 10
1317
	set auth enable radius-auth
1318

    
1319
EOD;
1320

    
1321
				if (isset ($pppoecfg['radius']['accounting'])) {
1322
					$mpdconf .=<<<EOD
1323
	set auth enable radius-acct
1324

    
1325
EOD;
1326
				}
1327
			}
1328

    
1329
			fwrite($fd, $mpdconf);
1330
			fclose($fd);
1331
			unset($mpdconf);
1332

    
1333
			/* write mpd.links */
1334
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.links", "w");
1335
			if (!$fd) {
1336
				printf(gettext("Error: cannot open mpd.links in vpn_pppoe_configure().") . "\n");
1337
				return 1;
1338
			}
1339

    
1340
			$mpdlinks = "";
1341

    
1342
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1343
				$mpdlinks .=<<<EOD
1344

    
1345
poes{$pppoecfg['pppoeid']}{$i}:
1346
	set phys type pppoe
1347
	set pppoe iface {$pppoe_interface}
1348
	set pppoe service "*"
1349
	set pppoe disable originate
1350
	set pppoe enable incoming
1351

    
1352
EOD;
1353
			}
1354

    
1355
			fwrite($fd, $mpdlinks);
1356
			fclose($fd);
1357
			unset($mpdlinks);
1358

    
1359
			if ($pppoecfg['username']) {
1360
				/* write mpd.secret */
1361
				$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
1362
				if (!$fd) {
1363
					printf(gettext("Error: cannot open mpd.secret in vpn_pppoe_configure().") . "\n");
1364
					return 1;
1365
				}
1366

    
1367
				$mpdsecret = "\n\n";
1368

    
1369
				if (!empty($pppoecfg['username'])) {
1370
					$item = explode(" ", $pppoecfg['username']);
1371
					foreach($item as $userdata) {
1372
						$data = explode(":", $userdata);
1373
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1374
					}
1375
				}
1376

    
1377
				fwrite($fd, $mpdsecret);
1378
				fclose($fd);
1379
				unset($mpdsecret);
1380
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1381
			}
1382

    
1383
			/* Check if previous instance is still up */
1384
			while (file_exists("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid") && isvalidpid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid"))
1385
				killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1386

    
1387
			/* Get support for netgraph(4) from the nic */
1388
			pfSense_ngctl_attach(".", $pppoe_interface);
1389
			/* fire up mpd */
1390
			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");
1391

    
1392
			break;
1393
	}
1394

    
1395
	if (platform_booting())
1396
		echo gettext("done") . "\n";
1397

    
1398
	return 0;
1399
}
1400

    
1401
function vpn_l2tp_configure() {
1402
	global $config, $g;
1403

    
1404
	$syscfg = $config['system'];
1405
	$l2tpcfg = $config['l2tp'];
1406

    
1407
	/* create directory if it does not exist */
1408
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn"))
1409
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1410

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

    
1415
		echo gettext("Configuring l2tp VPN service... ");
1416
	} else {
1417
		/* kill mpd */
1418
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1419

    
1420
		/* wait for process to die */
1421
		sleep(8);
1422

    
1423
	}
1424

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

    
1429
	switch ($l2tpcfg['mode']) {
1430

    
1431
		case 'server' :
1432
			if ($l2tpcfg['paporchap'] == "chap")
1433
				$paporchap = "set link enable chap";
1434
			else
1435
				$paporchap = "set link enable pap";
1436

    
1437
			/* write mpd.conf */
1438
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1439
			if (!$fd) {
1440
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
1441
				return 1;
1442
			}
1443
			$mpdconf = "\n\n";
1444
			$mpdconf .=<<<EOD
1445
l2tps:
1446

    
1447
EOD;
1448

    
1449
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1450
				$mpdconf .= "	load l2tp{$i}\n";
1451
			}
1452

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

    
1455
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1456

    
1457
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1458
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1459
				} else {
1460
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1461
				}
1462

    
1463
				$mpdconf .=<<<EOD
1464

    
1465
l2tp{$i}:
1466
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1467
	{$isssue_ip_type}
1468
	load l2tp_standard
1469

    
1470
EOD;
1471
			}
1472

    
1473
			$mpdconf .=<<<EOD
1474

    
1475
l2tp_standard:
1476
	set bundle disable multilink
1477
	set bundle enable compression
1478
	set bundle yes crypt-reqd
1479
	set ipcp yes vjcomp
1480
	# set ipcp ranges 131.188.69.161/32 131.188.69.170/28
1481
	set ccp yes mppc
1482
	set iface disable on-demand
1483
	set iface enable proxy-arp
1484
	set iface up-script /usr/local/sbin/vpn-linkup
1485
	set iface down-script /usr/local/sbin/vpn-linkdown
1486
	set link yes acfcomp protocomp
1487
	set link no pap chap
1488
	set link enable chap
1489
	set link keep-alive 10 180
1490

    
1491
EOD;
1492

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

    
1515
			if (isset ($l2tpcfg['radius']['enable'])) {
1516
				$mpdconf .=<<<EOD
1517
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1518
	set radius retries 3
1519
	set radius timeout 10
1520
	set auth enable radius-auth
1521

    
1522
EOD;
1523

    
1524
				if (isset ($l2tpcfg['radius']['accounting'])) {
1525
					$mpdconf .=<<<EOD
1526
	set auth enable radius-acct
1527

    
1528
EOD;
1529
				}
1530
			}
1531

    
1532
			fwrite($fd, $mpdconf);
1533
			fclose($fd);
1534
			unset($mpdconf);
1535

    
1536
			/* write mpd.links */
1537
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.links", "w");
1538
			if (!$fd) {
1539
				printf(gettext("Error: cannot open mpd.links in vpn_l2tp_configure().") . "\n");
1540
				return 1;
1541
			}
1542

    
1543
			$mpdlinks = "";
1544

    
1545
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1546
				$mpdlinks .=<<<EOD
1547

    
1548
l2tp{$i}:
1549
	set link type l2tp
1550
	set l2tp enable incoming
1551
	set l2tp disable originate
1552

    
1553
EOD;
1554
			if (!empty($l2tpcfg['secret']))
1555
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
1556
			}
1557

    
1558
			fwrite($fd, $mpdlinks);
1559
			fclose($fd);
1560
			unset($mpdlinks);
1561

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

    
1569
			$mpdsecret = "\n\n";
1570

    
1571
			if (is_array($l2tpcfg['user'])) {
1572
				foreach ($l2tpcfg['user'] as $user)
1573
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1574
			}
1575

    
1576
			fwrite($fd, $mpdsecret);
1577
			fclose($fd);
1578
			unset($mpdsecret);
1579
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
1580

    
1581
			vpn_netgraph_support();
1582

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

    
1586
			break;
1587

    
1588
		case 'redir' :
1589
			break;
1590
	}
1591

    
1592
	if (platform_booting())
1593
		echo "done\n";
1594

    
1595
	return 0;
1596
}
1597

    
1598
function vpn_ipsec_configure_preferoldsa() {
1599
	global $config;
1600
	if(isset($config['ipsec']['preferoldsa']))
1601
		set_single_sysctl("net.key.preferred_oldsa", "-30");
1602
	else
1603
		set_single_sysctl("net.key.preferred_oldsa", "0");
1604
}
1605

    
1606
?>
(59-59/68)