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
	$a_phase1 = $config['ipsec']['phase1'];
113
	$a_phase2 = $config['ipsec']['phase2'];
114
	$a_client = $config['ipsec']['client'];
115

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

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

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

    
129
		return 0;
130
	} else {
131
		$certpath = "{$g['varetc_path']}/ipsec/ipsec.d/certs";
132
		$capath = "{$g['varetc_path']}/ipsec/ipsec.d/cacerts";
133
		$keypath = "{$g['varetc_path']}/ipsec/ipsec.d/private";
134

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
321
EOD;
322

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
441
		$pskconf = "";
442

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

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

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

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

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

    
460
					@chmod($certpath, 0600);
461

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
633
				$left_spec = $ep;
634

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
797

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

    
803
				}
804
			}
805

    
806
					$ipsecconf .=<<<EOD
807

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

    
823
EOD;
824

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

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

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

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

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

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

    
893
	return count($filterdns_list);
894
}
895

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1007
EOD;
1008

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

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

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

    
1017
				$mpdconf .= <<<EOD
1018

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

    
1024
EOD;
1025
			}
1026

    
1027
			$mpdconf .=<<<EOD
1028

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

    
1049
EOD;
1050

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

    
1056
EOD;
1057
			}
1058

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

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

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

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

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

    
1101
EOD;
1102

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

    
1108
EOD;
1109
				}
1110
			}
1111

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

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

    
1123
			$mpdlinks = "";
1124

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

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

    
1134
EOD;
1135
			}
1136

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

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

    
1148
			$mpdsecret = "";
1149

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

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

    
1163
			vpn_netgraph_support();
1164

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

    
1168
			break;
1169

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

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

    
1177
	return 0;
1178
}
1179

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

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

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

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

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

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

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

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

    
1210
	}
1211

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

    
1214
		case 'server' :
1215

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

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

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

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

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

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

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

    
1246
				$mpdconf .=<<<EOD
1247

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

    
1253
EOD;
1254
			}
1255

    
1256
			$mpdconf .=<<<EOD
1257

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

    
1284
EOD;
1285

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

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

    
1318
EOD;
1319

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

    
1324
EOD;
1325
				}
1326
			}
1327

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

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

    
1339
			$mpdlinks = "";
1340

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

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

    
1351
EOD;
1352
			}
1353

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

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

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

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

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

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

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

    
1391
			break;
1392
	}
1393

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

    
1397
	return 0;
1398
}
1399

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

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

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

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

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

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

    
1422
	}
1423

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

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

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

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

    
1446
EOD;
1447

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

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

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

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

    
1462
				$mpdconf .=<<<EOD
1463

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

    
1469
EOD;
1470
			}
1471

    
1472
			$mpdconf .=<<<EOD
1473

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

    
1490
EOD;
1491

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

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

    
1521
EOD;
1522

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

    
1527
EOD;
1528
				}
1529
			}
1530

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

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

    
1542
			$mpdlinks = "";
1543

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

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

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

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

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

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

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

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

    
1580
			vpn_netgraph_support();
1581

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

    
1585
			break;
1586

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

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

    
1594
	return 0;
1595
}
1596

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

    
1605
?>
(59-59/68)