Projet

Général

Profil

Télécharger (45,6 ko) Statistiques
| Branche: | Tag: | Révision:

univnautes / etc / inc / vpn.inc @ c650b2f7

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

    
272
		$strongswan = <<<EOD
273

    
274
#Automatically generated please do not modify
275
starter {
276
    load_warning = no
277
}
278

    
279
charon {
280

    
281
        # number of worker threads in charon
282
        threads = 16
283

    
284
	# XXX: There is not much choice here really users win their security!
285
	i_dont_care_about_security_and_use_aggressive_mode_psk=yes
286

    
287
	# And two loggers using syslog. The subsections define the facility to log
288
	# to, currently one of: daemon, auth.
289
	syslog {
290

    
291
		identifier = charon
292
		# default level to the LOG_DAEMON facility
293
		daemon {
294
		}
295
		# very minimalistic IKE auditing logs to LOG_AUTHPRIV
296
		auth {
297
		    default = -1
298
		    ike = 1
299
		    ike_name = yes
300
		}
301
	}
302

    
303
EOD;
304

    
305
		if (is_array($a_client) && isset($a_client['enable']) && isset($a_client['net_list']))
306
			$strongswan .= "\tcisco_unity = yes\n";
307

    
308
		$strongswan .= "\tplugins {\n";
309

    
310
		if (is_array($a_client) && isset($a_client['enable'])) {
311
			$strongswan .= "\t\tattr {\n";
312
			if ($a_client['pool_address'] && $a_client['pool_netbits'])
313
				$strongswan .= "\t\tsubnet = {$a_client['pool_address']}/{$a_client['pool_netbits']}\n";
314

    
315
			$cfgservers = array();
316
			if (!empty($a_client['dns_server1']))
317
				$cfgservers[] = $a_client['dns_server1'];
318
			if (!empty($a_client['dns_server2']))
319
				$cfgservers[] = $a_client['dns_server2'];
320
			if (!empty($a_client['dns_server3']))
321
				$cfgservers[] = $a_client['dns_server3'];
322
			if (!empty($a_client['dns_server4']))
323
				$cfgservers[] = $a_client['dns_server4'];
324

    
325
			if (!empty($cfgservers))
326
				$strongswan .= "\t\tdns = " . implode(",", $cfgservers) . "\n";
327
			unset($cfgservers);
328
			$cfgservers = array();
329
			if (!empty($a_client['wins_server1']))
330
				$cfgservers[] = $a_client['wins_server1'];
331
			if (!empty($a_client['wins_server2']))
332
				$cfgservers[] = $a_client['wins_server2'];
333
			if (!empty($cfgservers))
334
				$strongswan .= "\t\tnbns = " . implode(",", $cfgservers) . "\n";
335
			unset($cfgservers);
336

    
337
			if (isset($a_client['net_list'])) {
338
				$net_list = '';
339
				foreach ($a_phase2 as $ph2ent) {
340
					if (isset($ph2ent['disabled']))
341
						continue;
342

    
343
					if (!isset($ph2ent['mobile']))
344
						continue;
345

    
346
					$localid = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
347

    
348
					if (!empty($net_list))
349
						$net_list .= ",";
350
					$net_list .= $localid;
351
				}
352

    
353
				if (!empty($net_list)) {
354
					$strongswan .= "\t\tsplit-include = {$net_list}\n";
355
					unset($net_list);
356
				}
357
			}
358

    
359
			if (!empty($a_client['dns_domain'])) {
360
				$strongswan .= "\t\t# Search domain and default domain\n";
361
				$strongswan .= "\t\t28674 = {$a_client['dns_domain']}\n";
362
				if (empty($a_client['dns_split']))
363
					$strongswan .= "\t\t28675 = {$a_client['dns_domain']}";
364
				$strongswan .= "\n";
365
			}
366

    
367
			if (!empty($a_client['dns_split'])) {
368
				$strongswan .= "\t\t28675 = {$a_client['dns_split']}\n";
369
			}
370

    
371
			if (!empty($a_client['login_banner']))
372
				$strongswan .= "\t\t28672 = {$a_client['login_banner']}\n";
373

    
374
			if (isset($a_client['save_passwd']))
375
				$strongswan .= "\t\t28673 = yes\n";
376

    
377
			if ($a_client['pfs_group'])
378
				$strongswan .= "\t\t28679 = {$a_client['pfs_group']}\n";
379
			$strongswan .= "\t\t}\n";
380

    
381
			if ($a_client['user_source'] != "none") {
382
				$strongswan .= "\txauth-generic {\n";
383
				$strongswan .= "\t\tscript = /etc/inc/ipsec.auth-user.php\n";
384
				$strongswan .= "\t\tauthcfg = ";
385
				$firstsed = 0;
386
				$authcfgs = explode(",", $a_client['user_source']);
387
				foreach ($authcfgs as $authcfg) {
388
					if ($firstsed > 0)
389
						$strongswan .= ",";
390
					if ($authcfg == "system")
391
						$authcfg = "Local Database";
392
					$strongswan .= $authcfg;
393
					$firstsed = 1;
394
				}
395
				$strongswan .= "\n";
396
				$strongswan .= "\t}\n";
397
			}
398
		}
399

    
400
		$strongswan .= "\t}\n}\n";
401
		@file_put_contents("{$g['varetc_path']}/ipsec/strongswan.conf", $strongswan);
402
		unset($strongswan);
403

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

    
426
		$pskconf = "";
427

    
428
		if (is_array($a_phase1) && count($a_phase1)) {
429
			foreach ($a_phase1 as $ph1ent) {
430

    
431
				if (isset($ph1ent['disabled']))
432
					continue;
433

    
434
				if (strstr($ph1ent['authentication_method'],'rsa')) {
435
					$certline = '';
436

    
437
					if (strstr($authmethod,'rsa')) {
438

    
439
						$cert = lookup_cert($ph1ent['certref']);
440

    
441
						if (!$cert) {
442
							log_error(sprintf(gettext("Error: Invalid phase1 certificate reference for %s"), $ph1ent['name']));
443
							continue;
444
						}
445

    
446
						chmod($certpath, 0600);
447

    
448
						$keyfile = "cert-{$ikeid}.key";
449
						$keypath = "{$g['varetc_path']}/ipsec/{$keyfile}";
450

    
451
						if (!file_put_contents($keypath, base64_decode($cert['prv']))) {
452
							log_error(sprintf(gettext("Error: Cannot write phase1 key file for %s"), $ph1ent['name']));
453
							continue;
454
						}
455

    
456
						chmod($keypath, 0600);
457
						/* XXX" Traffic selectors? */
458
						$pskconf .= " : RSA {$keypath}\n";
459

    
460
						$ca = lookup_ca($ph1ent['caref']);
461
						if ($ca) {
462
							$cafile = "ca-{$ikeid}.crt";
463
							$capath = "{$g['varetc_path']}/ipsec/ipsec.d/cacerts/{$cafile}";
464

    
465
							if (!file_put_contents($capath, base64_decode($ca['crt'])))
466
							{
467
								log_error(sprintf(gettext("Error: Cannot write phase1 CA certificate file for %s"), $ph1ent['name']));
468
								continue;
469
							}
470

    
471
							chmod($capath, 0600);
472
						}
473
					}
474
				} else {
475
					list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, "local");
476
					list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, "peer", $rgmap);
477

    
478
					if (empty($peerid_data))
479
						continue;
480

    
481
					$myid = isset($ph1ent['mobile']) ? trim($myid_data) . " " : "";
482
					$peerid = ($peerid_data != "allusers") ? trim($peerid_data) : "";
483
					if (!empty($ph1ent['pre-shared-key']))
484
						$pskconf .= $myid . $peerid . " : PSK \"" . trim($ph1ent['pre-shared-key']) . "\"\n";
485
				}
486
			}
487
		}
488

    
489
		/* Add user PSKs */
490
		if (is_array($config['system']) && is_array($config['system']['user'])) {
491
			foreach ($config['system']['user'] as $user) {
492
				if (!empty($user['ipsecpsk'])) {
493
					$pskconf .= "{$user['name']} : PSK \"{$user['ipsecpsk']}\"\n";
494
				}
495
			}
496
			unset($user);
497
		}
498

    
499
		/* add PSKs for mobile clients */
500
		if (is_array($ipseccfg['mobilekey'])) {
501
			foreach ($ipseccfg['mobilekey'] as $key) {
502
				if ($key['ident'] == "allusers")
503
					$key['ident'] = '';
504
				$pskconf .= "{$key['ident']} : PSK \"{$key['pre-shared-key']}\"\n";
505
			}
506
			unset($key);
507
		}
508

    
509
		@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.secrets", $pskconf);
510
		chmod("{$g['varetc_path']}/ipsec/ipsec.secrets", 0600);
511
		unset($pskconf);
512

    
513
		$natfilterrules = false;
514
		/* begin ipsec.conf */
515
		$ipsecconf = "";
516
		if (is_array($a_phase1) && count($a_phase1))  {
517

    
518
			$ipsecconf .= "# This file is automatically generated. Do not edit\n";
519
			$ipsecconf .= "config setup\n\tuniqueids = yes\n";
520
			$ipsecconf .= "\tcharondebug=\"" . vpn_ipsec_configure_loglevels(true) . "\"\n";
521

    
522
			foreach ($a_phase1 as $ph1ent) {
523
				if (isset($ph1ent['disabled']))
524
					continue;
525

    
526
				if ($ph1ent['mode'] == "aggressive")
527
					$aggressive = "yes";
528
				else
529
					$aggressive = "no";
530

    
531
				$ep = ipsec_get_phase1_src($ph1ent);
532
				if (!$ep)
533
					continue;
534

    
535
				$keyexchange = "ikev1";
536
				$passive = "route";
537
				if (!empty($ph1ent['iketype']) && $ph1ent['iketype'] != "ikev1") {
538
					$keyexchange = "ikev2";
539
					//$passive = "start";
540
				} else
541
					$passive = "route";
542

    
543
				if (isset($ph1ent['mobile'])) {
544
					$right_spec = "%any";
545
					$passive = 'add';
546
				} else
547
					$right_spec = $ph1ent['remote-gateway'];
548

    
549
				list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, "local");
550
				list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, "peer", $rgmap);
551

    
552
				/* Only specify peer ID if we are not dealing with a mobile PSK-only tunnel */
553
				$peerid_spec = '';
554
				if (!isset($ph1ent['mobile']))
555
					$peerid_spec = $peerid_data;
556

    
557
				if (is_array($ph1ent['encryption-algorithm']) && !empty($ph1ent['encryption-algorithm']['name']) && !empty($ph1ent['hash-algorithm'])) {
558
					$ealgosp1 = '';
559
					$ealg_id = $ph1ent['encryption-algorithm']['name'];
560
					$ealg_kl = $ph1ent['encryption-algorithm']['keylen'];
561
					if ($ealg_kl)
562
						$ealgosp1 = "ike = {$ealg_id}{$ealg_kl}-{$ph1ent['hash-algorithm']}";
563
					else
564
						$ealgosp1 = "ike = {$ealg_id}-{$ph1ent['hash-algorithm']}";
565

    
566
					$modp = vpn_ipsec_convert_to_modp($ph1ent['dhgroup']);
567
					if (!empty($modp))
568
						$ealgosp1 .= "-{$modp}";
569

    
570
					$ealgosp1 .= "!";
571
				}
572

    
573
				if ($ph1ent['dpd_delay'] && $ph1ent['dpd_maxfail']) {
574
					if ($passive == "route")
575
						$dpdline = "dpdaction = restart";
576
					else
577
						$dpdline = "dpdaction = clear";
578
					$dpdline .= "\n\tdpddelay = {$ph1ent['dpd_delay']}s";
579
					$dpdtimeout = $ph1ent['dpd_delay'] * ($ph1ent['dpd_maxfail'] + 1);
580
					$dpdline .= "\n\tdpdtimeout = {$dpdtimeout}s";
581
				} else
582
					$dpdline = "dpdaction = none";
583

    
584
				$ikelifeline = '';
585
				if ($ph1ent['lifetime'])
586
					$ikelifeline = "ikelifetime = {$ph1ent['lifetime']}s";
587

    
588
				$authentication = "";
589
				$rightsourceip = NULL;
590
				switch ($ph1ent['authentication_method']) {
591
				case 'xauth_rsa_server':
592
					$authentication = "leftauth = pubkey\n\trightauth = pubkey";
593
					$authentication .= "\n\trightauth2 = xauth-generic";
594
					break;
595
				case 'xauth_psk_server':
596
					$authentication = "leftauth = psk\n\trightauth = psk";
597
					$authentication .= "\n\trightauth2 = xauth-generic";
598
					if (!empty($a_client['pool_address'])) 
599
						$rightsourceip = "\trightsourceip = {$a_client['pool_address']}/{$a_client['pool_netbits']}\n";
600
					break;
601
				case 'pre_shared_key':
602
					$authentication = "leftauth = psk\n\trightauth = psk";
603
					break;
604
				case 'rsasig':
605
					$authentication = "leftauth = pubkey\n\trightauth = pubkey";
606
					break;
607
				case 'hybrid_rsa_server':
608
					$authentication = "leftauth = xauth-generic\n\trightauth = pubkey";
609
					$authentication .= "\n\trightauth2 = xauth";
610
					break;
611
				}
612

    
613
				$left_spec = $ep;
614

    
615
				$ipseclifetime = 0;
616
				$rightsubnet_spec = array();
617
				$leftsubnet_spec = array();
618
				$ealgoAHsp2arr = array();
619
				$ealgoESPsp2arr = array();
620
			if (is_array($a_phase2) && count($a_phase2)) {
621
				foreach ($a_phase2 as $ph2ent) {
622
					$ikeid = $ph2ent['ikeid'];
623
					if ($ikeid != $ph1ent['ikeid'])
624
						continue;
625

    
626
					if (isset($ph2ent['disabled']))
627
						continue;
628

    
629
					if (isset($ph2ent['mobile']) && !isset($a_client['enable']))
630
						continue;
631

    
632
					if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
633
						$tunneltype = "type = tunnel";
634

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

    
663
						if (empty($leftsubnet_spec[$leftsubnet_data]))
664
							$leftsubnet_spec[$leftsubnet_data] = $leftsubnet_data;
665

    
666
						if (!isset($ph2ent['mobile'])) {
667
							$tmpsubnet = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']);
668
							if (empty($rightsubnet_spec[$tmpsubnet]))
669
								$rightsubnet_spec[$tmpsubnet] = $tmpsubnet;
670
						} else if (!empty($a_client['pool_address'])) {
671
							if (empty($rightsubnet_spec["{$a_client['pool_address']}/{$a_client['pool_netbits']}"]))
672
								$rightsubnet_spec["{$a_client['pool_address']}/{$a_client['pool_netbits']}"] = "{$a_client['pool_address']}/{$a_client['pool_netbits']}";
673
						}
674
					} else {
675
						$tunneltype = "type = transport";
676

    
677
						if ((($ph1ent['authentication_method'] == "xauth_psk_server") ||
678
						    ($ph1ent['authentication_method'] == "pre_shared_key")) && isset($ph1ent['mobile'])) {
679
							$left_spec = "%any";
680
						} else {
681
							$tmpsubnet = ipsec_get_phase1_src($ph1ent);
682
							if ($leftsubnet_spec[$tmpsubnet])
683
								$leftsubnet_spec[$tmpsubnet] = $tmpsubnet;
684
						}
685

    
686
						if (!isset($ph2ent['mobile'])) {
687
							if (empty($rightsubnet_spec[$right_spec]))
688
								$rightsubnet_spec[$right_spec] = $right_spec;
689
						}
690
					}
691

    
692
					if (isset($a_client['pfs_group']))
693
						$ph2ent['pfsgroup'] = $a_client['pfs_group'];
694

    
695
					if ($ph2ent['protocol'] == 'esp') {
696
						if (is_array($ph2ent['encryption-algorithm-option'])) {
697
							foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
698
								$ealg_id = $ealg['name'];
699
								$ealg_kl = $ealg['keylen'];
700

    
701
								if (!empty($ealg_kl) && $ealg_kl == "auto") {
702
									if (empty($p2_ealgos) || !is_array($p2_ealgos))
703
										require("ipsec.inc");
704
									$key_hi = $p2_ealgos[$ealg_id]['keysel']['hi'];
705
									$key_lo = $p2_ealgos[$ealg_id]['keysel']['lo'];
706
									$key_step = $p2_ealgos[$ealg_id]['keysel']['step'];
707
									/* XXX: in some cases where include ordering is suspect these variables
708
									 * are somehow 0 and we enter this loop forever and timeout after 900
709
									 * seconds wrecking bootup */
710
									if ($key_hi != 0 and $key_lo !=0 and $key_step !=0) {
711
										for ($keylen = $key_hi; $keylen >= $key_lo; $keylen -= $key_step) {
712
											if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
713
												foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
714
													$halgo = str_replace('hmac_', '', $halgo);
715
													$tmpealgo = "{$ealg_id}{$keylen}-{$halgo}";
716
													$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
717
													if (!empty($modp))
718
														$tmpealgo .= "-{$modp}";
719
													$ealgoESPsp2arr[] = $tmpealgo;
720
												}
721
											} else {
722
												$tmpealgo = "{$ealg_id}{$keylen}";
723
												$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
724
												if (!empty($modp))
725
													$tmpealgo .= "-{$modp}";
726
												$ealgoESPsp2arr[] = $tmpealgo;
727
											}
728
										}
729
									}
730
								} else {
731
									if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
732
										foreach ($ph2ent['hash-algorithm-option'] as $halgo) {
733
											$halgo = str_replace('hmac_', '', $halgo);
734
											$tmpealgo = "{$ealg_id}{$ealg_kl}-{$halgo}";
735
											$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
736
											if (!empty($modp))
737
												$tmpealgo .= "-{$modp}";
738
											$ealgoESPsp2arr[] = $tmpealgo;
739
										}
740
									} else {
741
										$tmpealgo = "{$ealg_id}{$ealg_kl}";
742
										$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
743
										if (!empty($modp))
744
											$tmpealgo .= "-{$modp}";
745
										$ealgoESPsp2arr[] = $tmpealgo;
746
									}
747
								}
748
							}
749
						}
750
					} else if ($ph2ent['protocol'] == 'ah') {
751
						if (!empty($ph2ent['hash-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
752
							$modp = vpn_ipsec_convert_to_modp($ph2ent['pfsgroup']);
753
							foreach ($ph2ent['hash-algorithm-option'] as $tmpAHalgo) {
754
								$tmpAHalgo = str_replace('hmac_', '', $tmpAHalgo);
755
								if (!empty($modp))
756
									$tmpAHalgo = "-{$modp}";
757
								$ealgoAHsp2arr[] = $tmpAHalgo;
758
							}
759
						}
760
					}
761

    
762

    
763
					if (!empty($ph2ent['lifetime'])) {
764
						if ($ipseclifetime == 0 || intval($ipseclifetime) > intval($ph2ent['lifetime']))
765
							$ipseclifetime = intval($ph2ent['lifetime']);
766
					}
767
				}
768
			}
769

    
770
				$ipsecconf .=<<<EOD
771

    
772
conn con{$ph1ent['ikeid']}
773
	aggressive = {$aggressive}
774
	fragmentation = yes
775
	keyexchange = {$keyexchange}
776
	reauth = yes
777
	rekey = yes
778
	reqid = {$ikeid}
779
	installpolicy = yes
780
	{$tunneltype}
781
	{$dpdline}
782
	auto = {$passive}
783
	left = {$left_spec}
784
	right = {$right_spec}
785
	leftid = {$myid_data}
786

    
787
EOD;
788

    
789
				if (!empty($ikelifeline))
790
					$ipsecconf .= "\t{$ikelifeline}\n";
791
				if ($ipseclifetime > 0)
792
					$ipsecconf .= "\tlifetime = {$ipseclifetime}s\n";
793
				if (!empty($rightsourceip))
794
					$ipsecconf .= "{$rightsourceip}";
795
				if (!empty($rightsubnet_spec))
796
					$ipsecconf .= "\trightsubnet = " . join(",", $rightsubnet_spec) . "\n";
797
				if (!empty($leftsubnet_spec))
798
					$ipsecconf .= "\tleftsubnet = " . join(",", $leftsubnet_spec) . "\n";
799
				if (!empty($ealgosp1))
800
					$ipsecconf .= "\t{$ealgosp1}\n";
801
				if (!empty($ealgoAHsp2arr))
802
					$ipsecconf .= "\tah = " . join(',', $ealgoAHsp2arr) . "!\n";
803
				if (!empty($ealgoESPsp2arr)) {
804
					file_put_contents("/var/etc/ipsec/dump_test", print_r($ealgoESPsp2arr, true));
805
					$ipsecconf .= "\tesp = " . join(',', $ealgoESPsp2arr) . "!\n";
806
				}
807
				if (!empty($authentication))
808
					$ipsecconf .= "\t{$authentication}\n";
809
				if (!empty($peerid_spec))
810
					$ipsecconf .= "\trightid = {$peerid_spec}\n";
811
			}
812
		}
813
	}
814
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.conf", $ipsecconf);
815
	unset($ipsecconf);
816
	/* end ipsec.conf */
817

    
818
	/* mange process */
819
	if (isvalidpid("{$g['varrun_path']}/charon.pid")) {
820
		/* Read secrets */
821
		mwexec("/usr/local/sbin/ipsec rereadall", false);
822
		/* Update configuration changes */
823
		mwexec("/usr/local/sbin/ipsec reload", false);
824
	} else {
825
		mwexec("/usr/local/sbin/ipsec start", false); 
826
	}
827

    
828
	if ($natfilterrules == true)
829
		filter_configure();
830
	/* start filterdns, if necessary */
831
	if (count($filterdns_list) > 0) {
832
		$interval = 60;
833
		if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval']))
834
			$interval = $ipseccfg['dns-interval'];
835

    
836
		$hostnames = "";
837
		array_unique($filterdns_list);
838
		foreach ($filterdns_list as $hostname)
839
			$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload ipsecdns\"'\n";
840
		file_put_contents("{$g['varetc_path']}/ipsec/filterdns-ipsec.hosts", $hostnames);
841
		unset($hostnames);
842

    
843
		if (isvalidpid("{$g['varrun_path']}/filterdns-ipsec.pid"))
844
			sigkillbypid("{$g['varrun_path']}/filterdns-ipsec.pid", "HUP");
845
		else {
846
			mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/ipsec/filterdns-ipsec.hosts -d 1");
847
		}
848
	} else {
849
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
850
		@unlink("{$g['varrun_path']}/filterdns-ipsec.pid");
851
	}
852

    
853
	if ($g['booting'])
854
		echo "done\n";
855

    
856
	return count($filterdns_list);
857
}
858

    
859
/*
860
 * Forcefully restart IPsec
861
 * This is required for when dynamic interfaces reload
862
 * For all other occasions the normal vpn_ipsec_configure()
863
 * will gracefully reload the settings without restarting
864
 */
865
function vpn_ipsec_force_reload($interface = "") {
866
	global $g, $config;
867

    
868
	$ipseccfg = $config['ipsec'];
869

    
870
	if (!empty($interface) && is_array($ipseccfg['phase1'])) {
871
		$found = false;
872
		foreach ($ipseccfg['phase1'] as $ipsec) {
873
			if (!isset($ipsec['disabled']) && ($ipsec['interface'] == $interface)) {
874
				$found = true;
875
				break;
876
			}
877
		}
878
		if (!$found) {
879
			log_error(sprintf(gettext("Ignoring IPsec reload since there are no tunnels on interface %s"), $interface));
880
			return;
881
		}
882
	}
883

    
884
	/* if ipsec is enabled, start up again */
885
	if (isset($ipseccfg['enable'])) {
886
		log_error(gettext("Forcefully reloading IPsec"));
887
		vpn_ipsec_configure();
888
	}
889
}
890

    
891
/* master setup for vpn (mpd) */
892
function vpn_setup() {
893
	global $g;
894

    
895
	if ($g['platform'] == 'jail')
896
		return;
897

    
898
	/* start pptpd */
899
	vpn_pptpd_configure();
900

    
901
	/* start pppoe server */
902
	vpn_pppoes_configure();
903

    
904
	/* setup l2tp */
905
	vpn_l2tp_configure();
906
}
907

    
908
function vpn_netgraph_support() {
909
	$iflist = get_configured_interface_list();
910
	foreach ($iflist as $iface) {
911
		$realif = get_real_interface($iface);
912
		/* Get support for netgraph(4) from the nic */
913
		$ifinfo = pfSense_get_interface_addresses($realif);
914
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge")))
915
			pfSense_ngctl_attach(".", $realif);
916
	}
917
}
918

    
919
function vpn_pptpd_configure() {
920
	global $config, $g;
921

    
922
	$syscfg = $config['system'];
923
	$pptpdcfg = $config['pptpd'];
924

    
925
	if ($g['booting']) {
926
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
927
			return 0;
928

    
929
		echo gettext("Configuring PPTP VPN service... ");
930
	} else {
931
		/* kill mpd */
932
		killbypid("{$g['varrun_path']}/pptp-vpn.pid");
933

    
934
		/* wait for process to die */
935
		sleep(3);
936

    
937
		if (is_process_running("mpd -b")) {
938
			killbypid("{$g['varrun_path']}/pptp-vpn.pid");
939
			log_error(gettext("Could not kill mpd within 3 seconds.   Trying again."));
940
		}
941

    
942
		/* remove mpd.conf, if it exists */
943
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.conf");
944
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.links");
945
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.secret");
946
	}
947

    
948
	if (empty($pptpdcfg['n_pptp_units'])) {
949
		log_error("Something wrong in the PPTPd configuration. Preventing starting the daemon because issues would arise.");
950
		return;
951
	}
952

    
953
	/* make sure pptp-vpn directory exists */
954
	if (!file_exists("{$g['varetc_path']}/pptp-vpn"))
955
		mkdir("{$g['varetc_path']}/pptp-vpn");
956

    
957
	switch ($pptpdcfg['mode']) {
958
		case 'server' :
959
			/* write mpd.conf */
960
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.conf", "w");
961
			if (!$fd) {
962
				printf(gettext("Error: cannot open mpd.conf in vpn_pptpd_configure().") . "\n");
963
				return 1;
964
			}
965

    
966
			$mpdconf = <<<EOD
967
pptps:
968

    
969
EOD;
970

    
971
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
972
				$mpdconf .= "	load pt{$i}\n";
973
			}
974

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

    
977
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
978

    
979
				$mpdconf .= <<<EOD
980

    
981
pt{$i}:
982
	new -i pptpd{$i} pt{$i} pt{$i}
983
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
984
	load pts
985

    
986
EOD;
987
			}
988

    
989
			$mpdconf .=<<<EOD
990

    
991
pts:
992
	set iface disable on-demand
993
	set iface enable proxy-arp
994
	set iface enable tcpmssfix
995
	set iface idle 1800
996
	set iface up-script /usr/local/sbin/vpn-linkup
997
	set iface down-script /usr/local/sbin/vpn-linkdown
998
	set bundle enable multilink
999
	set bundle enable crypt-reqd
1000
	set link yes acfcomp protocomp
1001
	set link no pap chap
1002
	set link enable chap-msv2
1003
	set link mtu 1460
1004
	set link keep-alive 10 60
1005
	set ipcp yes vjcomp
1006
	set bundle enable compression
1007
	set ccp yes mppc
1008
	set ccp yes mpp-e128
1009
	set ccp yes mpp-stateless
1010

    
1011
EOD;
1012

    
1013
			if (!isset ($pptpdcfg['req128'])) {
1014
				$mpdconf .=<<<EOD
1015
	set ccp yes mpp-e40
1016
	set ccp yes mpp-e56
1017

    
1018
EOD;
1019
			}
1020

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

    
1024
			if (!empty($pptpdcfg['dns1'])) {
1025
				$mpdconf .= "	set ipcp dns " . $pptpdcfg['dns1'];
1026
				if (!empty($pptpdcfg['dns2']))
1027
					$mpdconf .= " " . $pptpdcfg['dns2'];
1028
				$mpdconf .= "\n";
1029
			} elseif (isset ($config['dnsmasq']['enable'])) {
1030
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1031
				if ($syscfg['dnsserver'][0])
1032
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1033
				$mpdconf .= "\n";
1034
			} elseif (isset($config['unbound']['enable'])) {
1035
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1036
				if ($syscfg['dnsserver'][0])
1037
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1038
				$mpdconf .= "\n";
1039
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1040
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1041
			}
1042

    
1043
			if (isset ($pptpdcfg['radius']['server']['enable'])) {
1044
				$authport = (isset($pptpdcfg['radius']['server']['port']) && strlen($pptpdcfg['radius']['server']['port']) > 1) ? $pptpdcfg['radius']['server']['port'] : 1812;
1045
				$acctport = $authport + 1;
1046
				$mpdconf .=<<<EOD
1047
	set radius server {$pptpdcfg['radius']['server']['ip']} "{$pptpdcfg['radius']['server']['secret']}" {$authport} {$acctport}
1048

    
1049
EOD;
1050
			if (isset ($pptpdcfg['radius']['server2']['enable'])) {
1051
				$authport = (isset($pptpdcfg['radius']['server2']['port']) && strlen($pptpdcfg['radius']['server2']['port']) > 1) ? $pptpdcfg['radius']['server2']['port'] : 1812;
1052
				$acctport = $authport + 1;
1053
				$mpdconf .=<<<EOD
1054
	set radius server {$pptpdcfg['radius']['server2']['ip']} "{$pptpdcfg['radius']['server2']['secret2']}" {$authport} {$acctport}
1055

    
1056
EOD;
1057
			}
1058
			$mpdconf .=<<<EOD
1059
	set radius retries 3
1060
	set radius timeout 10
1061
	set auth enable radius-auth
1062

    
1063
EOD;
1064

    
1065
				if (isset ($pptpdcfg['radius']['accounting'])) {
1066
					$mpdconf .=<<<EOD
1067
	set auth enable radius-acct
1068
	set radius acct-update 300
1069

    
1070
EOD;
1071
				}
1072
			}
1073

    
1074
			fwrite($fd, $mpdconf);
1075
			fclose($fd);
1076
			unset($mpdconf);
1077

    
1078
			/* write mpd.links */
1079
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.links", "w");
1080
			if (!$fd) {
1081
				printf(gettext("Error: cannot open mpd.links in vpn_pptpd_configure().") . "\n");
1082
				return 1;
1083
			}
1084

    
1085
			$mpdlinks = "";
1086

    
1087
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1088
				$mpdlinks .=<<<EOD
1089

    
1090
pt{$i}:
1091
	set link type pptp
1092
	set pptp enable incoming
1093
	set pptp disable originate
1094
	set pptp disable windowing
1095

    
1096
EOD;
1097
			}
1098

    
1099
			fwrite($fd, $mpdlinks);
1100
			fclose($fd);
1101
			unset($mpdlinks);
1102

    
1103
			/* write mpd.secret */
1104
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.secret", "w");
1105
			if (!$fd) {
1106
				printf(gettext("Error: cannot open mpd.secret in vpn_pptpd_configure().") . "\n");
1107
				return 1;
1108
			}
1109

    
1110
			$mpdsecret = "";
1111

    
1112
			if (is_array($pptpdcfg['user'])) {
1113
				foreach ($pptpdcfg['user'] as $user) {
1114
					$pass = str_replace('\\', '\\\\', $user['password']);
1115
					$pass = str_replace('"', '\"', $pass);
1116
					$mpdsecret .= "{$user['name']} \"{$pass}\" {$user['ip']}\n";
1117
				}
1118
			}
1119

    
1120
			fwrite($fd, $mpdsecret);
1121
			fclose($fd);
1122
			unset($mpdsecret);
1123
			chmod("{$g['varetc_path']}/pptp-vpn/mpd.secret", 0600);
1124

    
1125
			vpn_netgraph_support();
1126

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

    
1130
			break;
1131

    
1132
		case 'redir' :
1133
			break;
1134
	}
1135

    
1136
	if ($g['booting'])
1137
		echo "done\n";
1138

    
1139
	return 0;
1140
}
1141

    
1142
function vpn_pppoes_configure() {
1143
	global $config;
1144

    
1145
	if (is_array($config['pppoes']['pppoe'])) {
1146
		foreach ($config['pppoes']['pppoe'] as $pppoe)
1147
			vpn_pppoe_configure($pppoe);
1148
	}
1149
}
1150

    
1151
function vpn_pppoe_configure(&$pppoecfg) {
1152
	global $config, $g;
1153

    
1154
	$syscfg = $config['system'];
1155

    
1156
	/* create directory if it does not exist */
1157
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn"))
1158
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1159

    
1160
	if ($g['booting']) {
1161
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
1162
			return 0;
1163

    
1164
		echo gettext("Configuring PPPoE VPN service... ");
1165
	} else {
1166
		/* kill mpd */
1167
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1168

    
1169
		/* wait for process to die */
1170
		sleep(2);
1171

    
1172
	}
1173

    
1174
	switch ($pppoecfg['mode']) {
1175

    
1176
		case 'server' :
1177

    
1178
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1179

    
1180
			if ($pppoecfg['paporchap'] == "chap")
1181
				$paporchap = "set link enable chap";
1182
			else
1183
				$paporchap = "set link enable pap";
1184

    
1185
			/* write mpd.conf */
1186
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1187
			if (!$fd) {
1188
				printf(gettext("Error: cannot open mpd.conf in vpn_pppoe_configure().") . "\n");
1189
				return 1;
1190
			}
1191
			$mpdconf = "\n\n";
1192
			$mpdconf .= "poes:\n";
1193

    
1194
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1195
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1196
			}
1197

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

    
1200
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1201

    
1202
				if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1203
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1204
				} else {
1205
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1206
				}
1207

    
1208
				$mpdconf .=<<<EOD
1209

    
1210
poes{$pppoecfg['pppoeid']}{$i}:
1211
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1212
	{$isssue_ip_type}
1213
	load pppoe_standard
1214

    
1215
EOD;
1216
			}
1217

    
1218
			$mpdconf .=<<<EOD
1219

    
1220
pppoe_standard:
1221
	set bundle no multilink
1222
	set bundle enable compression
1223
	set auth max-logins 1
1224
	set iface up-script /usr/local/sbin/vpn-linkup
1225
	set iface down-script /usr/local/sbin/vpn-linkdown
1226
	set iface idle 0
1227
	set iface disable on-demand
1228
	set iface disable proxy-arp
1229
	set iface enable tcpmssfix
1230
	set iface mtu 1500
1231
	set link no pap chap
1232
	{$paporchap}
1233
	set link keep-alive 60 180
1234
	set ipcp yes vjcomp
1235
	set ipcp no vjcomp
1236
	set link max-redial -1
1237
	set link mtu 1492
1238
	set link mru 1492
1239
	set ccp yes mpp-e40
1240
	set ccp yes mpp-e128
1241
	set ccp yes mpp-stateless
1242
	set link latency 1
1243
	#set ipcp dns 10.10.1.3
1244
	#set bundle accept encryption
1245

    
1246
EOD;
1247

    
1248
			if (!empty($pppoecfg['dns1'])) {
1249
				$mpdconf .= "	set ipcp dns " . $pppoecfg['dns1'];
1250
				if (!empty($pppoecfg['dns2']))
1251
					$mpdconf .= " " . $pppoecfg['dns2'];
1252
				$mpdconf .= "\n";
1253
			} elseif (isset ($config['dnsmasq']['enable'])) {
1254
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1255
				if ($syscfg['dnsserver'][0])
1256
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1257
				$mpdconf .= "\n";
1258
			} elseif (isset ($config['unbound']['enable'])) {
1259
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1260
				if ($syscfg['dnsserver'][0])
1261
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1262
				$mpdconf .= "\n";
1263
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1264
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1265
			}
1266

    
1267
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1268
				$radiusport = "";
1269
				$radiusacctport = "";
1270
				if (isset($pppoecfg['radius']['server']['port']))
1271
					$radiusport = $pppoecfg['radius']['server']['port'];
1272
				if (isset($pppoecfg['radius']['server']['acctport']))
1273
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1274
				$mpdconf .=<<<EOD
1275
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
1276
	set radius retries 3
1277
	set radius timeout 10
1278
	set auth enable radius-auth
1279

    
1280
EOD;
1281

    
1282
				if (isset ($pppoecfg['radius']['accounting'])) {
1283
					$mpdconf .=<<<EOD
1284
	set auth enable radius-acct
1285

    
1286
EOD;
1287
				}
1288
			}
1289

    
1290
			fwrite($fd, $mpdconf);
1291
			fclose($fd);
1292
			unset($mpdconf);
1293

    
1294
			/* write mpd.links */
1295
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.links", "w");
1296
			if (!$fd) {
1297
				printf(gettext("Error: cannot open mpd.links in vpn_pppoe_configure().") . "\n");
1298
				return 1;
1299
			}
1300

    
1301
			$mpdlinks = "";
1302

    
1303
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1304
				$mpdlinks .=<<<EOD
1305

    
1306
poes{$pppoecfg['pppoeid']}{$i}:
1307
	set phys type pppoe
1308
	set pppoe iface {$pppoe_interface}
1309
	set pppoe service "*"
1310
	set pppoe disable originate
1311
	set pppoe enable incoming
1312

    
1313
EOD;
1314
			}
1315

    
1316
			fwrite($fd, $mpdlinks);
1317
			fclose($fd);
1318
			unset($mpdlinks);
1319

    
1320
			if ($pppoecfg['username']) {
1321
				/* write mpd.secret */
1322
				$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
1323
				if (!$fd) {
1324
					printf(gettext("Error: cannot open mpd.secret in vpn_pppoe_configure().") . "\n");
1325
					return 1;
1326
				}
1327

    
1328
				$mpdsecret = "\n\n";
1329

    
1330
				if (!empty($pppoecfg['username'])) {
1331
					$item = explode(" ", $pppoecfg['username']);
1332
					foreach($item as $userdata) {
1333
						$data = explode(":", $userdata);
1334
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1335
					}
1336
				}
1337

    
1338
				fwrite($fd, $mpdsecret);
1339
				fclose($fd);
1340
				unset($mpdsecret);
1341
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1342
			}
1343

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

    
1348
			/* Get support for netgraph(4) from the nic */
1349
			pfSense_ngctl_attach(".", $pppoe_interface);
1350
			/* fire up mpd */
1351
			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");
1352

    
1353
			break;
1354
	}
1355

    
1356
	if ($g['booting'])
1357
		echo gettext("done") . "\n";
1358

    
1359
	return 0;
1360
}
1361

    
1362
function vpn_l2tp_configure() {
1363
	global $config, $g;
1364

    
1365
	$syscfg = $config['system'];
1366
	$l2tpcfg = $config['l2tp'];
1367

    
1368
	/* create directory if it does not exist */
1369
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn"))
1370
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1371

    
1372
	if ($g['booting']) {
1373
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off"))
1374
			return 0;
1375

    
1376
		echo gettext("Configuring l2tp VPN service... ");
1377
	} else {
1378
		/* kill mpd */
1379
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1380

    
1381
		/* wait for process to die */
1382
		sleep(8);
1383

    
1384
	}
1385

    
1386
	/* make sure l2tp-vpn directory exists */
1387
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn"))
1388
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1389

    
1390
	switch ($l2tpcfg['mode']) {
1391

    
1392
		case 'server' :
1393
			if ($l2tpcfg['paporchap'] == "chap")
1394
				$paporchap = "set link enable chap";
1395
			else
1396
				$paporchap = "set link enable pap";
1397

    
1398
			/* write mpd.conf */
1399
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1400
			if (!$fd) {
1401
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
1402
				return 1;
1403
			}
1404
			$mpdconf = "\n\n";
1405
			$mpdconf .=<<<EOD
1406
l2tps:
1407

    
1408
EOD;
1409

    
1410
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1411
				$mpdconf .= "	load l2tp{$i}\n";
1412
			}
1413

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

    
1416
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1417

    
1418
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1419
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1420
				} else {
1421
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1422
				}
1423

    
1424
				$mpdconf .=<<<EOD
1425

    
1426
l2tp{$i}:
1427
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1428
	{$isssue_ip_type}
1429
	load l2tp_standard
1430

    
1431
EOD;
1432
			}
1433

    
1434
			$mpdconf .=<<<EOD
1435

    
1436
l2tp_standard:
1437
	set bundle disable multilink
1438
	set bundle enable compression
1439
	set bundle yes crypt-reqd
1440
	set ipcp yes vjcomp
1441
	# set ipcp ranges 131.188.69.161/32 131.188.69.170/28
1442
	set ccp yes mppc
1443
	set iface disable on-demand
1444
	set iface enable proxy-arp
1445
	set iface up-script /usr/local/sbin/vpn-linkup
1446
	set iface down-script /usr/local/sbin/vpn-linkdown
1447
	set link yes acfcomp protocomp
1448
	set link no pap chap
1449
	set link enable chap
1450
	set link keep-alive 10 180
1451

    
1452
EOD;
1453

    
1454
			if (is_ipaddr($l2tpcfg['wins'])) {
1455
				$mpdconf .= "	set ipcp nbns {$l2tpcfg['wins']}\n";
1456
			}
1457
			if (is_ipaddr($l2tpcfg['dns1'])) {
1458
				$mpdconf .= "	set ipcp dns " . $l2tpcfg['dns1'];
1459
				if (is_ipaddr($l2tpcfg['dns2']))
1460
					$mpdconf .= " " . $l2tpcfg['dns2'];
1461
				$mpdconf .= "\n";
1462
			} elseif (isset ($config['dnsmasq']['enable'])) {
1463
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1464
				if ($syscfg['dnsserver'][0])
1465
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1466
				$mpdconf .= "\n";
1467
			} elseif (isset ($config['unbound']['enable'])) {
1468
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1469
				if ($syscfg['dnsserver'][0])
1470
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1471
				$mpdconf .= "\n";
1472
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1473
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1474
			}
1475

    
1476
			if (isset ($l2tpcfg['radius']['enable'])) {
1477
				$mpdconf .=<<<EOD
1478
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1479
	set radius retries 3
1480
	set radius timeout 10
1481
	set auth enable radius-auth
1482

    
1483
EOD;
1484

    
1485
				if (isset ($l2tpcfg['radius']['accounting'])) {
1486
					$mpdconf .=<<<EOD
1487
	set auth enable radius-acct
1488

    
1489
EOD;
1490
				}
1491
			}
1492

    
1493
			fwrite($fd, $mpdconf);
1494
			fclose($fd);
1495
			unset($mpdconf);
1496

    
1497
			/* write mpd.links */
1498
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.links", "w");
1499
			if (!$fd) {
1500
				printf(gettext("Error: cannot open mpd.links in vpn_l2tp_configure().") . "\n");
1501
				return 1;
1502
			}
1503

    
1504
			$mpdlinks = "";
1505

    
1506
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1507
				$mpdlinks .=<<<EOD
1508

    
1509
l2tp{$i}:
1510
	set link type l2tp
1511
	set l2tp enable incoming
1512
	set l2tp disable originate
1513

    
1514
EOD;
1515
			if (!empty($l2tpcfg['secret']))
1516
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
1517
			}
1518

    
1519
			fwrite($fd, $mpdlinks);
1520
			fclose($fd);
1521
			unset($mpdlinks);
1522

    
1523
			/* write mpd.secret */
1524
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.secret", "w");
1525
			if (!$fd) {
1526
				printf(gettext("Error: cannot open mpd.secret in vpn_l2tp_configure().") . "\n");
1527
				return 1;
1528
			}
1529

    
1530
			$mpdsecret = "\n\n";
1531

    
1532
			if (is_array($l2tpcfg['user'])) {
1533
				foreach ($l2tpcfg['user'] as $user)
1534
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1535
			}
1536

    
1537
			fwrite($fd, $mpdsecret);
1538
			fclose($fd);
1539
			unset($mpdsecret);
1540
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
1541

    
1542
			vpn_netgraph_support();
1543

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

    
1547
			break;
1548

    
1549
		case 'redir' :
1550
			break;
1551
	}
1552

    
1553
	if ($g['booting'])
1554
		echo "done\n";
1555

    
1556
	return 0;
1557
}
1558

    
1559
function vpn_ipsec_configure_preferoldsa() {
1560
	global $config;
1561
	if(isset($config['ipsec']['preferoldsa']))
1562
		set_single_sysctl("net.key.preferred_oldsa", "-30");
1563
	else
1564
		set_single_sysctl("net.key.preferred_oldsa", "0");
1565
}
1566

    
1567
?>
(59-59/68)