Project

General

Profile

Download (47.4 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
	if (!isset($ipseccfg['enable'])) {
113
		/* try to stop charon */
114
		mwexec("/usr/local/sbin/ipsec stop");
115
		/* Stop dynamic monitoring */
116
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
117

    
118
		/* wait for process to die */
119
		sleep(2);
120

    
121
		/* disallow IPSEC, it is off */
122
		mwexec("/sbin/ifconfig enc0 down");
123
		set_single_sysctl("net.inet.ip.ipsec_in_use", "0");
124

    
125
		return 0;
126
	}
127

    
128
	$a_phase1 = $config['ipsec']['phase1'];
129
	$a_phase2 = $config['ipsec']['phase2'];
130
	$a_client = $config['ipsec']['client'];
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

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

    
700
					$leftsubnet_spec[] = $leftsubnet_data;
701

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

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

    
719
					if (!isset($ph2ent['mobile'])) {
720
						$rightsubnet_spec[] = $right_spec;
721
					}
722
				}
723

    
724
				if (isset($a_client['pfs_group']))
725
					$ph2ent['pfsgroup'] = $a_client['pfs_group'];
726

    
727
				if ($ph2ent['protocol'] == 'esp') {
728
					if (is_array($ph2ent['encryption-algorithm-option'])) {
729
						foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
730
							$ealg_id = $ealg['name'];
731
							$ealg_kl = $ealg['keylen'];
732

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

    
794

    
795
				if (!empty($ph2ent['lifetime'])) {
796
					if ($ipseclifetime == 0 || intval($ipseclifetime) > intval($ph2ent['lifetime']))
797
						$ipseclifetime = intval($ph2ent['lifetime']);
798
				}
799

    
800
			}
801
		}
802

    
803
			$ipsecconnect =<<<EOD
804
	fragmentation = yes
805
	keyexchange = {$keyexchange}
806
	{$reauth}
807
	{$forceencaps}
808
	{$rekey}
809
	installpolicy = yes
810
	{$tunneltype}
811
	{$dpdline}
812
	auto = {$passive}
813
	left = {$left_spec}
814
	right = {$right_spec}
815
	leftid = {$myid_data}
816

    
817
EOD;
818

    
819
			if (!empty($ikelifeline))
820
				$ipsecconnect .= "\t{$ikelifeline}\n";
821
			if ($ipseclifetime > 0)
822
				$ipsecconnect .= "\tlifetime = {$ipseclifetime}s\n";
823
			if (!empty($rightsourceip))
824
				$ipsecconnect .= "{$rightsourceip}";
825
			if (!empty($ealgosp1))
826
				$ipsecconnect .= "\t{$ealgosp1}\n";
827
			if (!empty($ealgoAHsp2arr))
828
				$ipsecconnect .= "\tah = " . join(',', $ealgoAHsp2arr) . "!\n";
829
			if (!empty($ealgoESPsp2arr))
830
				$ipsecconnect .= "\tesp = " . join(',', $ealgoESPsp2arr) . "!\n";
831
			if (!empty($authentication))
832
				$ipsecconnect .= "\t{$authentication}\n";
833
			if (!empty($peerid_spec))
834
				$ipsecconnect .= "\trightid = {$peerid_spec}\n";
835
			if ($keyexchange == 'ikev1')
836
				$ipsecconnect .= "\taggressive = {$aggressive}\n";
837

    
838
			if (!isset($ph1ent['mobile']) && $keyexchange == 'ikev1') {
839
				if (!empty($rightsubnet_spec)) {
840
					$ipsecfin = '';
841
					foreach ($rightsubnet_spec as $idx => $rsubnet) {
842
						$ipsecfin .= "\nconn con{$ph1ent['ikeid']}00{$idx}\n";
843
						$ipsecfin .= "\treqid = {$ikeid}00{$idx}\n";
844
						$ipsecfin .= $ipsecconnect;
845
						$ipsecfin .= "\trightsubnet = {$rsubnet}\n";
846
						$ipsecfin .= "\tleftsubnet = " . $leftsubnet_spec[$idx] . "\n";
847
					}
848
				} else
849
					log_error("No phase2 specifications for tunnel with REQID = {$ikeid}");
850
			} else {
851
				$ipsecfin = "\nconn con{$ph1ent['ikeid']}\n";
852
				$ipsecfin .= "\treqid = {$ikeid}\n";
853
				$ipsecfin .= $ipsecconnect;
854
				if (!empty($rightsubnet_spec)) {
855
					$tempsubnets = array();
856
					foreach ($rightsubnet_spec as $rightsubnet)
857
						$tempsubnets[$rightsubnet] = $rightsubnet;
858
					$ipsecfin .= "\trightsubnet = " . join(",", $tempsubnets) . "\n";
859
					unset($tempsubnets, $rightsubnet);
860
				}
861
				if (!empty($leftsubnet_spec)) {
862
					$tempsubnets = array();
863
					foreach ($leftsubnet_spec as $leftsubnet)
864
						$tempsubnets[$leftsubnet] = $leftsubnet;
865
					$ipsecfin .= "\tleftsubnet = " . join(",", $leftsubnet_spec) . "\n";
866
					unset($tempsubnets, $leftsubnet);
867
				}
868
			}
869
			$ipsecconf .= $ipsecfin;
870
			unset($ipsecfin);
871

    
872
		}
873
	}
874

    
875
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.conf", $ipsecconf);
876
	unset($ipsecconf);
877
	/* end ipsec.conf */
878

    
879
	/* mange process */
880
	if (isvalidpid("{$g['varrun_path']}/charon.pid")) {
881
		/* Read secrets */
882
		mwexec("/usr/local/sbin/ipsec rereadall", false);
883
		/* Update configuration changes */
884
		mwexec("/usr/local/sbin/ipsec update", false);
885
		mwexec("/usr/local/sbin/ipsec reload", false);
886
	} else {
887
		mwexec("/usr/local/sbin/ipsec start", false); 
888
	}
889

    
890
	if ($natfilterrules == true)
891
		filter_configure();
892
	/* start filterdns, if necessary */
893
	if (count($filterdns_list) > 0) {
894
		$interval = 60;
895
		if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval']))
896
			$interval = $ipseccfg['dns-interval'];
897

    
898
		$hostnames = "";
899
		array_unique($filterdns_list);
900
		foreach ($filterdns_list as $hostname)
901
			$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload ipsecdns\"'\n";
902
		file_put_contents("{$g['varetc_path']}/ipsec/filterdns-ipsec.hosts", $hostnames);
903
		unset($hostnames);
904

    
905
		if (isvalidpid("{$g['varrun_path']}/filterdns-ipsec.pid"))
906
			sigkillbypid("{$g['varrun_path']}/filterdns-ipsec.pid", "HUP");
907
		else {
908
			mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/ipsec/filterdns-ipsec.hosts -d 1");
909
		}
910
	} else {
911
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
912
		@unlink("{$g['varrun_path']}/filterdns-ipsec.pid");
913
	}
914

    
915
	if (platform_booting())
916
		echo "done\n";
917

    
918
	return count($filterdns_list);
919
}
920

    
921
/*
922
 * Forcefully restart IPsec
923
 * This is required for when dynamic interfaces reload
924
 * For all other occasions the normal vpn_ipsec_configure()
925
 * will gracefully reload the settings without restarting
926
 */
927
function vpn_ipsec_force_reload($interface = "") {
928
	global $g, $config;
929

    
930
	$ipseccfg = $config['ipsec'];
931

    
932
	if (!empty($interface) && is_array($ipseccfg['phase1'])) {
933
		$found = false;
934
		foreach ($ipseccfg['phase1'] as $ipsec) {
935
			if (!isset($ipsec['disabled']) && ($ipsec['interface'] == $interface)) {
936
				$found = true;
937
				break;
938
			}
939
		}
940
		if (!$found) {
941
			log_error(sprintf(gettext("Ignoring IPsec reload since there are no tunnels on interface %s"), $interface));
942
			return;
943
		}
944
	}
945

    
946
	/* if ipsec is enabled, start up again */
947
	if (isset($ipseccfg['enable'])) {
948
		log_error(gettext("Forcefully reloading IPsec"));
949
		vpn_ipsec_configure();
950
	}
951
}
952

    
953
/* master setup for vpn (mpd) */
954
function vpn_setup() {
955
	global $g;
956

    
957
	if ($g['platform'] == 'jail')
958
		return;
959

    
960
	/* start pptpd */
961
	vpn_pptpd_configure();
962

    
963
	/* start pppoe server */
964
	vpn_pppoes_configure();
965

    
966
	/* setup l2tp */
967
	vpn_l2tp_configure();
968
}
969

    
970
function vpn_netgraph_support() {
971
	$iflist = get_configured_interface_list();
972
	foreach ($iflist as $iface) {
973
		$realif = get_real_interface($iface);
974
		/* Get support for netgraph(4) from the nic */
975
		$ifinfo = pfSense_get_interface_addresses($realif);
976
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge")))
977
			pfSense_ngctl_attach(".", $realif);
978
	}
979
}
980

    
981
function vpn_pptpd_configure() {
982
	global $config, $g;
983

    
984
	$syscfg = $config['system'];
985
	$pptpdcfg = $config['pptpd'];
986

    
987
	if (platform_booting()) {
988
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
989
			return 0;
990

    
991
		if (platform_booting(true))
992
			echo gettext("Configuring PPTP VPN service... ");
993
	} else {
994
		/* kill mpd */
995
		killbypid("{$g['varrun_path']}/pptp-vpn.pid");
996

    
997
		/* wait for process to die */
998
		sleep(3);
999

    
1000
		if (is_process_running("mpd -b")) {
1001
			killbypid("{$g['varrun_path']}/pptp-vpn.pid");
1002
			log_error(gettext("Could not kill mpd within 3 seconds.   Trying again."));
1003
		}
1004

    
1005
		/* remove mpd.conf, if it exists */
1006
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.conf");
1007
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.links");
1008
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.secret");
1009
	}
1010

    
1011
	if (empty($pptpdcfg['n_pptp_units'])) {
1012
		log_error("Something wrong in the PPTPd configuration. Preventing starting the daemon because issues would arise.");
1013
		return;
1014
	}
1015

    
1016
	/* make sure pptp-vpn directory exists */
1017
	if (!file_exists("{$g['varetc_path']}/pptp-vpn"))
1018
		mkdir("{$g['varetc_path']}/pptp-vpn");
1019

    
1020
	switch ($pptpdcfg['mode']) {
1021
		case 'server' :
1022
			/* write mpd.conf */
1023
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.conf", "w");
1024
			if (!$fd) {
1025
				printf(gettext("Error: cannot open mpd.conf in vpn_pptpd_configure().") . "\n");
1026
				return 1;
1027
			}
1028

    
1029
			$mpdconf = <<<EOD
1030
pptps:
1031

    
1032
EOD;
1033

    
1034
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1035
				$mpdconf .= "	load pt{$i}\n";
1036
			}
1037

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

    
1040
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
1041

    
1042
				$mpdconf .= <<<EOD
1043

    
1044
pt{$i}:
1045
	new -i pptpd{$i} pt{$i} pt{$i}
1046
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
1047
	load pts
1048

    
1049
EOD;
1050
			}
1051

    
1052
			$mpdconf .=<<<EOD
1053

    
1054
pts:
1055
	set iface disable on-demand
1056
	set iface enable proxy-arp
1057
	set iface enable tcpmssfix
1058
	set iface idle 1800
1059
	set iface up-script /usr/local/sbin/vpn-linkup
1060
	set iface down-script /usr/local/sbin/vpn-linkdown
1061
	set bundle enable multilink
1062
	set bundle enable crypt-reqd
1063
	set link yes acfcomp protocomp
1064
	set link no pap chap
1065
	set link enable chap-msv2
1066
	set link mtu 1460
1067
	set link keep-alive 10 60
1068
	set ipcp yes vjcomp
1069
	set bundle enable compression
1070
	set ccp yes mppc
1071
	set ccp yes mpp-e128
1072
	set ccp yes mpp-stateless
1073

    
1074
EOD;
1075

    
1076
			if (!isset ($pptpdcfg['req128'])) {
1077
				$mpdconf .=<<<EOD
1078
	set ccp yes mpp-e40
1079
	set ccp yes mpp-e56
1080

    
1081
EOD;
1082
			}
1083

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

    
1087
			if (!empty($pptpdcfg['dns1'])) {
1088
				$mpdconf .= "	set ipcp dns " . $pptpdcfg['dns1'];
1089
				if (!empty($pptpdcfg['dns2']))
1090
					$mpdconf .= " " . $pptpdcfg['dns2'];
1091
				$mpdconf .= "\n";
1092
			} elseif (isset ($config['dnsmasq']['enable'])) {
1093
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1094
				if ($syscfg['dnsserver'][0])
1095
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1096
				$mpdconf .= "\n";
1097
			} elseif (isset($config['unbound']['enable'])) {
1098
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1099
				if ($syscfg['dnsserver'][0])
1100
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1101
				$mpdconf .= "\n";
1102
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1103
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1104
			}
1105

    
1106
			if (isset ($pptpdcfg['radius']['server']['enable'])) {
1107
				$authport = (isset($pptpdcfg['radius']['server']['port']) && strlen($pptpdcfg['radius']['server']['port']) > 1) ? $pptpdcfg['radius']['server']['port'] : 1812;
1108
				$acctport = $authport + 1;
1109
				$mpdconf .=<<<EOD
1110
	set radius server {$pptpdcfg['radius']['server']['ip']} "{$pptpdcfg['radius']['server']['secret']}" {$authport} {$acctport}
1111

    
1112
EOD;
1113
			if (isset ($pptpdcfg['radius']['server2']['enable'])) {
1114
				$authport = (isset($pptpdcfg['radius']['server2']['port']) && strlen($pptpdcfg['radius']['server2']['port']) > 1) ? $pptpdcfg['radius']['server2']['port'] : 1812;
1115
				$acctport = $authport + 1;
1116
				$mpdconf .=<<<EOD
1117
	set radius server {$pptpdcfg['radius']['server2']['ip']} "{$pptpdcfg['radius']['server2']['secret2']}" {$authport} {$acctport}
1118

    
1119
EOD;
1120
			}
1121
			$mpdconf .=<<<EOD
1122
	set radius retries 3
1123
	set radius timeout 10
1124
	set auth enable radius-auth
1125

    
1126
EOD;
1127

    
1128
				if (isset ($pptpdcfg['radius']['accounting'])) {
1129
					$mpdconf .=<<<EOD
1130
	set auth enable radius-acct
1131
	set radius acct-update 300
1132

    
1133
EOD;
1134
				}
1135
			}
1136

    
1137
			fwrite($fd, $mpdconf);
1138
			fclose($fd);
1139
			unset($mpdconf);
1140

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

    
1148
			$mpdlinks = "";
1149

    
1150
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1151
				$mpdlinks .=<<<EOD
1152

    
1153
pt{$i}:
1154
	set link type pptp
1155
	set pptp enable incoming
1156
	set pptp disable originate
1157
	set pptp disable windowing
1158

    
1159
EOD;
1160
			}
1161

    
1162
			fwrite($fd, $mpdlinks);
1163
			fclose($fd);
1164
			unset($mpdlinks);
1165

    
1166
			/* write mpd.secret */
1167
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.secret", "w");
1168
			if (!$fd) {
1169
				printf(gettext("Error: cannot open mpd.secret in vpn_pptpd_configure().") . "\n");
1170
				return 1;
1171
			}
1172

    
1173
			$mpdsecret = "";
1174

    
1175
			if (is_array($pptpdcfg['user'])) {
1176
				foreach ($pptpdcfg['user'] as $user) {
1177
					$pass = str_replace('\\', '\\\\', $user['password']);
1178
					$pass = str_replace('"', '\"', $pass);
1179
					$mpdsecret .= "{$user['name']} \"{$pass}\" {$user['ip']}\n";
1180
				}
1181
			}
1182

    
1183
			fwrite($fd, $mpdsecret);
1184
			fclose($fd);
1185
			unset($mpdsecret);
1186
			chmod("{$g['varetc_path']}/pptp-vpn/mpd.secret", 0600);
1187

    
1188
			vpn_netgraph_support();
1189

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

    
1193
			break;
1194

    
1195
		case 'redir' :
1196
			break;
1197
	}
1198

    
1199
	if (platform_booting())
1200
		echo "done\n";
1201

    
1202
	return 0;
1203
}
1204

    
1205
function vpn_pppoes_configure() {
1206
	global $config;
1207

    
1208
	if (is_array($config['pppoes']['pppoe'])) {
1209
		foreach ($config['pppoes']['pppoe'] as $pppoe)
1210
			vpn_pppoe_configure($pppoe);
1211
	}
1212
}
1213

    
1214
function vpn_pppoe_configure(&$pppoecfg) {
1215
	global $config, $g;
1216

    
1217
	$syscfg = $config['system'];
1218

    
1219
	/* create directory if it does not exist */
1220
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn"))
1221
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1222

    
1223
	if (platform_booting()) {
1224
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
1225
			return 0;
1226

    
1227
		echo gettext("Configuring PPPoE Server service... ");
1228
	} else {
1229
		/* kill mpd */
1230
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1231

    
1232
		/* wait for process to die */
1233
		sleep(2);
1234

    
1235
	}
1236

    
1237
	switch ($pppoecfg['mode']) {
1238

    
1239
		case 'server' :
1240

    
1241
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1242

    
1243
			if ($pppoecfg['paporchap'] == "chap")
1244
				$paporchap = "set link enable chap";
1245
			else
1246
				$paporchap = "set link enable pap";
1247

    
1248
			/* write mpd.conf */
1249
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1250
			if (!$fd) {
1251
				printf(gettext("Error: cannot open mpd.conf in vpn_pppoe_configure().") . "\n");
1252
				return 1;
1253
			}
1254
			$mpdconf = "\n\n";
1255
			$mpdconf .= "poes:\n";
1256

    
1257
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1258
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1259
			}
1260

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

    
1263
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1264

    
1265
				if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1266
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1267
				} else {
1268
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1269
				}
1270

    
1271
				$mpdconf .=<<<EOD
1272

    
1273
poes{$pppoecfg['pppoeid']}{$i}:
1274
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1275
	{$isssue_ip_type}
1276
	load pppoe_standard
1277

    
1278
EOD;
1279
			}
1280

    
1281
			$mpdconf .=<<<EOD
1282

    
1283
pppoe_standard:
1284
	set bundle no multilink
1285
	set bundle enable compression
1286
	set auth max-logins 1
1287
	set iface up-script /usr/local/sbin/vpn-linkup
1288
	set iface down-script /usr/local/sbin/vpn-linkdown
1289
	set iface idle 0
1290
	set iface disable on-demand
1291
	set iface disable proxy-arp
1292
	set iface enable tcpmssfix
1293
	set iface mtu 1500
1294
	set link no pap chap
1295
	{$paporchap}
1296
	set link keep-alive 60 180
1297
	set ipcp yes vjcomp
1298
	set ipcp no vjcomp
1299
	set link max-redial -1
1300
	set link mtu 1492
1301
	set link mru 1492
1302
	set ccp yes mpp-e40
1303
	set ccp yes mpp-e128
1304
	set ccp yes mpp-stateless
1305
	set link latency 1
1306
	#set ipcp dns 10.10.1.3
1307
	#set bundle accept encryption
1308

    
1309
EOD;
1310

    
1311
			if (!empty($pppoecfg['dns1'])) {
1312
				$mpdconf .= "	set ipcp dns " . $pppoecfg['dns1'];
1313
				if (!empty($pppoecfg['dns2']))
1314
					$mpdconf .= " " . $pppoecfg['dns2'];
1315
				$mpdconf .= "\n";
1316
			} elseif (isset ($config['dnsmasq']['enable'])) {
1317
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1318
				if ($syscfg['dnsserver'][0])
1319
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1320
				$mpdconf .= "\n";
1321
			} elseif (isset ($config['unbound']['enable'])) {
1322
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1323
				if ($syscfg['dnsserver'][0])
1324
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1325
				$mpdconf .= "\n";
1326
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1327
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1328
			}
1329

    
1330
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1331
				$radiusport = "";
1332
				$radiusacctport = "";
1333
				if (isset($pppoecfg['radius']['server']['port']))
1334
					$radiusport = $pppoecfg['radius']['server']['port'];
1335
				if (isset($pppoecfg['radius']['server']['acctport']))
1336
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1337
				$mpdconf .=<<<EOD
1338
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
1339
	set radius retries 3
1340
	set radius timeout 10
1341
	set auth enable radius-auth
1342

    
1343
EOD;
1344

    
1345
				if (isset ($pppoecfg['radius']['accounting'])) {
1346
					$mpdconf .=<<<EOD
1347
	set auth enable radius-acct
1348

    
1349
EOD;
1350
				}
1351
			}
1352

    
1353
			fwrite($fd, $mpdconf);
1354
			fclose($fd);
1355
			unset($mpdconf);
1356

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

    
1364
			$mpdlinks = "";
1365

    
1366
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1367
				$mpdlinks .=<<<EOD
1368

    
1369
poes{$pppoecfg['pppoeid']}{$i}:
1370
	set phys type pppoe
1371
	set pppoe iface {$pppoe_interface}
1372
	set pppoe service "*"
1373
	set pppoe disable originate
1374
	set pppoe enable incoming
1375

    
1376
EOD;
1377
			}
1378

    
1379
			fwrite($fd, $mpdlinks);
1380
			fclose($fd);
1381
			unset($mpdlinks);
1382

    
1383
			if ($pppoecfg['username']) {
1384
				/* write mpd.secret */
1385
				$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
1386
				if (!$fd) {
1387
					printf(gettext("Error: cannot open mpd.secret in vpn_pppoe_configure().") . "\n");
1388
					return 1;
1389
				}
1390

    
1391
				$mpdsecret = "\n\n";
1392

    
1393
				if (!empty($pppoecfg['username'])) {
1394
					$item = explode(" ", $pppoecfg['username']);
1395
					foreach($item as $userdata) {
1396
						$data = explode(":", $userdata);
1397
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1398
					}
1399
				}
1400

    
1401
				fwrite($fd, $mpdsecret);
1402
				fclose($fd);
1403
				unset($mpdsecret);
1404
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1405
			}
1406

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

    
1411
			/* Get support for netgraph(4) from the nic */
1412
			pfSense_ngctl_attach(".", $pppoe_interface);
1413
			/* fire up mpd */
1414
			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");
1415

    
1416
			break;
1417
	}
1418

    
1419
	if (platform_booting())
1420
		echo gettext("done") . "\n";
1421

    
1422
	return 0;
1423
}
1424

    
1425
function vpn_l2tp_configure() {
1426
	global $config, $g;
1427

    
1428
	$syscfg = $config['system'];
1429
	$l2tpcfg = $config['l2tp'];
1430

    
1431
	/* create directory if it does not exist */
1432
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn"))
1433
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1434

    
1435
	if (platform_booting()) {
1436
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off"))
1437
			return 0;
1438

    
1439
		echo gettext("Configuring l2tp VPN service... ");
1440
	} else {
1441
		/* kill mpd */
1442
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1443

    
1444
		/* wait for process to die */
1445
		sleep(8);
1446

    
1447
	}
1448

    
1449
	/* make sure l2tp-vpn directory exists */
1450
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn"))
1451
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1452

    
1453
	switch ($l2tpcfg['mode']) {
1454

    
1455
		case 'server' :
1456
			if ($l2tpcfg['paporchap'] == "chap")
1457
				$paporchap = "set link enable chap";
1458
			else
1459
				$paporchap = "set link enable pap";
1460

    
1461
			/* write mpd.conf */
1462
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1463
			if (!$fd) {
1464
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
1465
				return 1;
1466
			}
1467
			$mpdconf = "\n\n";
1468
			$mpdconf .=<<<EOD
1469
l2tps:
1470

    
1471
EOD;
1472

    
1473
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1474
				$mpdconf .= "	load l2tp{$i}\n";
1475
			}
1476

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

    
1479
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1480

    
1481
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1482
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1483
				} else {
1484
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1485
				}
1486

    
1487
				$mpdconf .=<<<EOD
1488

    
1489
l2tp{$i}:
1490
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1491
	{$isssue_ip_type}
1492
	load l2tp_standard
1493

    
1494
EOD;
1495
			}
1496

    
1497
			$mpdconf .=<<<EOD
1498

    
1499
l2tp_standard:
1500
	set bundle disable multilink
1501
	set bundle enable compression
1502
	set bundle yes crypt-reqd
1503
	set ipcp yes vjcomp
1504
	# set ipcp ranges 131.188.69.161/32 131.188.69.170/28
1505
	set ccp yes mppc
1506
	set iface disable on-demand
1507
	set iface enable proxy-arp
1508
	set iface up-script /usr/local/sbin/vpn-linkup
1509
	set iface down-script /usr/local/sbin/vpn-linkdown
1510
	set link yes acfcomp protocomp
1511
	set link no pap chap
1512
	set link enable chap
1513
	set link keep-alive 10 180
1514

    
1515
EOD;
1516

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

    
1539
			if (isset ($l2tpcfg['radius']['enable'])) {
1540
				$mpdconf .=<<<EOD
1541
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1542
	set radius retries 3
1543
	set radius timeout 10
1544
	set auth enable radius-auth
1545

    
1546
EOD;
1547

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

    
1552
EOD;
1553
				}
1554
			}
1555

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

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

    
1567
			$mpdlinks = "";
1568

    
1569
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1570
				$mpdlinks .=<<<EOD
1571

    
1572
l2tp{$i}:
1573
	set link type l2tp
1574
	set l2tp enable incoming
1575
	set l2tp disable originate
1576

    
1577
EOD;
1578
			if (!empty($l2tpcfg['secret']))
1579
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
1580
			}
1581

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

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

    
1593
			$mpdsecret = "\n\n";
1594

    
1595
			if (is_array($l2tpcfg['user'])) {
1596
				foreach ($l2tpcfg['user'] as $user)
1597
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1598
			}
1599

    
1600
			fwrite($fd, $mpdsecret);
1601
			fclose($fd);
1602
			unset($mpdsecret);
1603
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
1604

    
1605
			vpn_netgraph_support();
1606

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

    
1610
			break;
1611

    
1612
		case 'redir' :
1613
			break;
1614
	}
1615

    
1616
	if (platform_booting())
1617
		echo "done\n";
1618

    
1619
	return 0;
1620
}
1621

    
1622
function vpn_ipsec_configure_preferoldsa() {
1623
	global $config;
1624
	if(isset($config['ipsec']['preferoldsa']))
1625
		set_single_sysctl("net.key.preferred_oldsa", "-30");
1626
	else
1627
		set_single_sysctl("net.key.preferred_oldsa", "0");
1628
}
1629

    
1630
?>
(59-59/68)