Project

General

Profile

Download (48.2 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

    
290
	$unity_enabled = 'no';
291
	if (isset($config['ipsec']['unityplugin']))
292
		$unity_enabled = 'yes';
293

    
294
	$strongswan = <<<EOD
295

    
296
# Automatically generated config file - DO NOT MODIFY. Changes will be overwritten. 
297
starter {
298
load_warning = no
299
}
300

    
301
charon {
302
# number of worker threads in charon
303
threads = 16
304
ikesa_table_size = 32
305
ikesa_table_segments = 4
306
init_limit_half_open = 1000
307
install_routes = no
308
{$i_dont_care_about_security_and_use_aggressive_mode_psk}
309
{$accept_unencrypted}
310
cisco_unity = {$unity_enabled}
311

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

    
327
EOD;
328

    
329
	$strongswan .= "\tplugins {\n";
330

    
331
	if (is_array($a_client) && isset($a_client['enable'])) {
332
		$strongswan .= "\t\tattr {\n";
333
		if ($a_client['pool_address'] && $a_client['pool_netbits'])
334
			$strongswan .= "\t\t\tsubnet = {$a_client['pool_address']}/{$a_client['pool_netbits']}\n";
335

    
336
		$cfgservers = array();
337
		if (!empty($a_client['dns_server1']))
338
			$cfgservers[] = $a_client['dns_server1'];
339
		if (!empty($a_client['dns_server2']))
340
			$cfgservers[] = $a_client['dns_server2'];
341
		if (!empty($a_client['dns_server3']))
342
			$cfgservers[] = $a_client['dns_server3'];
343
		if (!empty($a_client['dns_server4']))
344
			$cfgservers[] = $a_client['dns_server4'];
345

    
346
		if (!empty($cfgservers))
347
			$strongswan .= "\t\t\tdns = " . implode(",", $cfgservers) . "\n";
348
		unset($cfgservers);
349
		$cfgservers = array();
350
		if (!empty($a_client['wins_server1']))
351
			$cfgservers[] = $a_client['wins_server1'];
352
		if (!empty($a_client['wins_server2']))
353
			$cfgservers[] = $a_client['wins_server2'];
354
		if (!empty($cfgservers))
355
			$strongswan .= "\t\t\tnbns = " . implode(",", $cfgservers) . "\n";
356
		unset($cfgservers);
357

    
358
		if (isset($a_client['net_list'])) {
359
			$net_list = '';
360
			foreach ($a_phase2 as $ph2ent) {
361
				if (isset($ph2ent['disabled']))
362
					continue;
363

    
364
				if (!isset($ph2ent['mobile']))
365
					continue;
366

    
367
				$localid = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
368

    
369
				if (!empty($net_list))
370
					$net_list .= ",";
371
				$net_list .= $localid;
372
			}
373

    
374
			if (!empty($net_list)) {
375
				$strongswan .= "\t\t\tsplit-include = {$net_list}\n";
376
				unset($net_list);
377
			}
378
		}
379

    
380
		if (!empty($a_client['dns_domain'])) {
381
			$strongswan .= "\t\t\t# Search domain and default domain\n";
382
			$strongswan .= "\t\t\t28674 = {$a_client['dns_domain']}\n";
383
			if (empty($a_client['dns_split']))
384
				$strongswan .= "\t\t\t28675 = {$a_client['dns_domain']}";
385
			$strongswan .= "\n";
386
		}
387

    
388
		if (!empty($a_client['dns_split'])) {
389
			$strongswan .= "\t\t\t28675 = {$a_client['dns_split']}\n";
390
		}
391

    
392
		if (!empty($a_client['login_banner']))
393
			$strongswan .= "\t\t\t28672 = {$a_client['login_banner']}\n";
394

    
395
		if (isset($a_client['save_passwd']))
396
			$strongswan .= "\t\t\t28673 = 1\n";
397

    
398
		if ($a_client['pfs_group'])
399
			$strongswan .= "\t\t\t28679 = {$a_client['pfs_group']}\n";
400
		$strongswan .= "\t\t}\n";
401

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

    
421
	$strongswan .= "\t}\n}\n";
422
	@file_put_contents("{$g['varetc_path']}/ipsec/strongswan.conf", $strongswan);
423
	unset($strongswan);
424

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

    
447
	$pskconf = "";
448

    
449
	if (is_array($a_phase1) && count($a_phase1)) {
450
		foreach ($a_phase1 as $ph1ent) {
451

    
452
			if (isset($ph1ent['disabled']))
453
				continue;
454

    
455
			if (strstr($ph1ent['authentication_method'], 'rsa') || $ph1ent['authentication_method'] == 'eap-tls') {
456
				$certline = '';
457

    
458
				$ikeid = $ph1ent['ikeid'];
459
				$cert = lookup_cert($ph1ent['certref']);
460

    
461
				if (!$cert) {
462
					log_error(sprintf(gettext("Error: Invalid phase1 certificate reference for %s"), $ph1ent['name']));
463
					continue;
464
				}
465

    
466
				@chmod($certpath, 0600);
467

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

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

    
483
				/* XXX" Traffic selectors? */
484
				$pskconf .= " : RSA {$ph1keyfile}\n";
485
			} else {
486
				list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, 'local');
487
				list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, 'peer', $rgmap);
488

    
489
				if (empty($peerid_data))
490
					continue;
491

    
492
				$myid = isset($ph1ent['mobile']) ? trim($myid_data) : "%any";
493
				$peerid = ($peerid_data != 'allusers') ? trim($peerid_data) : '';
494
				if (!empty($ph1ent['pre-shared-key'])) {
495
					if ($myid_type == 'fqdn' && !empty($myid_data))
496
						$pskconf .= "@{$myid} {$peerid} : PSK 0s" . base64_encode(trim($ph1ent['pre-shared-key'])) . "\n";
497
					else
498
						$pskconf .= "{$myid} {$peerid} : PSK 0s" . base64_encode(trim($ph1ent['pre-shared-key'])) . "\n";
499
				}
500
			}
501
		}
502
	}
503

    
504
	/* Add user PSKs */
505
	if (is_array($config['system']) && is_array($config['system']['user'])) {
506
		foreach ($config['system']['user'] as $user) {
507
			if (!empty($user['ipsecpsk'])) {
508
				$pskconf .= "%any {$user['name']} : PSK 0s" . base64_encode($user['ipsecpsk']) . "\n";
509
			}
510
		}
511
		unset($user);
512
	}
513

    
514
	/* add PSKs for mobile clients */
515
	if (is_array($ipseccfg['mobilekey'])) {
516
		foreach ($ipseccfg['mobilekey'] as $key) {
517
			if ($key['ident'] == "allusers")
518
				$key['ident'] = '%any';
519
			$pskconf .= "%any {$key['ident']} : PSK 0s" . base64_encode($key['pre-shared-key']) . "\n";
520
		}
521
		unset($key);
522
	}
523

    
524
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.secrets", $pskconf);
525
	chmod("{$g['varetc_path']}/ipsec/ipsec.secrets", 0600);
526
	unset($pskconf);
527

    
528
	$natfilterrules = false;
529
	/* begin ipsec.conf */
530
	$ipsecconf = "";
531
	$enablecompression = false;
532
	if (is_array($a_phase1) && count($a_phase1))  {
533

    
534
		$ipsecconf .= "# This file is automatically generated. Do not edit\n";
535
		$ipsecconf .= "config setup\n\tuniqueids = yes\n";
536
		$ipsecconf .= "\tcharondebug=\"" . vpn_ipsec_configure_loglevels(true) . "\"\n";
537

    
538
		foreach ($a_phase1 as $ph1ent) {
539
			if (isset($ph1ent['disabled']))
540
				continue;
541

    
542
			if ($ph1ent['mode'] == "aggressive")
543
				$aggressive = "yes";
544
			else
545
				$aggressive = "no";
546

    
547
			$ep = ipsec_get_phase1_src($ph1ent);
548
			if (!$ep)
549
				continue;
550

    
551
			$ikeid = $ph1ent['ikeid'];
552
			$keyexchange = "ikev1";
553
			$passive = "route";
554
			if (!empty($ph1ent['iketype'])) {
555
				if ($ph1ent['iketype'] == "ikev2") {
556
					$keyexchange = "ikev2";
557
					//$passive = "start";
558
				} else if ($ph1ent['iketype'] == "auto")
559
					$keyexchange = "ike";
560
			}
561

    
562
			if (isset($ph1ent['mobile'])) {
563
				$right_spec = "%any";
564
				$passive = 'add';
565
			} else
566
				$right_spec = $ph1ent['remote-gateway'];
567

    
568
			list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, 'local');
569
			if ($myid_type != 'address')
570
				$myid_data = "{$myid_type}:{$myid_data}";
571

    
572
			/* Only specify peer ID if we are not dealing with a mobile PSK-only tunnel */
573
			$peerid_spec = '';
574
			if (!isset($ph1ent['mobile'])) {
575
				list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, 'peer', $rgmap);
576
				if ($peerid_type != 'address')
577
					$peerid_spec = "{$peerid_type}:{$peerid_data}";
578
				else
579
					$peerid_spec = $peerid_data;
580
			}
581

    
582
			if (is_array($ph1ent['encryption-algorithm']) && !empty($ph1ent['encryption-algorithm']['name']) && !empty($ph1ent['hash-algorithm'])) {
583
				$ealgosp1 = '';
584
				$ealg_id = $ph1ent['encryption-algorithm']['name'];
585
				$ealg_kl = $ph1ent['encryption-algorithm']['keylen'];
586
				if ($ealg_kl)
587
					$ealgosp1 = "ike = {$ealg_id}{$ealg_kl}-{$ph1ent['hash-algorithm']}";
588
				else
589
					$ealgosp1 = "ike = {$ealg_id}-{$ph1ent['hash-algorithm']}";
590

    
591
				$modp = vpn_ipsec_convert_to_modp($ph1ent['dhgroup']);
592
				if (!empty($modp))
593
					$ealgosp1 .= "-{$modp}";
594

    
595
				$ealgosp1 .= "!";
596
			}
597

    
598
			if ($ph1ent['dpd_delay'] && $ph1ent['dpd_maxfail']) {
599
				if ($passive == "route")
600
					$dpdline = "dpdaction = restart";
601
				else
602
					$dpdline = "dpdaction = clear";
603
				$dpdline .= "\n\tdpddelay = {$ph1ent['dpd_delay']}s";
604
				$dpdtimeout = $ph1ent['dpd_delay'] * ($ph1ent['dpd_maxfail'] + 1);
605
				$dpdline .= "\n\tdpdtimeout = {$dpdtimeout}s";
606
			} else
607
				$dpdline = "dpdaction = none";
608

    
609
			$ikelifeline = '';
610
			if ($ph1ent['lifetime'])
611
				$ikelifeline = "ikelifetime = {$ph1ent['lifetime']}s";
612

    
613
			$rightsourceip = NULL;
614
			if (isset($ph1ent['mobile']) && !empty($a_client['pool_address'])) 
615
				$rightsourceip = "\trightsourceip = {$a_client['pool_address']}/{$a_client['pool_netbits']}\n";
616

    
617
			$authentication = "";
618
			switch ($ph1ent['authentication_method']) {
619
			case 'eap-tls':
620
				$authentication = "leftauth=eap-tls\n\trightauth=eap-tls";
621
				if (!empty($ph1ent['certref']))
622
					$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
623
				break;
624
			case 'xauth_rsa_server':
625
				$authentication = "leftauth = pubkey\n\trightauth = pubkey";
626
				$authentication .= "\n\trightauth2 = xauth-generic";
627
				if (!empty($ph1ent['certref']))
628
					$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
629
				break;
630
			case 'xauth_psk_server':
631
				$authentication = "leftauth = psk\n\trightauth = psk";
632
				$authentication .= "\n\trightauth2 = xauth-generic";
633
				break;
634
			case 'pre_shared_key':
635
				$authentication = "leftauth = psk\n\trightauth = psk";
636
				break;
637
			case 'rsasig':
638
				$authentication = "leftauth = pubkey\n\trightauth = pubkey";
639
				if (!empty($ph1ent['certref']))
640
					$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
641
				break;
642
			case 'hybrid_rsa_server':
643
				$authentication = "leftauth = xauth-generic\n\trightauth = pubkey";
644
				$authentication .= "\n\trightauth2 = xauth";
645
				if (!empty($ph1ent['certref']))
646
					$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
647
				break;
648
			}
649

    
650
			$left_spec = $ep;
651

    
652
			if (isset($ph1ent['reauth_enable']))
653
				$reauth = "reauth = no";
654
			else
655
				$reauth = "reauth = yes";
656
			if (isset($ph1ent['rekey_enable']))
657
				$rekey = "rekey = no";
658
			else
659
				$rekey = "rekey = yes";
660

    
661
			if ($ph1ent['nat_traversal'] == 'off')
662
				$forceencaps = 'forceencaps = no';
663
			else if ($ph1ent['nat_traversal'] == 'force')
664
				$forceencaps = 'forceencaps = yes';
665
			else
666
				$forceencaps = 'forceencaps = no';
667

    
668
			$ipseclifetime = 0;
669
			$rightsubnet_spec = array();
670
			$leftsubnet_spec = array();
671
			$ealgoAHsp2arr = array();
672
			$ealgoESPsp2arr = array();
673
		if (is_array($a_phase2) && count($a_phase2)) {
674
			foreach ($a_phase2 as $ph2ent) {
675
				if ($ikeid != $ph2ent['ikeid'])
676
					continue;
677

    
678
				if (isset($ph2ent['disabled']))
679
					continue;
680

    
681
				if (isset($ph2ent['mobile']) && !isset($a_client['enable']))
682
					continue;
683

    
684
				if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
685
					$tunneltype = "type = tunnel";
686

    
687
					$localid_type = $ph2ent['localid']['type'];
688
					$leftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['localid'], false, $ph2ent['mode']);
689

    
690
					/* Do not print localid in some cases, such as a pure-psk or psk/xauth single phase2 mobile tunnel */
691
					if (($localid_type == "none" || $localid_type == "mobile")
692
					    && isset($ph1ent['mobile']) && (ipsec_get_number_of_phase2($ikeid)==1)) {
693
						$left_spec = '%any';
694
					} else {
695
						if ($localid_type != "address") {
696
							$localid_type = "subnet";
697
						}
698
						// Don't let an empty subnet into config, it can cause parse errors. Ticket #2201.
699
						if (!is_ipaddr($leftsubnet_data) && !is_subnet($leftsubnet_data) && ($leftsubnet_data != "0.0.0.0/0")) {
700
							log_error("Invalid IPsec Phase 2 \"{$ph2ent['descr']}\" - {$ph2ent['localid']['type']} has no subnet.");
701
							continue;
702
						}
703
						if (!empty($ph2ent['natlocalid'])) {
704
							$natleftsubnet_data =  ipsec_idinfo_to_cidr($ph2ent['natlocalid'], false, $ph2ent['mode']);
705
							if ($ph2ent['natlocalid']['type'] != "address") {
706
								if (is_subnet($natleftsubnet_data))
707
									$leftsubnet_data = "{$natleftsubnet_data}|{$leftsubnet_data}";
708
							} else {
709
								if (is_ipaddr($natleftsubnet_data))
710
									$leftsubnet_data = "{$natleftsubnet_data}|{$leftsubnet_data}";
711
							}
712
							$natfilterrules = true;
713
						}
714
					}
715

    
716
					$leftsubnet_spec[] = $leftsubnet_data;
717

    
718
					if (!isset($ph2ent['mobile'])) {
719
						$tmpsubnet = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']);
720
						$rightsubnet_spec[] = $tmpsubnet;
721
					} else if (!empty($a_client['pool_address'])) {
722
						$rightsubnet_spec[] = "{$a_client['pool_address']}/{$a_client['pool_netbits']}";
723
					}
724
				} else {
725
					$tunneltype = "type = transport";
726

    
727
					if ((($ph1ent['authentication_method'] == "xauth_psk_server") ||
728
					    ($ph1ent['authentication_method'] == "pre_shared_key")) && isset($ph1ent['mobile'])) {
729
						$left_spec = "%any";
730
					} else {
731
						$tmpsubnet = ipsec_get_phase1_src($ph1ent);
732
						$leftsubnet_spec[] = $tmpsubnet;
733
					}
734

    
735
					if (!isset($ph2ent['mobile'])) {
736
						$rightsubnet_spec[] = $right_spec;
737
					}
738
				}
739

    
740
				if (isset($a_client['pfs_group']))
741
					$ph2ent['pfsgroup'] = $a_client['pfs_group'];
742

    
743
				if ($ph2ent['protocol'] == 'esp') {
744
					if (is_array($ph2ent['encryption-algorithm-option'])) {
745
						foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
746
							$ealg_id = $ealg['name'];
747
							$ealg_kl = $ealg['keylen'];
748

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

    
810

    
811
				if (!empty($ph2ent['lifetime'])) {
812
					if ($ipseclifetime == 0 || intval($ipseclifetime) > intval($ph2ent['lifetime']))
813
						$ipseclifetime = intval($ph2ent['lifetime']);
814
				}
815

    
816
			}
817
		}
818

    
819
			$ipsecconnect =<<<EOD
820
	fragmentation = yes
821
	keyexchange = {$keyexchange}
822
	{$reauth}
823
	{$forceencaps}
824
	{$rekey}
825
	installpolicy = yes
826
	{$tunneltype}
827
	{$dpdline}
828
	auto = {$passive}
829
	left = {$left_spec}
830
	right = {$right_spec}
831
	leftid = {$myid_data}
832

    
833
EOD;
834

    
835
			if (isset($config['ipsec']['compression'])) {
836
				$ipsecconnect .= '\tcompress = yes\n';
837
				$enablecompression = true;
838
			}
839
			if (!empty($ikelifeline))
840
				$ipsecconnect .= "\t{$ikelifeline}\n";
841
			if ($ipseclifetime > 0)
842
				$ipsecconnect .= "\tlifetime = {$ipseclifetime}s\n";
843
			if (!empty($rightsourceip))
844
				$ipsecconnect .= "{$rightsourceip}";
845
			if (!empty($ealgosp1))
846
				$ipsecconnect .= "\t{$ealgosp1}\n";
847
			if (!empty($ealgoAHsp2arr))
848
				$ipsecconnect .= "\tah = " . join(',', $ealgoAHsp2arr) . "!\n";
849
			if (!empty($ealgoESPsp2arr))
850
				$ipsecconnect .= "\tesp = " . join(',', $ealgoESPsp2arr) . "!\n";
851
			if (!empty($authentication))
852
				$ipsecconnect .= "\t{$authentication}\n";
853
			if (!empty($peerid_spec))
854
				$ipsecconnect .= "\trightid = {$peerid_spec}\n";
855
			if ($keyexchange == 'ikev1')
856
				$ipsecconnect .= "\taggressive = {$aggressive}\n";
857

    
858
			if (!isset($ph1ent['mobile']) && $keyexchange == 'ikev1') {
859
				if (!empty($rightsubnet_spec)) {
860
					$ipsecfin = '';
861
					foreach ($rightsubnet_spec as $idx => $rsubnet) {
862
						$ipsecfin .= "\nconn con{$ph1ent['ikeid']}00{$idx}\n";
863
						$ipsecfin .= "\treqid = {$ikeid}00{$idx}\n";
864
						$ipsecfin .= $ipsecconnect;
865
						$ipsecfin .= "\trightsubnet = {$rsubnet}\n";
866
						$ipsecfin .= "\tleftsubnet = " . $leftsubnet_spec[$idx] . "\n";
867
					}
868
				} else
869
					log_error("No phase2 specifications for tunnel with REQID = {$ikeid}");
870
			} else {
871
				$ipsecfin = "\nconn con{$ph1ent['ikeid']}\n";
872
				$ipsecfin .= "\treqid = {$ikeid}\n";
873
				$ipsecfin .= $ipsecconnect;
874
				if (!empty($rightsubnet_spec)) {
875
					$tempsubnets = array();
876
					foreach ($rightsubnet_spec as $rightsubnet)
877
						$tempsubnets[$rightsubnet] = $rightsubnet;
878
					$ipsecfin .= "\trightsubnet = " . join(",", $tempsubnets) . "\n";
879
					unset($tempsubnets, $rightsubnet);
880
				}
881
				if (!empty($leftsubnet_spec)) {
882
					$tempsubnets = array();
883
					foreach ($leftsubnet_spec as $leftsubnet)
884
						$tempsubnets[$leftsubnet] = $leftsubnet;
885
					$ipsecfin .= "\tleftsubnet = " . join(",", $leftsubnet_spec) . "\n";
886
					unset($tempsubnets, $leftsubnet);
887
				}
888
			}
889
			$ipsecconf .= $ipsecfin;
890
			unset($ipsecfin);
891

    
892
		}
893
	}
894

    
895
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.conf", $ipsecconf);
896
	unset($ipsecconf);
897
	/* end ipsec.conf */
898

    
899
	if ($enablecompression === true)
900
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 1);
901
	else
902
		set_single_sysctl('net.inet.ipcomp.ipcomp_enable', 0);
903

    
904
	/* mange process */
905
	if (isvalidpid("{$g['varrun_path']}/charon.pid")) {
906
		/* Read secrets */
907
		mwexec("/usr/local/sbin/ipsec rereadall", false);
908
		/* Update configuration changes */
909
		mwexec("/usr/local/sbin/ipsec update", false);
910
		mwexec("/usr/local/sbin/ipsec reload", false);
911
	} else {
912
		mwexec("/usr/local/sbin/ipsec start", false); 
913
	}
914

    
915
	if ($natfilterrules == true)
916
		filter_configure();
917
	/* start filterdns, if necessary */
918
	if (count($filterdns_list) > 0) {
919
		$interval = 60;
920
		if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval']))
921
			$interval = $ipseccfg['dns-interval'];
922

    
923
		$hostnames = "";
924
		array_unique($filterdns_list);
925
		foreach ($filterdns_list as $hostname)
926
			$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload ipsecdns\"'\n";
927
		file_put_contents("{$g['varetc_path']}/ipsec/filterdns-ipsec.hosts", $hostnames);
928
		unset($hostnames);
929

    
930
		if (isvalidpid("{$g['varrun_path']}/filterdns-ipsec.pid"))
931
			sigkillbypid("{$g['varrun_path']}/filterdns-ipsec.pid", "HUP");
932
		else {
933
			mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/ipsec/filterdns-ipsec.hosts -d 1");
934
		}
935
	} else {
936
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
937
		@unlink("{$g['varrun_path']}/filterdns-ipsec.pid");
938
	}
939

    
940
	if (platform_booting())
941
		echo "done\n";
942

    
943
	return count($filterdns_list);
944
}
945

    
946
/*
947
 * Forcefully restart IPsec
948
 * This is required for when dynamic interfaces reload
949
 * For all other occasions the normal vpn_ipsec_configure()
950
 * will gracefully reload the settings without restarting
951
 */
952
function vpn_ipsec_force_reload($interface = "") {
953
	global $g, $config;
954

    
955
	$ipseccfg = $config['ipsec'];
956

    
957
	if (!empty($interface) && is_array($ipseccfg['phase1'])) {
958
		$found = false;
959
		foreach ($ipseccfg['phase1'] as $ipsec) {
960
			if (!isset($ipsec['disabled']) && ($ipsec['interface'] == $interface)) {
961
				$found = true;
962
				break;
963
			}
964
		}
965
		if (!$found) {
966
			log_error(sprintf(gettext("Ignoring IPsec reload since there are no tunnels on interface %s"), $interface));
967
			return;
968
		}
969
	}
970

    
971
	/* if ipsec is enabled, start up again */
972
	if (isset($ipseccfg['enable'])) {
973
		log_error(gettext("Forcefully reloading IPsec"));
974
		vpn_ipsec_configure();
975
	}
976
}
977

    
978
/* master setup for vpn (mpd) */
979
function vpn_setup() {
980
	global $g;
981

    
982
	if ($g['platform'] == 'jail')
983
		return;
984

    
985
	/* start pptpd */
986
	vpn_pptpd_configure();
987

    
988
	/* start pppoe server */
989
	vpn_pppoes_configure();
990

    
991
	/* setup l2tp */
992
	vpn_l2tp_configure();
993
}
994

    
995
function vpn_netgraph_support() {
996
	$iflist = get_configured_interface_list();
997
	foreach ($iflist as $iface) {
998
		$realif = get_real_interface($iface);
999
		/* Get support for netgraph(4) from the nic */
1000
		$ifinfo = pfSense_get_interface_addresses($realif);
1001
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge")))
1002
			pfSense_ngctl_attach(".", $realif);
1003
	}
1004
}
1005

    
1006
function vpn_pptpd_configure() {
1007
	global $config, $g;
1008

    
1009
	$syscfg = $config['system'];
1010
	$pptpdcfg = $config['pptpd'];
1011

    
1012
	if (platform_booting()) {
1013
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
1014
			return 0;
1015

    
1016
		if (platform_booting(true))
1017
			echo gettext("Configuring PPTP VPN service... ");
1018
	} else {
1019
		/* kill mpd */
1020
		killbypid("{$g['varrun_path']}/pptp-vpn.pid");
1021

    
1022
		/* wait for process to die */
1023
		sleep(3);
1024

    
1025
		if (is_process_running("mpd -b")) {
1026
			killbypid("{$g['varrun_path']}/pptp-vpn.pid");
1027
			log_error(gettext("Could not kill mpd within 3 seconds.   Trying again."));
1028
		}
1029

    
1030
		/* remove mpd.conf, if it exists */
1031
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.conf");
1032
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.links");
1033
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.secret");
1034
	}
1035

    
1036
	if (empty($pptpdcfg['n_pptp_units'])) {
1037
		log_error("Something wrong in the PPTPd configuration. Preventing starting the daemon because issues would arise.");
1038
		return;
1039
	}
1040

    
1041
	/* make sure pptp-vpn directory exists */
1042
	if (!file_exists("{$g['varetc_path']}/pptp-vpn"))
1043
		mkdir("{$g['varetc_path']}/pptp-vpn");
1044

    
1045
	switch ($pptpdcfg['mode']) {
1046
		case 'server' :
1047
			/* write mpd.conf */
1048
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.conf", "w");
1049
			if (!$fd) {
1050
				printf(gettext("Error: cannot open mpd.conf in vpn_pptpd_configure().") . "\n");
1051
				return 1;
1052
			}
1053

    
1054
			$mpdconf = <<<EOD
1055
pptps:
1056

    
1057
EOD;
1058

    
1059
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1060
				$mpdconf .= "	load pt{$i}\n";
1061
			}
1062

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

    
1065
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
1066

    
1067
				$mpdconf .= <<<EOD
1068

    
1069
pt{$i}:
1070
	new -i pptpd{$i} pt{$i} pt{$i}
1071
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
1072
	load pts
1073

    
1074
EOD;
1075
			}
1076

    
1077
			$mpdconf .=<<<EOD
1078

    
1079
pts:
1080
	set iface disable on-demand
1081
	set iface enable proxy-arp
1082
	set iface enable tcpmssfix
1083
	set iface idle 1800
1084
	set iface up-script /usr/local/sbin/vpn-linkup
1085
	set iface down-script /usr/local/sbin/vpn-linkdown
1086
	set bundle enable multilink
1087
	set bundle enable crypt-reqd
1088
	set link yes acfcomp protocomp
1089
	set link no pap chap
1090
	set link enable chap-msv2
1091
	set link mtu 1460
1092
	set link keep-alive 10 60
1093
	set ipcp yes vjcomp
1094
	set bundle enable compression
1095
	set ccp yes mppc
1096
	set ccp yes mpp-e128
1097
	set ccp yes mpp-stateless
1098

    
1099
EOD;
1100

    
1101
			if (!isset ($pptpdcfg['req128'])) {
1102
				$mpdconf .=<<<EOD
1103
	set ccp yes mpp-e40
1104
	set ccp yes mpp-e56
1105

    
1106
EOD;
1107
			}
1108

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

    
1112
			if (!empty($pptpdcfg['dns1'])) {
1113
				$mpdconf .= "	set ipcp dns " . $pptpdcfg['dns1'];
1114
				if (!empty($pptpdcfg['dns2']))
1115
					$mpdconf .= " " . $pptpdcfg['dns2'];
1116
				$mpdconf .= "\n";
1117
			} elseif (isset ($config['dnsmasq']['enable'])) {
1118
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1119
				if ($syscfg['dnsserver'][0])
1120
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1121
				$mpdconf .= "\n";
1122
			} elseif (isset($config['unbound']['enable'])) {
1123
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1124
				if ($syscfg['dnsserver'][0])
1125
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1126
				$mpdconf .= "\n";
1127
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1128
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1129
			}
1130

    
1131
			if (isset ($pptpdcfg['radius']['server']['enable'])) {
1132
				$authport = (isset($pptpdcfg['radius']['server']['port']) && strlen($pptpdcfg['radius']['server']['port']) > 1) ? $pptpdcfg['radius']['server']['port'] : 1812;
1133
				$acctport = $authport + 1;
1134
				$mpdconf .=<<<EOD
1135
	set radius server {$pptpdcfg['radius']['server']['ip']} "{$pptpdcfg['radius']['server']['secret']}" {$authport} {$acctport}
1136

    
1137
EOD;
1138
			if (isset ($pptpdcfg['radius']['server2']['enable'])) {
1139
				$authport = (isset($pptpdcfg['radius']['server2']['port']) && strlen($pptpdcfg['radius']['server2']['port']) > 1) ? $pptpdcfg['radius']['server2']['port'] : 1812;
1140
				$acctport = $authport + 1;
1141
				$mpdconf .=<<<EOD
1142
	set radius server {$pptpdcfg['radius']['server2']['ip']} "{$pptpdcfg['radius']['server2']['secret2']}" {$authport} {$acctport}
1143

    
1144
EOD;
1145
			}
1146
			$mpdconf .=<<<EOD
1147
	set radius retries 3
1148
	set radius timeout 10
1149
	set auth enable radius-auth
1150

    
1151
EOD;
1152

    
1153
				if (isset ($pptpdcfg['radius']['accounting'])) {
1154
					$mpdconf .=<<<EOD
1155
	set auth enable radius-acct
1156
	set radius acct-update 300
1157

    
1158
EOD;
1159
				}
1160
			}
1161

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

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

    
1173
			$mpdlinks = "";
1174

    
1175
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1176
				$mpdlinks .=<<<EOD
1177

    
1178
pt{$i}:
1179
	set link type pptp
1180
	set pptp enable incoming
1181
	set pptp disable originate
1182
	set pptp disable windowing
1183

    
1184
EOD;
1185
			}
1186

    
1187
			fwrite($fd, $mpdlinks);
1188
			fclose($fd);
1189
			unset($mpdlinks);
1190

    
1191
			/* write mpd.secret */
1192
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.secret", "w");
1193
			if (!$fd) {
1194
				printf(gettext("Error: cannot open mpd.secret in vpn_pptpd_configure().") . "\n");
1195
				return 1;
1196
			}
1197

    
1198
			$mpdsecret = "";
1199

    
1200
			if (is_array($pptpdcfg['user'])) {
1201
				foreach ($pptpdcfg['user'] as $user) {
1202
					$pass = str_replace('\\', '\\\\', $user['password']);
1203
					$pass = str_replace('"', '\"', $pass);
1204
					$mpdsecret .= "{$user['name']} \"{$pass}\" {$user['ip']}\n";
1205
				}
1206
			}
1207

    
1208
			fwrite($fd, $mpdsecret);
1209
			fclose($fd);
1210
			unset($mpdsecret);
1211
			chmod("{$g['varetc_path']}/pptp-vpn/mpd.secret", 0600);
1212

    
1213
			vpn_netgraph_support();
1214

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

    
1218
			break;
1219

    
1220
		case 'redir' :
1221
			break;
1222
	}
1223

    
1224
	if (platform_booting())
1225
		echo "done\n";
1226

    
1227
	return 0;
1228
}
1229

    
1230
function vpn_pppoes_configure() {
1231
	global $config;
1232

    
1233
	if (is_array($config['pppoes']['pppoe'])) {
1234
		foreach ($config['pppoes']['pppoe'] as $pppoe)
1235
			vpn_pppoe_configure($pppoe);
1236
	}
1237
}
1238

    
1239
function vpn_pppoe_configure(&$pppoecfg) {
1240
	global $config, $g;
1241

    
1242
	$syscfg = $config['system'];
1243

    
1244
	/* create directory if it does not exist */
1245
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn"))
1246
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1247

    
1248
	if (platform_booting()) {
1249
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
1250
			return 0;
1251

    
1252
		echo gettext("Configuring PPPoE Server service... ");
1253
	} else {
1254
		/* kill mpd */
1255
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1256

    
1257
		/* wait for process to die */
1258
		sleep(2);
1259

    
1260
	}
1261

    
1262
	switch ($pppoecfg['mode']) {
1263

    
1264
		case 'server' :
1265

    
1266
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1267

    
1268
			if ($pppoecfg['paporchap'] == "chap")
1269
				$paporchap = "set link enable chap";
1270
			else
1271
				$paporchap = "set link enable pap";
1272

    
1273
			/* write mpd.conf */
1274
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1275
			if (!$fd) {
1276
				printf(gettext("Error: cannot open mpd.conf in vpn_pppoe_configure().") . "\n");
1277
				return 1;
1278
			}
1279
			$mpdconf = "\n\n";
1280
			$mpdconf .= "poes:\n";
1281

    
1282
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1283
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1284
			}
1285

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

    
1288
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1289

    
1290
				if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1291
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1292
				} else {
1293
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1294
				}
1295

    
1296
				$mpdconf .=<<<EOD
1297

    
1298
poes{$pppoecfg['pppoeid']}{$i}:
1299
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1300
	{$isssue_ip_type}
1301
	load pppoe_standard
1302

    
1303
EOD;
1304
			}
1305

    
1306
			$mpdconf .=<<<EOD
1307

    
1308
pppoe_standard:
1309
	set bundle no multilink
1310
	set bundle enable compression
1311
	set auth max-logins 1
1312
	set iface up-script /usr/local/sbin/vpn-linkup
1313
	set iface down-script /usr/local/sbin/vpn-linkdown
1314
	set iface idle 0
1315
	set iface disable on-demand
1316
	set iface disable proxy-arp
1317
	set iface enable tcpmssfix
1318
	set iface mtu 1500
1319
	set link no pap chap
1320
	{$paporchap}
1321
	set link keep-alive 60 180
1322
	set ipcp yes vjcomp
1323
	set ipcp no vjcomp
1324
	set link max-redial -1
1325
	set link mtu 1492
1326
	set link mru 1492
1327
	set ccp yes mpp-e40
1328
	set ccp yes mpp-e128
1329
	set ccp yes mpp-stateless
1330
	set link latency 1
1331
	#set ipcp dns 10.10.1.3
1332
	#set bundle accept encryption
1333

    
1334
EOD;
1335

    
1336
			if (!empty($pppoecfg['dns1'])) {
1337
				$mpdconf .= "	set ipcp dns " . $pppoecfg['dns1'];
1338
				if (!empty($pppoecfg['dns2']))
1339
					$mpdconf .= " " . $pppoecfg['dns2'];
1340
				$mpdconf .= "\n";
1341
			} elseif (isset ($config['dnsmasq']['enable'])) {
1342
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1343
				if ($syscfg['dnsserver'][0])
1344
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1345
				$mpdconf .= "\n";
1346
			} elseif (isset ($config['unbound']['enable'])) {
1347
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1348
				if ($syscfg['dnsserver'][0])
1349
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1350
				$mpdconf .= "\n";
1351
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1352
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1353
			}
1354

    
1355
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1356
				$radiusport = "";
1357
				$radiusacctport = "";
1358
				if (isset($pppoecfg['radius']['server']['port']))
1359
					$radiusport = $pppoecfg['radius']['server']['port'];
1360
				if (isset($pppoecfg['radius']['server']['acctport']))
1361
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1362
				$mpdconf .=<<<EOD
1363
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
1364
	set radius retries 3
1365
	set radius timeout 10
1366
	set auth enable radius-auth
1367

    
1368
EOD;
1369

    
1370
				if (isset ($pppoecfg['radius']['accounting'])) {
1371
					$mpdconf .=<<<EOD
1372
	set auth enable radius-acct
1373

    
1374
EOD;
1375
				}
1376
			}
1377

    
1378
			fwrite($fd, $mpdconf);
1379
			fclose($fd);
1380
			unset($mpdconf);
1381

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

    
1389
			$mpdlinks = "";
1390

    
1391
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1392
				$mpdlinks .=<<<EOD
1393

    
1394
poes{$pppoecfg['pppoeid']}{$i}:
1395
	set phys type pppoe
1396
	set pppoe iface {$pppoe_interface}
1397
	set pppoe service "*"
1398
	set pppoe disable originate
1399
	set pppoe enable incoming
1400

    
1401
EOD;
1402
			}
1403

    
1404
			fwrite($fd, $mpdlinks);
1405
			fclose($fd);
1406
			unset($mpdlinks);
1407

    
1408
			if ($pppoecfg['username']) {
1409
				/* write mpd.secret */
1410
				$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
1411
				if (!$fd) {
1412
					printf(gettext("Error: cannot open mpd.secret in vpn_pppoe_configure().") . "\n");
1413
					return 1;
1414
				}
1415

    
1416
				$mpdsecret = "\n\n";
1417

    
1418
				if (!empty($pppoecfg['username'])) {
1419
					$item = explode(" ", $pppoecfg['username']);
1420
					foreach($item as $userdata) {
1421
						$data = explode(":", $userdata);
1422
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1423
					}
1424
				}
1425

    
1426
				fwrite($fd, $mpdsecret);
1427
				fclose($fd);
1428
				unset($mpdsecret);
1429
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1430
			}
1431

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

    
1436
			/* Get support for netgraph(4) from the nic */
1437
			pfSense_ngctl_attach(".", $pppoe_interface);
1438
			/* fire up mpd */
1439
			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");
1440

    
1441
			break;
1442
	}
1443

    
1444
	if (platform_booting())
1445
		echo gettext("done") . "\n";
1446

    
1447
	return 0;
1448
}
1449

    
1450
function vpn_l2tp_configure() {
1451
	global $config, $g;
1452

    
1453
	$syscfg = $config['system'];
1454
	$l2tpcfg = $config['l2tp'];
1455

    
1456
	/* create directory if it does not exist */
1457
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn"))
1458
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1459

    
1460
	if (platform_booting()) {
1461
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off"))
1462
			return 0;
1463

    
1464
		echo gettext("Configuring l2tp VPN service... ");
1465
	} else {
1466
		/* kill mpd */
1467
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1468

    
1469
		/* wait for process to die */
1470
		sleep(8);
1471

    
1472
	}
1473

    
1474
	/* make sure l2tp-vpn directory exists */
1475
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn"))
1476
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1477

    
1478
	switch ($l2tpcfg['mode']) {
1479

    
1480
		case 'server' :
1481
			if ($l2tpcfg['paporchap'] == "chap")
1482
				$paporchap = "set link enable chap";
1483
			else
1484
				$paporchap = "set link enable pap";
1485

    
1486
			/* write mpd.conf */
1487
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1488
			if (!$fd) {
1489
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
1490
				return 1;
1491
			}
1492
			$mpdconf = "\n\n";
1493
			$mpdconf .=<<<EOD
1494
l2tps:
1495

    
1496
EOD;
1497

    
1498
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1499
				$mpdconf .= "	load l2tp{$i}\n";
1500
			}
1501

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

    
1504
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1505

    
1506
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1507
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1508
				} else {
1509
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1510
				}
1511

    
1512
				$mpdconf .=<<<EOD
1513

    
1514
l2tp{$i}:
1515
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1516
	{$isssue_ip_type}
1517
	load l2tp_standard
1518

    
1519
EOD;
1520
			}
1521

    
1522
			$mpdconf .=<<<EOD
1523

    
1524
l2tp_standard:
1525
	set bundle disable multilink
1526
	set bundle enable compression
1527
	set bundle yes crypt-reqd
1528
	set ipcp yes vjcomp
1529
	# set ipcp ranges 131.188.69.161/32 131.188.69.170/28
1530
	set ccp yes mppc
1531
	set iface disable on-demand
1532
	set iface enable proxy-arp
1533
	set iface up-script /usr/local/sbin/vpn-linkup
1534
	set iface down-script /usr/local/sbin/vpn-linkdown
1535
	set link yes acfcomp protocomp
1536
	set link no pap chap
1537
	set link enable chap
1538
	set link keep-alive 10 180
1539

    
1540
EOD;
1541

    
1542
			if (is_ipaddr($l2tpcfg['wins'])) {
1543
				$mpdconf .= "	set ipcp nbns {$l2tpcfg['wins']}\n";
1544
			}
1545
			if (is_ipaddr($l2tpcfg['dns1'])) {
1546
				$mpdconf .= "	set ipcp dns " . $l2tpcfg['dns1'];
1547
				if (is_ipaddr($l2tpcfg['dns2']))
1548
					$mpdconf .= " " . $l2tpcfg['dns2'];
1549
				$mpdconf .= "\n";
1550
			} elseif (isset ($config['dnsmasq']['enable'])) {
1551
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1552
				if ($syscfg['dnsserver'][0])
1553
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1554
				$mpdconf .= "\n";
1555
			} elseif (isset ($config['unbound']['enable'])) {
1556
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1557
				if ($syscfg['dnsserver'][0])
1558
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1559
				$mpdconf .= "\n";
1560
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1561
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1562
			}
1563

    
1564
			if (isset ($l2tpcfg['radius']['enable'])) {
1565
				$mpdconf .=<<<EOD
1566
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1567
	set radius retries 3
1568
	set radius timeout 10
1569
	set auth enable radius-auth
1570

    
1571
EOD;
1572

    
1573
				if (isset ($l2tpcfg['radius']['accounting'])) {
1574
					$mpdconf .=<<<EOD
1575
	set auth enable radius-acct
1576

    
1577
EOD;
1578
				}
1579
			}
1580

    
1581
			fwrite($fd, $mpdconf);
1582
			fclose($fd);
1583
			unset($mpdconf);
1584

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

    
1592
			$mpdlinks = "";
1593

    
1594
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1595
				$mpdlinks .=<<<EOD
1596

    
1597
l2tp{$i}:
1598
	set link type l2tp
1599
	set l2tp enable incoming
1600
	set l2tp disable originate
1601

    
1602
EOD;
1603
			if (!empty($l2tpcfg['secret']))
1604
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
1605
			}
1606

    
1607
			fwrite($fd, $mpdlinks);
1608
			fclose($fd);
1609
			unset($mpdlinks);
1610

    
1611
			/* write mpd.secret */
1612
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.secret", "w");
1613
			if (!$fd) {
1614
				printf(gettext("Error: cannot open mpd.secret in vpn_l2tp_configure().") . "\n");
1615
				return 1;
1616
			}
1617

    
1618
			$mpdsecret = "\n\n";
1619

    
1620
			if (is_array($l2tpcfg['user'])) {
1621
				foreach ($l2tpcfg['user'] as $user)
1622
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1623
			}
1624

    
1625
			fwrite($fd, $mpdsecret);
1626
			fclose($fd);
1627
			unset($mpdsecret);
1628
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
1629

    
1630
			vpn_netgraph_support();
1631

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

    
1635
			break;
1636

    
1637
		case 'redir' :
1638
			break;
1639
	}
1640

    
1641
	if (platform_booting())
1642
		echo "done\n";
1643

    
1644
	return 0;
1645
}
1646

    
1647
function vpn_ipsec_configure_preferoldsa() {
1648
	global $config;
1649
	if(isset($config['ipsec']['preferoldsa']))
1650
		set_single_sysctl("net.key.preferred_oldsa", "-30");
1651
	else
1652
		set_single_sysctl("net.key.preferred_oldsa", "0");
1653
}
1654

    
1655
?>
(59-59/68)