Projet

Général

Profil

Télécharger (43,8 ko) Statistiques
| Branche: | Tag: | Révision:

univnautes / etc / inc / vpn.inc @ bf8aab82

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}"]))
52
			$forconfig ? $cfgtext[] = "{$lkey} = -1" : 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}"]) >= 1 && 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
		mwexec("/sbin/ifconfig enc0 up");
132
		set_single_sysctl("net.inet.ip.ipsec_in_use", "1");
133
		/* needed for config files */
134
		if (!is_dir("{$g['varetc_path']}/ipsec"))
135
			mkdir("{$g['varetc_path']}/ipsec");
136
		if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d"))
137
			mkdir("{$g['varetc_path']}/ipsec/ipsec.d");
138
		if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/cacerts"))
139
			mkdir("{$g['varetc_path']}/ipsec/ipsec.d/cacerts");
140
		if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/private"))
141
			mkdir("{$g['varetc_path']}/ipsec/ipsec.d/private");
142
		if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/crls"))
143
			mkdir("{$g['varetc_path']}/ipsec/ipsec.d/crls");
144
		if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/certs"))
145
			mkdir("{$g['varetc_path']}/ipsec/ipsec.d/certs");
146
		if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/aacerts"))
147
			mkdir("{$g['varetc_path']}/ipsec/ipsec.d/aacerts");
148
		if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/acerts"))
149
			mkdir("{$g['varetc_path']}/ipsec/ipsec.d/acerts");
150
		if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/ocspcerts"))
151
			mkdir("{$g['varetc_path']}/ipsec/ipsec.d/ocspcerts");
152
		if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/reqs"))
153
			mkdir("{$g['varetc_path']}/ipsec/ipsec.d/reqs");
154
		
155

    
156
		if ($g['booting'])
157
			echo gettext("Configuring IPsec VPN... ");
158

    
159
		/* fastforwarding is not compatible with ipsec tunnels */
160
		set_single_sysctl("net.inet.ip.fastforwarding", "0");
161

    
162
		/* resolve all local, peer addresses and setup pings */
163
		$ipmap = array();
164
		$rgmap = array();
165
		$filterdns_list = array();
166
		$listeniflist = array();
167
		unset($iflist);
168
		if (is_array($a_phase1) && count($a_phase1)) {
169

    
170
			$ipsecpinghosts = "";
171
			/* step through each phase1 entry */
172
			foreach ($a_phase1 as $ph1ent) {
173
				if (isset($ph1ent['disabled']))
174
					continue;
175

    
176
				$listeniflist = get_real_interface($a_phase1['interface']);
177

    
178
				$ep = ipsec_get_phase1_src($ph1ent);
179
				if (!is_ipaddr($ep))
180
					continue;
181

    
182
				if(!in_array($ep,$ipmap))
183
					$ipmap[] = $ep;
184

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

    
188
				if (isset ($ph1ent['mobile']))
189
					continue;
190

    
191
				$rg = $ph1ent['remote-gateway'];
192

    
193
				if (!is_ipaddr($rg)) {
194
					$filterdns_list[] = "{$rg}";
195
					add_hostname_to_watch($rg);
196
					if(! $g['booting'])
197
						$rg = resolve_retry($rg);
198
					if (!is_ipaddr($rg))
199
						continue;
200
				}
201
				if(array_search($rg, $rgmap)) {
202
					log_error("The remote gateway {$rg} already exists on another phase 1 entry");
203
					continue;
204
				}
205
				$rgmap[$ph1ent['remote-gateway']] = $rg;
206

    
207
				if (is_array($a_phase2)) {
208
					/* step through each phase2 entry */
209
					foreach ($a_phase2 as $ph2ent) {
210
						$ikeid = $ph2ent['ikeid'];
211

    
212
						if (isset($ph2ent['disabled']))
213
							continue;
214

    
215
						if ($ikeid != $ph1ent['ikeid'])
216
							continue;
217

    
218
						/* add an ipsec pinghosts entry */
219
						if ($ph2ent['pinghost']) {
220
							if (!is_array($iflist))
221
								$iflist = get_configured_interface_list();
222
							foreach ($iflist as $ifent => $ifname) {
223
								if(is_ipaddrv6($ph2ent['pinghost'])) {
224
									$interface_ip = get_interface_ipv6($ifent);
225
									if(!is_ipaddrv6($interface_ip))
226
										continue;
227
									$local_subnet = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
228
									if (ip_in_subnet($interface_ip, $local_subnet)) {
229
										$srcip = $interface_ip;
230
										break;
231
									}
232
								} else {
233
									$interface_ip = get_interface_ip($ifent);
234
									if(!is_ipaddrv4($interface_ip))
235
										continue;
236
									$local_subnet = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
237
									if ($local_subnet == "0.0.0.0/0" || ip_in_subnet($interface_ip, $local_subnet)) {
238
										$srcip = $interface_ip;
239
										break;
240
									}
241
								}
242
							}
243
							$dstip = $ph2ent['pinghost'];
244
							if(is_ipaddrv6($dstip)) {
245
								$family = "inet6";
246
							} else {
247
								$family = "inet";
248
							}
249
							if (is_ipaddr($srcip))
250
								$ipsecpinghosts[] = "{$srcip}|{$dstip}|3|||||{$family}|\n";
251
						}
252
					}
253
				}
254
			}
255
			@file_put_contents("{$g['vardb_path']}/ipsecpinghosts", $ipsecpinghosts);
256
			unset($ipsecpinghosts);
257
		}
258
		unset($iflist);
259

    
260
		$strongswan = <<<EOD
261

    
262
#Automatically generated please do not modify
263
starter {
264
    load_warning = no
265
}
266

    
267
charon {
268

    
269
        # number of worker threads in charon
270
        threads = 16
271

    
272
	# NOTE: Allows to send multiple subnets for IKEv1
273
	cisco_unity = yes
274

    
275
	# XXX: There is not much choice here really users win their security!
276
	i_dont_care_about_security_and_use_aggressive_mode_psk=yes
277

    
278
	# And two loggers using syslog. The subsections define the facility to log
279
	# to, currently one of: daemon, auth.
280
	syslog {
281

    
282
		identifier = charon
283
		# default level to the LOG_DAEMON facility
284
		daemon {
285
		}
286
		# very minimalistic IKE auditing logs to LOG_AUTHPRIV
287
		auth {
288
		    default = -1
289
		    ike = 1
290
		    ike_name = yes
291
		}
292
	}
293

    
294
EOD;
295

    
296
		if (is_array($a_client) && isset($a_client['enable']) && isset($a_client['net_list']))
297
			$strongswan .= "\tcisco_unity = yes\n";
298

    
299
		$strongswan .= "\tplugins {\n";
300

    
301
		if (is_array($a_client) && isset($a_client['enable'])) {
302
			$strongswan .= "\t\tattr {\n";
303
			if ($a_client['pool_address'] && $a_client['pool_netbits'])
304
				$strongswan .= "\t\tsubnet = {$a_client['pool_address']}/{$a_client['pool_netbits']}\n";
305

    
306
			$cfgservers = array();
307
			if (!empty($a_client['dns_server1']))
308
				$cfgservers[] = $a_client['dns_server1'];
309
			if (!empty($a_client['dns_server2']))
310
				$cfgservers[] = $a_client['dns_server2'];
311
			if (!empty($a_client['dns_server3']))
312
				$cfgservers[] = $a_client['dns_server3'];
313
			if (!empty($a_client['dns_server4']))
314
				$cfgservers[] = $a_client['dns_server4'];
315

    
316
			if (!empty($cfgservers))
317
				$strongswan .= "\t\tdns = " . implode(",", $cfgservers) . "\n";
318
			unset($cfgservers);
319
			$cfgservers = array();
320
			if (!empty($a_client['wins_server1']))
321
				$cfgservers[] = $a_client['wins_server1'];
322
			if (!empty($a_client['wins_server2']))
323
				$cfgservers[] = $a_client['wins_server2'];
324
			if (!empty($cfgservers))
325
				$strongswan .= "\t\tnbns = " . implode(",", $cfgservers) . "\n";
326
			unset($cfgservers);
327

    
328
			if (isset($a_client['net_list'])) {
329
				$net_list = '';
330
				foreach ($a_phase2 as $ph2ent) {
331
					if (isset($ph2ent['disabled']))
332
						continue;
333

    
334
					if (!isset($ph2ent['mobile']))
335
						continue;
336

    
337
					$localid = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
338

    
339
					if (!empty($net_list))
340
						$net_list .= ",";
341
					$net_list .= $localid;
342
				}
343

    
344
				if (!empty($net_list)) {
345
					$strongswan .= "\t\tsplit-include = {$net_list}\n";
346
					unset($net_list);
347
				}
348
			}
349

    
350
			if (!empty($a_client['dns_domain'])) {
351
				$strongswan .= "\t\t# Search domain and default domain\n";
352
				$strongswan .= "\t\t28674 = {$a_client['dns_domain']}\n";
353
				if (empty($a_client['dns_split']))
354
					$strongswan .= "\t\t28675 = {$a_client['dns_domain']}";
355
				$strongswan .= "\n";
356
			}
357

    
358
			if (!empty($a_client['dns_split'])) {
359
				$strongswan .= "\t\t28675 = {$a_client['dns_split']}\n";
360
			}
361

    
362
			if (!empty($a_client['login_banner']))
363
				$strongswan .= "\t\t28672 = {$a_client['login_banner']}\n";
364

    
365
			if (isset($a_client['save_passwd']))
366
				$strongswan .= "\t\t28673 = yes\n";
367

    
368
			if ($a_client['pfs_group'])
369
				$strongswan .= "\t\t28679 = {$a_client['pfs_group']}\n";
370
			$strongswan .= "\t\t}\n";
371

    
372
			if ($a_client['user_source'] != "none") {
373
				$strongswan .= "\txauth-generic {\n";
374
				$strongswan .= "\t\tscript = /etc/inc/ipsec.auth-user.php\n";
375
				$strongswan .= "\t\tauthcfg = ";
376
				$firstsed = 0;
377
				$authcfgs = explode(",", $a_client['user_source']);
378
				foreach ($authcfgs as $authcfg) {
379
					if ($firstsed > 0)
380
						$strongswan .= ",";
381
					if ($authcfg == "system")
382
						$authcfg = "Local Database";
383
					$strongswan .= $authcfg;
384
					$firstsed = 1;
385
				}
386
				$strongswan .= "\n";
387
				$strongswan .= "\t}\n";
388
			}
389
		}
390

    
391
		$strongswan .= "\t}\n}\n";
392
		@file_put_contents("{$g['varetc_path']}/ipsec/strongswan.conf", $strongswan);
393
		unset($strongswan);
394

    
395
		/* generate CA certificates files */
396
		if (is_array($config['ca']) && count($config['ca'])) {
397
			foreach ($config['ca'] as $ca) {
398
				if (!isset($ca['crt'])) {
399
					log_error(sprintf(gettext("Error: Invalid certificate info for %s"), $ca['descr']));
400
					continue;
401
				}
402
				$cert = base64_decode($ca['crt']);
403
				$x509cert = openssl_x509_parse(openssl_x509_read($cert));
404
				if (!is_array($x509cert) || !isset($x509cert['hash'])) {
405
					log_error(sprintf(gettext("Error: Invalid certificate hash info for %s"), $ca['descr']));
406
					continue;
407
				}
408
				$fname = "{$g['varetc_path']}/ipsec/ipsec.d/cacerts/{$x509cert['hash']}.0";
409
				if (!@file_put_contents($fname, $cert)) {
410
					log_error(sprintf(gettext("Error: Cannot write IPsec CA file for %s"), $ca['descr']));
411
					continue;
412
				}
413
				unset($cert);
414
			}
415
		}
416

    
417
		$pskconf = "";
418

    
419
		if (is_array($a_phase1) && count($a_phase1)) {
420
			foreach ($a_phase1 as $ph1ent) {
421

    
422
				if (isset($ph1ent['disabled']))
423
					continue;
424

    
425
				if (strstr($ph1ent['authentication_method'],'rsa')) {
426
					$certline = '';
427

    
428
					if (strstr($authmethod,'rsa')) {
429

    
430
						$cert = lookup_cert($ph1ent['certref']);
431

    
432
						if (!$cert) {
433
							log_error(sprintf(gettext("Error: Invalid phase1 certificate reference for %s"), $ph1ent['name']));
434
							continue;
435
						}
436

    
437
						chmod($certpath, 0600);
438

    
439
						$keyfile = "cert-{$ikeid}.key";
440
						$keypath = "{$g['varetc_path']}/ipsec/{$keyfile}";
441

    
442
						if (!file_put_contents($keypath, base64_decode($cert['prv']))) {
443
							log_error(sprintf(gettext("Error: Cannot write phase1 key file for %s"), $ph1ent['name']));
444
							continue;
445
						}
446

    
447
						chmod($keypath, 0600);
448
						/* XXX" Traffic selectors? */
449
						$pskconf .= " : RSA {$keypath}\n";
450

    
451
						$ca = lookup_ca($ph1ent['caref']);
452
						if ($ca) {
453
							$cafile = "ca-{$ikeid}.crt";
454
							$capath = "{$g['varetc_path']}/ipsec/ipsec.d/cacerts/{$cafile}";
455

    
456
							if (!file_put_contents($capath, base64_decode($ca['crt'])))
457
							{
458
								log_error(sprintf(gettext("Error: Cannot write phase1 CA certificate file for %s"), $ph1ent['name']));
459
								continue;
460
							}
461

    
462
							chmod($capath, 0600);
463
						}
464
					}
465
				} else {
466
					list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, "local");
467
					list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, "peer", $rgmap);
468

    
469
					if (empty($peerid_data))
470
						continue;
471

    
472
					$myid = isset($ph1ent['mobile']) ? trim($myid_data) . " " : "";
473
					$peerid = ($peerid_data != "allusers") ? trim($peerid_data) : "";
474
					if (!empty($ph1ent['pre-shared-key']))
475
						$pskconf .= $myid . $peerid . " : PSK \"" . trim($ph1ent['pre-shared-key']) . "\"\n";
476
				}
477
			}
478
		}
479

    
480
		/* Add user PSKs */
481
		if (is_array($config['system']) && is_array($config['system']['user'])) {
482
			foreach ($config['system']['user'] as $user) {
483
				if (!empty($user['ipsecpsk'])) {
484
					$pskconf .= "{$user['name']} : PSK \"{$user['ipsecpsk']}\"\n";
485
				}
486
			}
487
			unset($user);
488
		}
489

    
490
		/* add PSKs for mobile clients */
491
		if (is_array($ipseccfg['mobilekey'])) {
492
			foreach ($ipseccfg['mobilekey'] as $key) {
493
				if ($key['ident'] == "allusers")
494
					$key['ident'] = '';
495
				$pskconf .= "{$key['ident']} : PSK \"{$key['pre-shared-key']}\"\n";
496
			}
497
			unset($key);
498
		}
499

    
500
		@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.secrets", $pskconf);
501
		chmod("{$g['varetc_path']}/ipsec/ipsec.secrets", 0600);
502
		unset($pskconf);
503

    
504
		$natfilterrules = false;
505
		/* begin ipsec.conf */
506
		$ipsecconf = "";
507
		if (is_array($a_phase1) && count($a_phase1))  {
508

    
509
			$ipsecconf .= "# This file is automatically generated. Do not edit\n";
510
			$ipsecconf .= "config setup\n\tuniqueids = yes\n";
511
			$ipsecconf .= "\tcharondebug=\"" . vpn_ipsec_configure_loglevels(true) . "\"\n";
512

    
513
			foreach ($a_phase1 as $ph1ent) {
514
				if (isset($ph1ent['disabled']))
515
					continue;
516

    
517
				if ($ph1ent['mode'] == "aggressive")
518
					$aggressive = "yes";
519
				else
520
					$aggressive = "no";
521

    
522
				$ep = ipsec_get_phase1_src($ph1ent);
523
				if (!$ep)
524
					continue;
525

    
526
				$keyexchange = "ikev1";
527
				if (!empty($ph1ent['iketype']) && $ph1ent['iketype'] != "ikev1") {
528
					$keyexchange = "ikev2";
529
					$passive = "start";
530
				} else
531
					$passive = "route";
532

    
533
				if (isset($ph1ent['mobile'])) {
534
					$right_spec = "%any";
535
					$passive = 'add';
536
				} else
537
					$right_spec = $ph1ent['remote-gateway'];
538

    
539
				list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, "local");
540
				list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, "peer", $rgmap);
541

    
542
				/* Only specify peer ID if we are not dealing with a mobile PSK-only tunnel */
543
				$peerid_spec = '';
544
				if (!isset($ph1ent['mobile']))
545
					$peerid_spec = $peerid_data;
546

    
547
				if (is_array($ph1ent['encryption-algorithm']) && !empty($ph1ent['encryption-algorithm']['name']) && !empty($ph1ent['hash-algorithm'])) {
548
					$ealgosp1 = '';
549
					$ealg_id = $ph1ent['encryption-algorithm']['name'];
550
					$ealg_kl = $ph1ent['encryption-algorithm']['keylen'];
551
					if ($ealg_kl)
552
						$ealgosp1 = "ike = {$ealg_id}{$ealg_kl}-{$ph1ent['hash-algorithm']}";
553
					else
554
						$ealgosp1 = "ike = {$ealg_id}-{$ph1ent['hash-algorithm']}";
555

    
556
					$modp = vpn_ipsec_convert_to_modp($ph1ent['dhgroup']);
557
					if (!empty($modp))
558
						$ealgosp1 .= "-{$modp}";
559

    
560
					if ($keyexchange == "ikev1")
561
						$ealgosp1 .= "!";
562
				}
563

    
564
				if ($ph1ent['dpd_delay'] && $ph1ent['dpd_maxfail']) {
565
					if ($passive == "route")
566
						$dpdline = "dpdaction = restart";
567
					else
568
						$dpdline = "dpdaction = clear";
569
					$dpdline .= "\n\tdpddelay = {$ph1ent['dpd_delay']}s";
570
					$dpdtimeout = $ph1ent['dpd_delay'] * ($ph1ent['dpd_maxfail'] + 1);
571
					$dpdline .= "\n\tdpdtimeout = {$dpdtimeout}s";
572
				} else
573
					$dpdline = "dpdaction = none";
574

    
575
				$ikelifeline = '';
576
				if ($ph1ent['lifetime'])
577
					$ikelifeline = "ikelifetime = {$ph1ent['lifetime']}s";
578

    
579
				$authentication = "";
580
				switch ($ph1ent['authentication_method']) {
581
				case 'xauth_rsa_server':
582
					$authentication = "leftauth = pubkey\n\trightauth = pubkey";
583
					$authentication .= "\n\trightauth2 = xauth-generic";
584
					break;
585
				case 'xauth_psk_server':
586
					$authentication = "leftauth = psk\n\trightauth = psk";
587
					$authentication .= "\n\trightauth2 = xauth-generic";
588
					break;
589
				case 'pre_shared_key':
590
					$authentication = "leftauth = psk\n\trightauth = psk";
591
					break;
592
				case 'rsasig':
593
					$authentication = "leftauth = pubkey\n\trightauth = pubkey";
594
					break;
595
				case 'hybrid_rsa_server':
596
					$authentication = "leftauth = xauth-generic\n\trightauth = pubkey";
597
					$authentication .= "\n\trightauth2 = xauth";
598
					break;
599
				}
600

    
601
				$left_spec = $ep;
602

    
603
				$ipseclifetime = 0;
604
				$rightsubnet_spec = array();
605
				$leftsubnet_spec = array();
606
				$ealgoAHsp2arr = array();
607
				$ealgoESPsp2arr = array();
608
			if (is_array($a_phase2) && count($a_phase2)) {
609
				foreach ($a_phase2 as $ph2ent) {
610
					$ikeid = $ph2ent['ikeid'];
611
					if ($ikeid != $ph1ent['ikeid'])
612
						continue;
613

    
614
					if (isset($ph2ent['disabled']))
615
						continue;
616

    
617
					if (isset($ph2ent['mobile']) && !isset($a_client['enable']))
618
						continue;
619

    
620
					if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
621
						$tunneltype = "type = tunnel";
622

    
623
						$localid_type = $ph2ent['localid']['type'];
624
						$leftsubnet_data = ipsec_idinfo_to_cidr($ph2ent['localid'], false, $ph2ent['mode']);
625
						/* Do not print localid in some cases, such as a pure-psk or psk/xauth single phase2 mobile tunnel */
626
						if (($localid_type == "none" || $localid_type == "mobile")
627
						    && isset($ph1ent['mobile']) && (ipsec_get_number_of_phase2($ikeid)==1)) {
628
							$left_spec = '%any';
629
						} else {
630
							if ($localid_type != "address") {
631
								$localid_type = "subnet";
632
							}
633
							// Don't let an empty subnet into config, it can cause parse errors. Ticket #2201.
634
							if (!is_ipaddr($leftsubnet_data) && !is_subnet($leftsubnet_data) && ($leftsubnet_data != "0.0.0.0/0")) {
635
								log_error("Invalid IPsec Phase 2 \"{$ph2ent['descr']}\" - {$ph2ent['localid']['type']} has no subnet.");
636
								continue;
637
							}
638
							if (!empty($ph2ent['natlocalid'])) {
639
								$natleftsubnet_data =  ipsec_idinfo_to_cidr($ph2ent['natlocalid'], false, $ph2ent['mode']);
640
								if ($ph2ent['natlocalid']['type'] != "address") {
641
									if (is_subnet($natleftsubnet_data))
642
										$leftsubnet_data = "{$natleftsubnet_data}|{$leftsubnet_data}";
643
								} else {
644
									if (is_ipaddr($natleftsubnet_data))
645
										$leftsubnet_data = "{$natleftsubnet_data}|{$leftsubnet_data}";
646
								}
647
								$natfilterrules = true;
648
							}
649
						}
650

    
651
						$leftsubnet_spec[] = $leftsubnet_data;
652

    
653
						if (!isset($ph2ent['mobile'])) {
654
							$rightsubnet_spec[] = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']);
655
						} else if (!empty($a_client['pool_address']))
656
							$rightsubnet_spec[] = "{$a_client['pool_address']}/{$a_client['pool_netbits']}";
657
					} else {
658
						$tunneltype = "type = transport";
659

    
660
						if ((($ph1ent['authentication_method'] == "xauth_psk_server") ||
661
						    ($ph1ent['authentication_method'] == "pre_shared_key")) && isset($ph1ent['mobile'])) {
662
							$left_spec = "%any";
663
						} else {
664
							$leftsubnet_spec[] = ipsec_get_phase1_src($ph1ent);
665
						}
666

    
667
						if (!isset($ph2ent['mobile']))
668
							$rightsubnet_spec[] = $right_spec;
669
					}
670

    
671
					if (isset($a_client['pfs_group']))
672
						$ph2ent['pfsgroup'] = $a_client['pfs_group'];
673

    
674
					if ($ph2ent['protocol'] == 'esp') {
675
						if (is_array($ph2ent['encryption-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
676
							foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
677
								$ealg_id = $ealg['name'];
678
								$ealg_kl = $ealg['keylen'];
679

    
680
								if (!empty($ealg_kl) && $ealg_kl == "auto") {
681
									if (empty($p2_ealgos) || !is_array($p2_ealgos))
682
										require("ipsec.inc");
683
									$key_hi = $p2_ealgos[$ealg_id]['keysel']['hi'];
684
									$key_lo = $p2_ealgos[$ealg_id]['keysel']['lo'];
685
									$key_step = $p2_ealgos[$ealg_id]['keysel']['step'];
686
									/* XXX: in some cases where include ordering is suspect these variables
687
									 * are somehow 0 and we enter this loop forever and timeout after 900
688
									 * seconds wrecking bootup */
689
									if ($key_hi != 0 and $key_lo !=0 and $key_step !=0) {
690
										for ($keylen = $key_hi; $keylen >= $key_lo; $keylen -= $key_step) {
691
											foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
692
												$halgo = str_replace('hmac_', '', $halgo);
693
												$tmpealgo = "{$ealg_id}{$keylen}-{$halgo}";
694
												$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
695
												if (!empty($modp))
696
													$tmpealgo .= "-{$modp}";
697
												$ealgoESPsp2arr[] = $tmpealgo;
698
											}
699
										}
700
									}
701
								} else {
702
									foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
703
										$halgo = str_replace('hmac_', '', $halgo);
704
										$tmpealgo = "{$ealg_id}{$ealg_kl}-{$halgo}";
705
										$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
706
										if (!empty($modp))
707
											$tmpealgo .= "-{$modp}";
708
										$ealgoESPsp2arr[] = $tmpealgo;
709
									}
710
								}
711
							}
712
						}
713
					} else if ($ph2ent['protocol'] == 'ah') {
714
						if (is_array($ph2ent['hash-algorithm-option'])) {
715
							$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
716
							foreach ($ph2ent['hash-algorithm-option'] as $tmpAHalgo) {
717
								$tmpAHalgo = str_replace('hmac_', '', $tmpAHalgo);
718
								if (!empty($modp))
719
									$tmpAHalgo = "-{$modp}";
720
								$ealgoAHsp2arr[] = $tmpAHalgo;
721
							}
722
						}
723
					}
724

    
725

    
726
					if (!empty($ph2ent['lifetime'])) {
727
						if ($ipseclifetime == 0 || intval($ipseclifetime) > intval($ph2ent['lifetime']))
728
							$ipseclifetime = intval($ph2ent['lifetime']);
729
					}
730
				}
731
			}
732

    
733
				$ipsecconf .=<<<EOD
734

    
735
conn con{$ph1ent['ikeid']}
736
	aggressive = {$aggressive}
737
	fragmentation = yes
738
	keyexchange = {$keyexchange}
739
	reauth = yes
740
	rekey = yes
741
	reqid = {$ikeid}
742
	installpolicy = yes
743
	{$tunneltype}
744
	{$dpdline}
745
	auto = {$passive}
746
	left = {$left_spec}
747
	right = {$right_spec}
748
	leftid = {$myid_data}
749

    
750
EOD;
751

    
752
				if (!empty($ikelifeline))
753
					$ipsecconf .= "\t{$ikelifeline}\n";
754
				if ($ipseclifetime > 0)
755
					$ipsecconf .= "\tlifetime = {$ipseclifetime}s\n";
756
				if (!empty($rightsubnet_spec))
757
					$ipsecconf .= "\trightsubnet = " . join(",", $rightsubnet_spec) . "\n";
758
				if (!empty($leftsubnet_spec))
759
					$ipsecconf .= "\tleftsubnet = " . join(",", $leftsubnet_spec) . "\n";
760
				if (!empty($ealgosp1))
761
					$ipsecconf .= "\t{$ealgosp1}\n";
762
				if (!empty($ealgoAHsp2arr))
763
					$ipsecconf .= "\tah = " . join(',', $ealgoAHsp2arr) . "!\n";
764
				if (!empty($ealgoESPsp2arr))
765
					$ipsecconf .= "\tesp = " . join(',', $ealgoESPsp2arr) . "!\n";
766
				if (!empty($authentication))
767
					$ipsecconf .= "\t{$authentication}\n";
768
				if (!empty($peerid_spec))
769
					$ipsecconf .= "\trightid = {$peerid_spec}\n";
770
			}
771
		}
772
	}
773
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.conf", $ipsecconf);
774
	unset($ipsecconf);
775
	/* end ipsec.conf */
776

    
777
	/* mange process */
778
	if (isvalidpid("{$g['varrun_path']}/charon.pid")) {
779
		/* Read secrets */
780
		mwexec("/usr/local/sbin/ipsec rereadall", false);
781
		/* Update configuration changes */
782
		mwexec("/usr/local/sbin/ipsec reload", false);
783
	} else {
784
		mwexec("/usr/local/sbin/ipsec start", false); 
785
	}
786

    
787
	if ($natfilterrules == true)
788
		filter_configure();
789
	/* start filterdns, if necessary */
790
	if (count($filterdns_list) > 0) {
791
		$interval = 60;
792
		if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval']))
793
			$interval = $ipseccfg['dns-interval'];
794

    
795
		$hostnames = "";
796
		array_unique($filterdns_list);
797
		foreach ($filterdns_list as $hostname)
798
			$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload ipsecdns\"'\n";
799
		file_put_contents("{$g['varetc_path']}/ipsec/filterdns-ipsec.hosts", $hostnames);
800
		unset($hostnames);
801

    
802
		if (isvalidpid("{$g['varrun_path']}/filterdns-ipsec.pid"))
803
			sigkillbypid("{$g['varrun_path']}/filterdns-ipsec.pid", "HUP");
804
		else {
805
			mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/ipsec/filterdns-ipsec.hosts -d 1");
806
		}
807
	} else {
808
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
809
		@unlink("{$g['varrun_path']}/filterdns-ipsec.pid");
810
	}
811

    
812
	if ($g['booting'])
813
		echo "done\n";
814

    
815
	return count($filterdns_list);
816
}
817

    
818
/*
819
 * Forcefully restart IPsec
820
 * This is required for when dynamic interfaces reload
821
 * For all other occasions the normal vpn_ipsec_configure()
822
 * will gracefully reload the settings without restarting
823
 */
824
function vpn_ipsec_force_reload($interface = "") {
825
	global $g, $config;
826

    
827
	$ipseccfg = $config['ipsec'];
828

    
829
	if (!empty($interface) && is_array($ipseccfg['phase1'])) {
830
		$found = false;
831
		foreach ($ipseccfg['phase1'] as $ipsec) {
832
			if (!isset($ipsec['disabled']) && ($ipsec['interface'] == $interface)) {
833
				$found = true;
834
				break;
835
			}
836
		}
837
		if (!$found) {
838
			log_error(sprintf(gettext("Ignoring IPsec reload since there are no tunnels on interface %s"), $interface));
839
			return;
840
		}
841
	}
842

    
843
	/* if ipsec is enabled, start up again */
844
	if (isset($ipseccfg['enable'])) {
845
		log_error(gettext("Forcefully reloading IPsec"));
846
		vpn_ipsec_configure();
847
	}
848
}
849

    
850
/* master setup for vpn (mpd) */
851
function vpn_setup() {
852
	global $g;
853

    
854
	if ($g['platform'] == 'jail')
855
		return;
856

    
857
	/* start pptpd */
858
	vpn_pptpd_configure();
859

    
860
	/* start pppoe server */
861
	vpn_pppoes_configure();
862

    
863
	/* setup l2tp */
864
	vpn_l2tp_configure();
865
}
866

    
867
function vpn_netgraph_support() {
868
	$iflist = get_configured_interface_list();
869
	foreach ($iflist as $iface) {
870
		$realif = get_real_interface($iface);
871
		/* Get support for netgraph(4) from the nic */
872
		$ifinfo = pfSense_get_interface_addresses($realif);
873
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge")))
874
			pfSense_ngctl_attach(".", $realif);
875
	}
876
}
877

    
878
function vpn_pptpd_configure() {
879
	global $config, $g;
880

    
881
	$syscfg = $config['system'];
882
	$pptpdcfg = $config['pptpd'];
883

    
884
	if ($g['booting']) {
885
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
886
			return 0;
887

    
888
		echo gettext("Configuring PPTP VPN service... ");
889
	} else {
890
		/* kill mpd */
891
		killbypid("{$g['varrun_path']}/pptp-vpn.pid");
892

    
893
		/* wait for process to die */
894
		sleep(3);
895

    
896
		if (is_process_running("mpd -b")) {
897
			killbypid("{$g['varrun_path']}/pptp-vpn.pid");
898
			log_error(gettext("Could not kill mpd within 3 seconds.   Trying again."));
899
		}
900

    
901
		/* remove mpd.conf, if it exists */
902
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.conf");
903
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.links");
904
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.secret");
905
	}
906

    
907
	if (empty($pptpdcfg['n_pptp_units'])) {
908
		log_error("Something wrong in the PPTPd configuration. Preventing starting the daemon because issues would arise.");
909
		return;
910
	}
911

    
912
	/* make sure pptp-vpn directory exists */
913
	if (!file_exists("{$g['varetc_path']}/pptp-vpn"))
914
		mkdir("{$g['varetc_path']}/pptp-vpn");
915

    
916
	switch ($pptpdcfg['mode']) {
917
		case 'server' :
918
			/* write mpd.conf */
919
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.conf", "w");
920
			if (!$fd) {
921
				printf(gettext("Error: cannot open mpd.conf in vpn_pptpd_configure().") . "\n");
922
				return 1;
923
			}
924

    
925
			$mpdconf = <<<EOD
926
pptps:
927

    
928
EOD;
929

    
930
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
931
				$mpdconf .= "	load pt{$i}\n";
932
			}
933

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

    
936
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
937

    
938
				$mpdconf .= <<<EOD
939

    
940
pt{$i}:
941
	new -i pptpd{$i} pt{$i} pt{$i}
942
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
943
	load pts
944

    
945
EOD;
946
			}
947

    
948
			$mpdconf .=<<<EOD
949

    
950
pts:
951
	set iface disable on-demand
952
	set iface enable proxy-arp
953
	set iface enable tcpmssfix
954
	set iface idle 1800
955
	set iface up-script /usr/local/sbin/vpn-linkup
956
	set iface down-script /usr/local/sbin/vpn-linkdown
957
	set bundle enable multilink
958
	set bundle enable crypt-reqd
959
	set link yes acfcomp protocomp
960
	set link no pap chap
961
	set link enable chap-msv2
962
	set link mtu 1460
963
	set link keep-alive 10 60
964
	set ipcp yes vjcomp
965
	set bundle enable compression
966
	set ccp yes mppc
967
	set ccp yes mpp-e128
968
	set ccp yes mpp-stateless
969

    
970
EOD;
971

    
972
			if (!isset ($pptpdcfg['req128'])) {
973
				$mpdconf .=<<<EOD
974
	set ccp yes mpp-e40
975
	set ccp yes mpp-e56
976

    
977
EOD;
978
			}
979

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

    
983
			if (!empty($pptpdcfg['dns1'])) {
984
				$mpdconf .= "	set ipcp dns " . $pptpdcfg['dns1'];
985
				if (!empty($pptpdcfg['dns2']))
986
					$mpdconf .= " " . $pptpdcfg['dns2'];
987
				$mpdconf .= "\n";
988
			} elseif (isset ($config['dnsmasq']['enable'])) {
989
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
990
				if ($syscfg['dnsserver'][0])
991
					$mpdconf .= " " . $syscfg['dnsserver'][0];
992
				$mpdconf .= "\n";
993
			} elseif (isset($config['unbound']['enable'])) {
994
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
995
				if ($syscfg['dnsserver'][0])
996
					$mpdconf .= " " . $syscfg['dnsserver'][0];
997
				$mpdconf .= "\n";
998
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
999
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1000
			}
1001

    
1002
			if (isset ($pptpdcfg['radius']['server']['enable'])) {
1003
				$authport = (isset($pptpdcfg['radius']['server']['port']) && strlen($pptpdcfg['radius']['server']['port']) > 1) ? $pptpdcfg['radius']['server']['port'] : 1812;
1004
				$acctport = $authport + 1;
1005
				$mpdconf .=<<<EOD
1006
	set radius server {$pptpdcfg['radius']['server']['ip']} "{$pptpdcfg['radius']['server']['secret']}" {$authport} {$acctport}
1007

    
1008
EOD;
1009
			if (isset ($pptpdcfg['radius']['server2']['enable'])) {
1010
				$authport = (isset($pptpdcfg['radius']['server2']['port']) && strlen($pptpdcfg['radius']['server2']['port']) > 1) ? $pptpdcfg['radius']['server2']['port'] : 1812;
1011
				$acctport = $authport + 1;
1012
				$mpdconf .=<<<EOD
1013
	set radius server {$pptpdcfg['radius']['server2']['ip']} "{$pptpdcfg['radius']['server2']['secret2']}" {$authport} {$acctport}
1014

    
1015
EOD;
1016
			}
1017
			$mpdconf .=<<<EOD
1018
	set radius retries 3
1019
	set radius timeout 10
1020
	set auth enable radius-auth
1021

    
1022
EOD;
1023

    
1024
				if (isset ($pptpdcfg['radius']['accounting'])) {
1025
					$mpdconf .=<<<EOD
1026
	set auth enable radius-acct
1027
	set radius acct-update 300
1028

    
1029
EOD;
1030
				}
1031
			}
1032

    
1033
			fwrite($fd, $mpdconf);
1034
			fclose($fd);
1035
			unset($mpdconf);
1036

    
1037
			/* write mpd.links */
1038
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.links", "w");
1039
			if (!$fd) {
1040
				printf(gettext("Error: cannot open mpd.links in vpn_pptpd_configure().") . "\n");
1041
				return 1;
1042
			}
1043

    
1044
			$mpdlinks = "";
1045

    
1046
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1047
				$mpdlinks .=<<<EOD
1048

    
1049
pt{$i}:
1050
	set link type pptp
1051
	set pptp enable incoming
1052
	set pptp disable originate
1053
	set pptp disable windowing
1054

    
1055
EOD;
1056
			}
1057

    
1058
			fwrite($fd, $mpdlinks);
1059
			fclose($fd);
1060
			unset($mpdlinks);
1061

    
1062
			/* write mpd.secret */
1063
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.secret", "w");
1064
			if (!$fd) {
1065
				printf(gettext("Error: cannot open mpd.secret in vpn_pptpd_configure().") . "\n");
1066
				return 1;
1067
			}
1068

    
1069
			$mpdsecret = "";
1070

    
1071
			if (is_array($pptpdcfg['user'])) {
1072
				foreach ($pptpdcfg['user'] as $user) {
1073
					$pass = str_replace('\\', '\\\\', $user['password']);
1074
					$pass = str_replace('"', '\"', $pass);
1075
					$mpdsecret .= "{$user['name']} \"{$pass}\" {$user['ip']}\n";
1076
				}
1077
			}
1078

    
1079
			fwrite($fd, $mpdsecret);
1080
			fclose($fd);
1081
			unset($mpdsecret);
1082
			chmod("{$g['varetc_path']}/pptp-vpn/mpd.secret", 0600);
1083

    
1084
			vpn_netgraph_support();
1085

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

    
1089
			break;
1090

    
1091
		case 'redir' :
1092
			break;
1093
	}
1094

    
1095
	if ($g['booting'])
1096
		echo "done\n";
1097

    
1098
	return 0;
1099
}
1100

    
1101
function vpn_pppoes_configure() {
1102
	global $config;
1103

    
1104
	if (is_array($config['pppoes']['pppoe'])) {
1105
		foreach ($config['pppoes']['pppoe'] as $pppoe)
1106
			vpn_pppoe_configure($pppoe);
1107
	}
1108
}
1109

    
1110
function vpn_pppoe_configure(&$pppoecfg) {
1111
	global $config, $g;
1112

    
1113
	$syscfg = $config['system'];
1114

    
1115
	/* create directory if it does not exist */
1116
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn"))
1117
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1118

    
1119
	if ($g['booting']) {
1120
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
1121
			return 0;
1122

    
1123
		echo gettext("Configuring PPPoE VPN service... ");
1124
	} else {
1125
		/* kill mpd */
1126
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1127

    
1128
		/* wait for process to die */
1129
		sleep(2);
1130

    
1131
	}
1132

    
1133
	switch ($pppoecfg['mode']) {
1134

    
1135
		case 'server' :
1136

    
1137
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1138

    
1139
			if ($pppoecfg['paporchap'] == "chap")
1140
				$paporchap = "set link enable chap";
1141
			else
1142
				$paporchap = "set link enable pap";
1143

    
1144
			/* write mpd.conf */
1145
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1146
			if (!$fd) {
1147
				printf(gettext("Error: cannot open mpd.conf in vpn_pppoe_configure().") . "\n");
1148
				return 1;
1149
			}
1150
			$mpdconf = "\n\n";
1151
			$mpdconf .= "poes:\n";
1152

    
1153
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1154
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1155
			}
1156

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

    
1159
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1160

    
1161
				if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1162
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1163
				} else {
1164
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1165
				}
1166

    
1167
				$mpdconf .=<<<EOD
1168

    
1169
poes{$pppoecfg['pppoeid']}{$i}:
1170
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1171
	{$isssue_ip_type}
1172
	load pppoe_standard
1173

    
1174
EOD;
1175
			}
1176

    
1177
			$mpdconf .=<<<EOD
1178

    
1179
pppoe_standard:
1180
	set bundle no multilink
1181
	set bundle enable compression
1182
	set auth max-logins 1
1183
	set iface up-script /usr/local/sbin/vpn-linkup
1184
	set iface down-script /usr/local/sbin/vpn-linkdown
1185
	set iface idle 0
1186
	set iface disable on-demand
1187
	set iface disable proxy-arp
1188
	set iface enable tcpmssfix
1189
	set iface mtu 1500
1190
	set link no pap chap
1191
	{$paporchap}
1192
	set link keep-alive 60 180
1193
	set ipcp yes vjcomp
1194
	set ipcp no vjcomp
1195
	set link max-redial -1
1196
	set link mtu 1492
1197
	set link mru 1492
1198
	set ccp yes mpp-e40
1199
	set ccp yes mpp-e128
1200
	set ccp yes mpp-stateless
1201
	set link latency 1
1202
	#set ipcp dns 10.10.1.3
1203
	#set bundle accept encryption
1204

    
1205
EOD;
1206

    
1207
			if (!empty($pppoecfg['dns1'])) {
1208
				$mpdconf .= "	set ipcp dns " . $pppoecfg['dns1'];
1209
				if (!empty($pppoecfg['dns2']))
1210
					$mpdconf .= " " . $pppoecfg['dns2'];
1211
				$mpdconf .= "\n";
1212
			} elseif (isset ($config['dnsmasq']['enable'])) {
1213
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1214
				if ($syscfg['dnsserver'][0])
1215
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1216
				$mpdconf .= "\n";
1217
			} elseif (isset ($config['unbound']['enable'])) {
1218
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1219
				if ($syscfg['dnsserver'][0])
1220
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1221
				$mpdconf .= "\n";
1222
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1223
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1224
			}
1225

    
1226
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1227
				$radiusport = "";
1228
				$radiusacctport = "";
1229
				if (isset($pppoecfg['radius']['server']['port']))
1230
					$radiusport = $pppoecfg['radius']['server']['port'];
1231
				if (isset($pppoecfg['radius']['server']['acctport']))
1232
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1233
				$mpdconf .=<<<EOD
1234
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
1235
	set radius retries 3
1236
	set radius timeout 10
1237
	set auth enable radius-auth
1238

    
1239
EOD;
1240

    
1241
				if (isset ($pppoecfg['radius']['accounting'])) {
1242
					$mpdconf .=<<<EOD
1243
	set auth enable radius-acct
1244

    
1245
EOD;
1246
				}
1247
			}
1248

    
1249
			fwrite($fd, $mpdconf);
1250
			fclose($fd);
1251
			unset($mpdconf);
1252

    
1253
			/* write mpd.links */
1254
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.links", "w");
1255
			if (!$fd) {
1256
				printf(gettext("Error: cannot open mpd.links in vpn_pppoe_configure().") . "\n");
1257
				return 1;
1258
			}
1259

    
1260
			$mpdlinks = "";
1261

    
1262
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1263
				$mpdlinks .=<<<EOD
1264

    
1265
poes{$pppoecfg['pppoeid']}{$i}:
1266
	set phys type pppoe
1267
	set pppoe iface {$pppoe_interface}
1268
	set pppoe service "*"
1269
	set pppoe disable originate
1270
	set pppoe enable incoming
1271

    
1272
EOD;
1273
			}
1274

    
1275
			fwrite($fd, $mpdlinks);
1276
			fclose($fd);
1277
			unset($mpdlinks);
1278

    
1279
			if ($pppoecfg['username']) {
1280
				/* write mpd.secret */
1281
				$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
1282
				if (!$fd) {
1283
					printf(gettext("Error: cannot open mpd.secret in vpn_pppoe_configure().") . "\n");
1284
					return 1;
1285
				}
1286

    
1287
				$mpdsecret = "\n\n";
1288

    
1289
				if (!empty($pppoecfg['username'])) {
1290
					$item = explode(" ", $pppoecfg['username']);
1291
					foreach($item as $userdata) {
1292
						$data = explode(":", $userdata);
1293
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1294
					}
1295
				}
1296

    
1297
				fwrite($fd, $mpdsecret);
1298
				fclose($fd);
1299
				unset($mpdsecret);
1300
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1301
			}
1302

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

    
1307
			/* Get support for netgraph(4) from the nic */
1308
			pfSense_ngctl_attach(".", $pppoe_interface);
1309
			/* fire up mpd */
1310
			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");
1311

    
1312
			break;
1313
	}
1314

    
1315
	if ($g['booting'])
1316
		echo gettext("done") . "\n";
1317

    
1318
	return 0;
1319
}
1320

    
1321
function vpn_l2tp_configure() {
1322
	global $config, $g;
1323

    
1324
	$syscfg = $config['system'];
1325
	$l2tpcfg = $config['l2tp'];
1326

    
1327
	/* create directory if it does not exist */
1328
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn"))
1329
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1330

    
1331
	if ($g['booting']) {
1332
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off"))
1333
			return 0;
1334

    
1335
		echo gettext("Configuring l2tp VPN service... ");
1336
	} else {
1337
		/* kill mpd */
1338
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1339

    
1340
		/* wait for process to die */
1341
		sleep(8);
1342

    
1343
	}
1344

    
1345
	/* make sure l2tp-vpn directory exists */
1346
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn"))
1347
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1348

    
1349
	switch ($l2tpcfg['mode']) {
1350

    
1351
		case 'server' :
1352
			if ($l2tpcfg['paporchap'] == "chap")
1353
				$paporchap = "set link enable chap";
1354
			else
1355
				$paporchap = "set link enable pap";
1356

    
1357
			/* write mpd.conf */
1358
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1359
			if (!$fd) {
1360
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
1361
				return 1;
1362
			}
1363
			$mpdconf = "\n\n";
1364
			$mpdconf .=<<<EOD
1365
l2tps:
1366

    
1367
EOD;
1368

    
1369
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1370
				$mpdconf .= "	load l2tp{$i}\n";
1371
			}
1372

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

    
1375
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1376

    
1377
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1378
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1379
				} else {
1380
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1381
				}
1382

    
1383
				$mpdconf .=<<<EOD
1384

    
1385
l2tp{$i}:
1386
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1387
	{$isssue_ip_type}
1388
	load l2tp_standard
1389

    
1390
EOD;
1391
			}
1392

    
1393
			$mpdconf .=<<<EOD
1394

    
1395
l2tp_standard:
1396
	set bundle disable multilink
1397
	set bundle enable compression
1398
	set bundle yes crypt-reqd
1399
	set ipcp yes vjcomp
1400
	# set ipcp ranges 131.188.69.161/32 131.188.69.170/28
1401
	set ccp yes mppc
1402
	set iface disable on-demand
1403
	set iface enable proxy-arp
1404
	set iface up-script /usr/local/sbin/vpn-linkup
1405
	set iface down-script /usr/local/sbin/vpn-linkdown
1406
	set link yes acfcomp protocomp
1407
	set link no pap chap
1408
	set link enable chap
1409
	set link keep-alive 10 180
1410

    
1411
EOD;
1412

    
1413
			if (is_ipaddr($l2tpcfg['wins'])) {
1414
				$mpdconf .= "	set ipcp nbns {$l2tpcfg['wins']}\n";
1415
			}
1416
			if (is_ipaddr($l2tpcfg['dns1'])) {
1417
				$mpdconf .= "	set ipcp dns " . $l2tpcfg['dns1'];
1418
				if (is_ipaddr($l2tpcfg['dns2']))
1419
					$mpdconf .= " " . $l2tpcfg['dns2'];
1420
				$mpdconf .= "\n";
1421
			} elseif (isset ($config['dnsmasq']['enable'])) {
1422
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1423
				if ($syscfg['dnsserver'][0])
1424
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1425
				$mpdconf .= "\n";
1426
			} elseif (isset ($config['unbound']['enable'])) {
1427
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1428
				if ($syscfg['dnsserver'][0])
1429
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1430
				$mpdconf .= "\n";
1431
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1432
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1433
			}
1434

    
1435
			if (isset ($l2tpcfg['radius']['enable'])) {
1436
				$mpdconf .=<<<EOD
1437
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1438
	set radius retries 3
1439
	set radius timeout 10
1440
	set auth enable radius-auth
1441

    
1442
EOD;
1443

    
1444
				if (isset ($l2tpcfg['radius']['accounting'])) {
1445
					$mpdconf .=<<<EOD
1446
	set auth enable radius-acct
1447

    
1448
EOD;
1449
				}
1450
			}
1451

    
1452
			fwrite($fd, $mpdconf);
1453
			fclose($fd);
1454
			unset($mpdconf);
1455

    
1456
			/* write mpd.links */
1457
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.links", "w");
1458
			if (!$fd) {
1459
				printf(gettext("Error: cannot open mpd.links in vpn_l2tp_configure().") . "\n");
1460
				return 1;
1461
			}
1462

    
1463
			$mpdlinks = "";
1464

    
1465
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1466
				$mpdlinks .=<<<EOD
1467

    
1468
l2tp{$i}:
1469
	set link type l2tp
1470
	set l2tp enable incoming
1471
	set l2tp disable originate
1472

    
1473
EOD;
1474
			if (!empty($l2tpcfg['secret']))
1475
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
1476
			}
1477

    
1478
			fwrite($fd, $mpdlinks);
1479
			fclose($fd);
1480
			unset($mpdlinks);
1481

    
1482
			/* write mpd.secret */
1483
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.secret", "w");
1484
			if (!$fd) {
1485
				printf(gettext("Error: cannot open mpd.secret in vpn_l2tp_configure().") . "\n");
1486
				return 1;
1487
			}
1488

    
1489
			$mpdsecret = "\n\n";
1490

    
1491
			if (is_array($l2tpcfg['user'])) {
1492
				foreach ($l2tpcfg['user'] as $user)
1493
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1494
			}
1495

    
1496
			fwrite($fd, $mpdsecret);
1497
			fclose($fd);
1498
			unset($mpdsecret);
1499
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
1500

    
1501
			vpn_netgraph_support();
1502

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

    
1506
			break;
1507

    
1508
		case 'redir' :
1509
			break;
1510
	}
1511

    
1512
	if ($g['booting'])
1513
		echo "done\n";
1514

    
1515
	return 0;
1516
}
1517

    
1518
function vpn_ipsec_configure_preferoldsa() {
1519
	global $config;
1520
	if(isset($config['ipsec']['preferoldsa']))
1521
		set_single_sysctl("net.key.preferred_oldsa", "-30");
1522
	else
1523
		set_single_sysctl("net.key.preferred_oldsa", "0");
1524
}
1525

    
1526
?>
(59-59/68)