Projet

Général

Profil

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

univnautes / etc / inc / vpn.inc @ 0b5fc1d1

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 == "start")
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
	keyingtries = %forever
740
	reauth = yes
741
	rekey = yes
742
	reqid = {$ikeid}
743
	installpolicy = yes
744
	{$tunneltype}
745
	{$dpdline}
746
	auto = {$passive}
747
	left = {$left_spec}
748
	right = {$right_spec}
749
	leftid = {$myid_data}
750

    
751
EOD;
752

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

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

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

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

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

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

    
816
	return count($filterdns_list);
817
}
818

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
929
EOD;
930

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

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

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

    
939
				$mpdconf .= <<<EOD
940

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

    
946
EOD;
947
			}
948

    
949
			$mpdconf .=<<<EOD
950

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

    
971
EOD;
972

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

    
978
EOD;
979
			}
980

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

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

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

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

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

    
1023
EOD;
1024

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

    
1030
EOD;
1031
				}
1032
			}
1033

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

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

    
1045
			$mpdlinks = "";
1046

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

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

    
1056
EOD;
1057
			}
1058

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

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

    
1070
			$mpdsecret = "";
1071

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

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

    
1085
			vpn_netgraph_support();
1086

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

    
1090
			break;
1091

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

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

    
1099
	return 0;
1100
}
1101

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

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

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

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

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

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

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

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

    
1132
	}
1133

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

    
1136
		case 'server' :
1137

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

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

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

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

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

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

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

    
1168
				$mpdconf .=<<<EOD
1169

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

    
1175
EOD;
1176
			}
1177

    
1178
			$mpdconf .=<<<EOD
1179

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

    
1206
EOD;
1207

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

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

    
1240
EOD;
1241

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

    
1246
EOD;
1247
				}
1248
			}
1249

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

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

    
1261
			$mpdlinks = "";
1262

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

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

    
1273
EOD;
1274
			}
1275

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

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

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

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

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

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

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

    
1313
			break;
1314
	}
1315

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

    
1319
	return 0;
1320
}
1321

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

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

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

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

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

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

    
1344
	}
1345

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

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

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

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

    
1368
EOD;
1369

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

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

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

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

    
1384
				$mpdconf .=<<<EOD
1385

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

    
1391
EOD;
1392
			}
1393

    
1394
			$mpdconf .=<<<EOD
1395

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

    
1412
EOD;
1413

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

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

    
1443
EOD;
1444

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

    
1449
EOD;
1450
				}
1451
			}
1452

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

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

    
1464
			$mpdlinks = "";
1465

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

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

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

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

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

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

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

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

    
1502
			vpn_netgraph_support();
1503

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

    
1507
			break;
1508

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

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

    
1516
	return 0;
1517
}
1518

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

    
1527
?>
(59-59/68)