Projet

Général

Profil

Télécharger (46,5 ko) Statistiques
| Branche: | Tag: | Révision:

univnautes / etc / inc / vpn.inc @ 21cd92ac

1
<?php
2

    
3
/*
4
	vpn.inc
5
	Copyright (C) 2004 Scott Ullrich
6
	Copyright (C) 2008 Shrew Soft Inc
7
	Copyright (C) 2008 Ermal Lu�i
8
	All rights reserved.
9

    
10
	originally part of m0n0wall (http://m0n0.ch/wall)
11
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
12
	All rights reserved.
13

    
14
	Redistribution and use in source and binary forms, with or without
15
	modification, are permitted provided that the following conditions are met:
16

    
17
	1. Redistributions of source code must retain the above copyright notice,
18
	   this list of conditions and the following disclaimer.
19

    
20
	2. Redistributions in binary form must reproduce the above copyright
21
	   notice, this list of conditions and the following disclaimer in the
22
	   documentation and/or other materials provided with the distribution.
23

    
24
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
25
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
26
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
28
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33
	POSSIBILITY OF SUCH DAMAGE.
34
*/
35

    
36
/*
37
	pfSense_BUILDER_BINARIES:	/sbin/ifconfig
38
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/ipsec	/usr/local/libexec/ipsec/charon /usr/local/libexec/ipsec/starter
39
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/filterdns	/usr/local/sbin/mpd4
40
	pfSense_MODULE:	vpn
41
*/
42

    
43
require_once("ipsec.inc");
44

    
45
function vpn_ipsec_configure_loglevels($forconfig = false)
46
{
47
	global $config, $ipsec_loglevels;
48

    
49
	$cfgtext = array();
50
	foreach ($ipsec_loglevels as $lkey => $ldescr) {
51
		if (!isset($config['ipsec']["ipsec_{$lkey}"]) && !$forconfig)
52
			mwexec("/usr/local/sbin/ipsec stroke loglevel {$lkey} -- -1", false);
53
		else if (is_numeric($config['ipsec']["ipsec_{$lkey}"]) &&
54
		    intval($config['ipsec']["ipsec_{$lkey}"]) >= 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
		$certpath = "{$g['varetc_path']}/ipsec/ipsec.d/certs";
132
		$capath = "{$g['varetc_path']}/ipsec/ipsec.d/cacerts";
133
		$keypath = "{$g['varetc_path']}/ipsec/ipsec.d/private";
134

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

    
160
		if ($g['booting'])
161
			echo gettext("Configuring IPsec VPN... ");
162

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

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

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

    
180
				$ikeid = $ph1ent['ikeid'];
181
				$listeniflist = get_real_interface($a_phase1['interface']);
182

    
183
				$ep = ipsec_get_phase1_src($ph1ent);
184
				if (!is_ipaddr($ep))
185
					continue;
186

    
187
				if(!in_array($ep,$ipmap))
188
					$ipmap[] = $ep;
189

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

    
193
				if (isset ($ph1ent['mobile']))
194
					continue;
195

    
196
				$rg = $ph1ent['remote-gateway'];
197

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

    
212
				if (is_array($a_phase2)) {
213
					/* step through each phase2 entry */
214
					foreach ($a_phase2 as $ph2ent) {
215
						if (isset($ph2ent['disabled']))
216
							continue;
217

    
218
						if ($ikeid != $ph2ent['ikeid'])
219
							continue;
220

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

    
275
		$accept_unencrypted = "";
276
		if (isset($config['ipsec']['acceptunencryptedmainmode']))
277
			$accept_unencrypted = "accept_unencrypted_mainmode_messages = yes";
278

    
279
		$strongswan = <<<EOD
280

    
281
# Automatically generated config file - DO NOT MODIFY. Changes will be overwritten. 
282
starter {
283
    load_warning = no
284
}
285

    
286
charon {
287
	# number of worker threads in charon
288
	threads = 16
289
	ikesa_table_size = 32
290
	ikesa_table_segments = 4
291
	init_limit_half_open = 1000
292
	install_routes = no
293

    
294
	# XXX: There is not much choice here really users win their security!
295
	i_dont_care_about_security_and_use_aggressive_mode_psk=yes
296

    
297
	{$accept_unencrypted}
298
	cisco_unity = yes
299

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

    
315
EOD;
316

    
317
		$strongswan .= "\tplugins {\n";
318

    
319
		if (is_array($a_client) && isset($a_client['enable'])) {
320
			$strongswan .= "\t\tattr {\n";
321
			if ($a_client['pool_address'] && $a_client['pool_netbits'])
322
				$strongswan .= "\t\tsubnet = {$a_client['pool_address']}/{$a_client['pool_netbits']}\n";
323

    
324
			$cfgservers = array();
325
			if (!empty($a_client['dns_server1']))
326
				$cfgservers[] = $a_client['dns_server1'];
327
			if (!empty($a_client['dns_server2']))
328
				$cfgservers[] = $a_client['dns_server2'];
329
			if (!empty($a_client['dns_server3']))
330
				$cfgservers[] = $a_client['dns_server3'];
331
			if (!empty($a_client['dns_server4']))
332
				$cfgservers[] = $a_client['dns_server4'];
333

    
334
			if (!empty($cfgservers))
335
				$strongswan .= "\t\tdns = " . implode(",", $cfgservers) . "\n";
336
			unset($cfgservers);
337
			$cfgservers = array();
338
			if (!empty($a_client['wins_server1']))
339
				$cfgservers[] = $a_client['wins_server1'];
340
			if (!empty($a_client['wins_server2']))
341
				$cfgservers[] = $a_client['wins_server2'];
342
			if (!empty($cfgservers))
343
				$strongswan .= "\t\tnbns = " . implode(",", $cfgservers) . "\n";
344
			unset($cfgservers);
345

    
346
			if (isset($a_client['net_list'])) {
347
				$net_list = '';
348
				foreach ($a_phase2 as $ph2ent) {
349
					if (isset($ph2ent['disabled']))
350
						continue;
351

    
352
					if (!isset($ph2ent['mobile']))
353
						continue;
354

    
355
					$localid = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
356

    
357
					if (!empty($net_list))
358
						$net_list .= ",";
359
					$net_list .= $localid;
360
				}
361

    
362
				if (!empty($net_list)) {
363
					$strongswan .= "\t\tsplit-include = {$net_list}\n";
364
					unset($net_list);
365
				}
366
			}
367

    
368
			if (!empty($a_client['dns_domain'])) {
369
				$strongswan .= "\t\t# Search domain and default domain\n";
370
				$strongswan .= "\t\t28674 = {$a_client['dns_domain']}\n";
371
				if (empty($a_client['dns_split']))
372
					$strongswan .= "\t\t28675 = {$a_client['dns_domain']}";
373
				$strongswan .= "\n";
374
			}
375

    
376
			if (!empty($a_client['dns_split'])) {
377
				$strongswan .= "\t\t28675 = {$a_client['dns_split']}\n";
378
			}
379

    
380
			if (!empty($a_client['login_banner']))
381
				$strongswan .= "\t\t28672 = {$a_client['login_banner']}\n";
382

    
383
			if (isset($a_client['save_passwd']))
384
				$strongswan .= "\t\t28673 = yes\n";
385

    
386
			if ($a_client['pfs_group'])
387
				$strongswan .= "\t\t28679 = {$a_client['pfs_group']}\n";
388
			$strongswan .= "\t\t}\n";
389

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

    
409
		$strongswan .= "\t}\n}\n";
410
		@file_put_contents("{$g['varetc_path']}/ipsec/strongswan.conf", $strongswan);
411
		unset($strongswan);
412

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

    
435
		$pskconf = "";
436

    
437
		if (is_array($a_phase1) && count($a_phase1)) {
438
			foreach ($a_phase1 as $ph1ent) {
439

    
440
				if (isset($ph1ent['disabled']))
441
					continue;
442

    
443
				if (strpos($ph1ent['authentication_method'], 'rsa') || $ph1ent['authentication_method'] == 'eap-tls') {
444
					$certline = '';
445

    
446
					$ikeid = $ph1ent['ikeid'];
447
					$cert = lookup_cert($ph1ent['certref']);
448

    
449
					if (!$cert) {
450
						log_error(sprintf(gettext("Error: Invalid phase1 certificate reference for %s"), $ph1ent['name']));
451
						continue;
452
					}
453

    
454
					@chmod($certpath, 0600);
455

    
456
					$ph1keyfile = "{$keypath}/cert-{$ikeid}.key";
457
					if (!file_put_contents($ph1keyfile, base64_decode($cert['prv']))) {
458
						log_error(sprintf(gettext("Error: Cannot write phase1 key file for %s"), $ph1ent['name']));
459
						continue;
460
					}
461
					@chmod($ph1keyfile, 0600);
462

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

    
471
					/* XXX" Traffic selectors? */
472
					$pskconf .= " : RSA {$ph1keyfile}\n";
473
				} else {
474
					list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, "local");
475
					list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, "peer", $rgmap);
476

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
587
				$rightsourceip = NULL;
588
				if (isset($ph1ent['mobile']) && !empty($a_client['pool_address'])) 
589
					$rightsourceip = "\trightsourceip = {$a_client['pool_address']}/{$a_client['pool_netbits']}\n";
590

    
591
				$authentication = "";
592
				switch ($ph1ent['authentication_method']) {
593
				case 'eap-tls':
594
					$authentication = "leftauth=eap-tls\n\trightauth=eap-tls";
595
					if (!empty($ph1ent['certref']))
596
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
597
					break;
598
				case 'xauth_rsa_server':
599
					$authentication = "leftauth = pubkey\n\trightauth = pubkey";
600
					$authentication .= "\n\trightauth2 = xauth-generic";
601
					if (!empty($ph1ent['certref']))
602
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
603
					break;
604
				case 'xauth_psk_server':
605
					$authentication = "leftauth = psk\n\trightauth = psk";
606
					$authentication .= "\n\trightauth2 = xauth-generic";
607
					break;
608
				case 'pre_shared_key':
609
					$authentication = "leftauth = psk\n\trightauth = psk";
610
					break;
611
				case 'rsasig':
612
					$authentication = "leftauth = pubkey\n\trightauth = pubkey";
613
					if (!empty($ph1ent['certref']))
614
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
615
					break;
616
				case 'hybrid_rsa_server':
617
					$authentication = "leftauth = xauth-generic\n\trightauth = pubkey";
618
					$authentication .= "\n\trightauth2 = xauth";
619
					if (!empty($ph1ent['certref']))
620
						$authentication .= "\n\tleftcert={$certpath}/cert-{$ph1ent['ikeid']}.crt";
621
					break;
622
				}
623

    
624
				$left_spec = $ep;
625

    
626
				if (isset($ph1ent['reauth_enable']))
627
					$reauth = "reauth = no";
628
				else
629
					$reauth = "reauth = yes";
630
				if (isset($ph1ent['rekey_enable']))
631
					$rekey = "rekey = no";
632
				else
633
					$rekey = "rekey = yes";
634

    
635
				if ($ph1ent['nat_traversal'] == 'off')
636
					$forceencaps = 'forceencaps = no';
637
				else if ($ph1ent['nat_traversal'] == 'force')
638
					$forceencaps = 'forceencaps = yes';
639
				else
640
					$forceencaps = 'forceencaps = no';
641

    
642
				$ipseclifetime = 0;
643
				$rightsubnet_spec = array();
644
				$leftsubnet_spec = array();
645
				$ealgoAHsp2arr = array();
646
				$ealgoESPsp2arr = array();
647
			if (is_array($a_phase2) && count($a_phase2)) {
648
				foreach ($a_phase2 as $ph2ent) {
649
					if ($ikeid != $ph2ent['ikeid'])
650
						continue;
651

    
652
					if (isset($ph2ent['disabled']))
653
						continue;
654

    
655
					if (isset($ph2ent['mobile']) && !isset($a_client['enable']))
656
						continue;
657

    
658
					if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
659
						$tunneltype = "type = tunnel";
660

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

    
689
						if (empty($leftsubnet_spec[$leftsubnet_data]))
690
							$leftsubnet_spec[$leftsubnet_data] = $leftsubnet_data;
691

    
692
						if (!isset($ph2ent['mobile'])) {
693
							$tmpsubnet = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']);
694
							if (empty($rightsubnet_spec[$tmpsubnet]))
695
								$rightsubnet_spec[$tmpsubnet] = $tmpsubnet;
696
						} else if (!empty($a_client['pool_address'])) {
697
							if (empty($rightsubnet_spec["{$a_client['pool_address']}/{$a_client['pool_netbits']}"]))
698
								$rightsubnet_spec["{$a_client['pool_address']}/{$a_client['pool_netbits']}"] = "{$a_client['pool_address']}/{$a_client['pool_netbits']}";
699
						}
700
					} else {
701
						$tunneltype = "type = transport";
702

    
703
						if ((($ph1ent['authentication_method'] == "xauth_psk_server") ||
704
						    ($ph1ent['authentication_method'] == "pre_shared_key")) && isset($ph1ent['mobile'])) {
705
							$left_spec = "%any";
706
						} else {
707
							$tmpsubnet = ipsec_get_phase1_src($ph1ent);
708
							if ($leftsubnet_spec[$tmpsubnet])
709
								$leftsubnet_spec[$tmpsubnet] = $tmpsubnet;
710
						}
711

    
712
						if (!isset($ph2ent['mobile'])) {
713
							if (empty($rightsubnet_spec[$right_spec]))
714
								$rightsubnet_spec[$right_spec] = $right_spec;
715
						}
716
					}
717

    
718
					if (isset($a_client['pfs_group']))
719
						$ph2ent['pfsgroup'] = $a_client['pfs_group'];
720

    
721
					if ($ph2ent['protocol'] == 'esp') {
722
						if (is_array($ph2ent['encryption-algorithm-option'])) {
723
							foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
724
								$ealg_id = $ealg['name'];
725
								$ealg_kl = $ealg['keylen'];
726

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

    
788

    
789
					if (!empty($ph2ent['lifetime'])) {
790
						if ($ipseclifetime == 0 || intval($ipseclifetime) > intval($ph2ent['lifetime']))
791
							$ipseclifetime = intval($ph2ent['lifetime']);
792
					}
793

    
794
				}
795
			}
796

    
797
					$ipsecconf .=<<<EOD
798

    
799
conn con{$ph1ent['ikeid']}
800
	aggressive = {$aggressive}
801
	fragmentation = yes
802
	keyexchange = {$keyexchange}
803
	{$reauth}
804
	{$forceencaps}
805
	{$rekey}
806
	reqid = {$ikeid}
807
	installpolicy = yes
808
	{$tunneltype}
809
	{$dpdline}
810
	auto = {$passive}
811
	left = {$left_spec}
812
	right = {$right_spec}
813
	leftid = {$myid_data}
814

    
815
EOD;
816

    
817
					if (!empty($ikelifeline))
818
						$ipsecconf .= "\t{$ikelifeline}\n";
819
					if ($ipseclifetime > 0)
820
						$ipsecconf .= "\tlifetime = {$ipseclifetime}s\n";
821
					if (!empty($rightsourceip))
822
						$ipsecconf .= "{$rightsourceip}";
823
					if (!empty($rightsubnet_spec))
824
						$ipsecconf .= "\trightsubnet = " . join(",", $rightsubnet_spec) . "\n";
825
					if (!empty($leftsubnet_spec))
826
						$ipsecconf .= "\tleftsubnet = " . join(",", $leftsubnet_spec) . "\n";
827
					if (!empty($ealgosp1))
828
						$ipsecconf .= "\t{$ealgosp1}\n";
829
					if (!empty($ealgoAHsp2arr))
830
						$ipsecconf .= "\tah = " . join(',', $ealgoAHsp2arr) . "!\n";
831
					if (!empty($ealgoESPsp2arr))
832
						$ipsecconf .= "\tesp = " . join(',', $ealgoESPsp2arr) . "!\n";
833
					if (!empty($authentication))
834
						$ipsecconf .= "\t{$authentication}\n";
835
					if (!empty($peerid_spec))
836
						$ipsecconf .= "\trightid = {$peerid_spec}\n";
837
			}
838
		}
839
	}
840
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.conf", $ipsecconf);
841
	unset($ipsecconf);
842
	/* end ipsec.conf */
843

    
844
	/* mange process */
845
	if (isvalidpid("{$g['varrun_path']}/charon.pid")) {
846
		/* Read secrets */
847
		mwexec("/usr/local/sbin/ipsec rereadall", false);
848
		/* Update configuration changes */
849
		mwexec("/usr/local/sbin/ipsec update", false);
850
		mwexec("/usr/local/sbin/ipsec reload", false);
851
	} else {
852
		mwexec("/usr/local/sbin/ipsec start", false); 
853
	}
854

    
855
	if ($natfilterrules == true)
856
		filter_configure();
857
	/* start filterdns, if necessary */
858
	if (count($filterdns_list) > 0) {
859
		$interval = 60;
860
		if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval']))
861
			$interval = $ipseccfg['dns-interval'];
862

    
863
		$hostnames = "";
864
		array_unique($filterdns_list);
865
		foreach ($filterdns_list as $hostname)
866
			$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload ipsecdns\"'\n";
867
		file_put_contents("{$g['varetc_path']}/ipsec/filterdns-ipsec.hosts", $hostnames);
868
		unset($hostnames);
869

    
870
		if (isvalidpid("{$g['varrun_path']}/filterdns-ipsec.pid"))
871
			sigkillbypid("{$g['varrun_path']}/filterdns-ipsec.pid", "HUP");
872
		else {
873
			mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/ipsec/filterdns-ipsec.hosts -d 1");
874
		}
875
	} else {
876
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
877
		@unlink("{$g['varrun_path']}/filterdns-ipsec.pid");
878
	}
879

    
880
	if ($g['booting'])
881
		echo "done\n";
882

    
883
	return count($filterdns_list);
884
}
885

    
886
/*
887
 * Forcefully restart IPsec
888
 * This is required for when dynamic interfaces reload
889
 * For all other occasions the normal vpn_ipsec_configure()
890
 * will gracefully reload the settings without restarting
891
 */
892
function vpn_ipsec_force_reload($interface = "") {
893
	global $g, $config;
894

    
895
	$ipseccfg = $config['ipsec'];
896

    
897
	if (!empty($interface) && is_array($ipseccfg['phase1'])) {
898
		$found = false;
899
		foreach ($ipseccfg['phase1'] as $ipsec) {
900
			if (!isset($ipsec['disabled']) && ($ipsec['interface'] == $interface)) {
901
				$found = true;
902
				break;
903
			}
904
		}
905
		if (!$found) {
906
			log_error(sprintf(gettext("Ignoring IPsec reload since there are no tunnels on interface %s"), $interface));
907
			return;
908
		}
909
	}
910

    
911
	/* if ipsec is enabled, start up again */
912
	if (isset($ipseccfg['enable'])) {
913
		log_error(gettext("Forcefully reloading IPsec"));
914
		vpn_ipsec_configure();
915
	}
916
}
917

    
918
/* master setup for vpn (mpd) */
919
function vpn_setup() {
920
	global $g;
921

    
922
	if ($g['platform'] == 'jail')
923
		return;
924

    
925
	/* start pptpd */
926
	vpn_pptpd_configure();
927

    
928
	/* start pppoe server */
929
	vpn_pppoes_configure();
930

    
931
	/* setup l2tp */
932
	vpn_l2tp_configure();
933
}
934

    
935
function vpn_netgraph_support() {
936
	$iflist = get_configured_interface_list();
937
	foreach ($iflist as $iface) {
938
		$realif = get_real_interface($iface);
939
		/* Get support for netgraph(4) from the nic */
940
		$ifinfo = pfSense_get_interface_addresses($realif);
941
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge")))
942
			pfSense_ngctl_attach(".", $realif);
943
	}
944
}
945

    
946
function vpn_pptpd_configure() {
947
	global $config, $g;
948

    
949
	$syscfg = $config['system'];
950
	$pptpdcfg = $config['pptpd'];
951

    
952
	if ($g['booting']) {
953
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
954
			return 0;
955

    
956
		echo gettext("Configuring PPTP VPN service... ");
957
	} else {
958
		/* kill mpd */
959
		killbypid("{$g['varrun_path']}/pptp-vpn.pid");
960

    
961
		/* wait for process to die */
962
		sleep(3);
963

    
964
		if (is_process_running("mpd -b")) {
965
			killbypid("{$g['varrun_path']}/pptp-vpn.pid");
966
			log_error(gettext("Could not kill mpd within 3 seconds.   Trying again."));
967
		}
968

    
969
		/* remove mpd.conf, if it exists */
970
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.conf");
971
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.links");
972
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.secret");
973
	}
974

    
975
	if (empty($pptpdcfg['n_pptp_units'])) {
976
		log_error("Something wrong in the PPTPd configuration. Preventing starting the daemon because issues would arise.");
977
		return;
978
	}
979

    
980
	/* make sure pptp-vpn directory exists */
981
	if (!file_exists("{$g['varetc_path']}/pptp-vpn"))
982
		mkdir("{$g['varetc_path']}/pptp-vpn");
983

    
984
	switch ($pptpdcfg['mode']) {
985
		case 'server' :
986
			/* write mpd.conf */
987
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.conf", "w");
988
			if (!$fd) {
989
				printf(gettext("Error: cannot open mpd.conf in vpn_pptpd_configure().") . "\n");
990
				return 1;
991
			}
992

    
993
			$mpdconf = <<<EOD
994
pptps:
995

    
996
EOD;
997

    
998
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
999
				$mpdconf .= "	load pt{$i}\n";
1000
			}
1001

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

    
1004
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
1005

    
1006
				$mpdconf .= <<<EOD
1007

    
1008
pt{$i}:
1009
	new -i pptpd{$i} pt{$i} pt{$i}
1010
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
1011
	load pts
1012

    
1013
EOD;
1014
			}
1015

    
1016
			$mpdconf .=<<<EOD
1017

    
1018
pts:
1019
	set iface disable on-demand
1020
	set iface enable proxy-arp
1021
	set iface enable tcpmssfix
1022
	set iface idle 1800
1023
	set iface up-script /usr/local/sbin/vpn-linkup
1024
	set iface down-script /usr/local/sbin/vpn-linkdown
1025
	set bundle enable multilink
1026
	set bundle enable crypt-reqd
1027
	set link yes acfcomp protocomp
1028
	set link no pap chap
1029
	set link enable chap-msv2
1030
	set link mtu 1460
1031
	set link keep-alive 10 60
1032
	set ipcp yes vjcomp
1033
	set bundle enable compression
1034
	set ccp yes mppc
1035
	set ccp yes mpp-e128
1036
	set ccp yes mpp-stateless
1037

    
1038
EOD;
1039

    
1040
			if (!isset ($pptpdcfg['req128'])) {
1041
				$mpdconf .=<<<EOD
1042
	set ccp yes mpp-e40
1043
	set ccp yes mpp-e56
1044

    
1045
EOD;
1046
			}
1047

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

    
1051
			if (!empty($pptpdcfg['dns1'])) {
1052
				$mpdconf .= "	set ipcp dns " . $pptpdcfg['dns1'];
1053
				if (!empty($pptpdcfg['dns2']))
1054
					$mpdconf .= " " . $pptpdcfg['dns2'];
1055
				$mpdconf .= "\n";
1056
			} elseif (isset ($config['dnsmasq']['enable'])) {
1057
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1058
				if ($syscfg['dnsserver'][0])
1059
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1060
				$mpdconf .= "\n";
1061
			} elseif (isset($config['unbound']['enable'])) {
1062
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1063
				if ($syscfg['dnsserver'][0])
1064
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1065
				$mpdconf .= "\n";
1066
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1067
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1068
			}
1069

    
1070
			if (isset ($pptpdcfg['radius']['server']['enable'])) {
1071
				$authport = (isset($pptpdcfg['radius']['server']['port']) && strlen($pptpdcfg['radius']['server']['port']) > 1) ? $pptpdcfg['radius']['server']['port'] : 1812;
1072
				$acctport = $authport + 1;
1073
				$mpdconf .=<<<EOD
1074
	set radius server {$pptpdcfg['radius']['server']['ip']} "{$pptpdcfg['radius']['server']['secret']}" {$authport} {$acctport}
1075

    
1076
EOD;
1077
			if (isset ($pptpdcfg['radius']['server2']['enable'])) {
1078
				$authport = (isset($pptpdcfg['radius']['server2']['port']) && strlen($pptpdcfg['radius']['server2']['port']) > 1) ? $pptpdcfg['radius']['server2']['port'] : 1812;
1079
				$acctport = $authport + 1;
1080
				$mpdconf .=<<<EOD
1081
	set radius server {$pptpdcfg['radius']['server2']['ip']} "{$pptpdcfg['radius']['server2']['secret2']}" {$authport} {$acctport}
1082

    
1083
EOD;
1084
			}
1085
			$mpdconf .=<<<EOD
1086
	set radius retries 3
1087
	set radius timeout 10
1088
	set auth enable radius-auth
1089

    
1090
EOD;
1091

    
1092
				if (isset ($pptpdcfg['radius']['accounting'])) {
1093
					$mpdconf .=<<<EOD
1094
	set auth enable radius-acct
1095
	set radius acct-update 300
1096

    
1097
EOD;
1098
				}
1099
			}
1100

    
1101
			fwrite($fd, $mpdconf);
1102
			fclose($fd);
1103
			unset($mpdconf);
1104

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

    
1112
			$mpdlinks = "";
1113

    
1114
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1115
				$mpdlinks .=<<<EOD
1116

    
1117
pt{$i}:
1118
	set link type pptp
1119
	set pptp enable incoming
1120
	set pptp disable originate
1121
	set pptp disable windowing
1122

    
1123
EOD;
1124
			}
1125

    
1126
			fwrite($fd, $mpdlinks);
1127
			fclose($fd);
1128
			unset($mpdlinks);
1129

    
1130
			/* write mpd.secret */
1131
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.secret", "w");
1132
			if (!$fd) {
1133
				printf(gettext("Error: cannot open mpd.secret in vpn_pptpd_configure().") . "\n");
1134
				return 1;
1135
			}
1136

    
1137
			$mpdsecret = "";
1138

    
1139
			if (is_array($pptpdcfg['user'])) {
1140
				foreach ($pptpdcfg['user'] as $user) {
1141
					$pass = str_replace('\\', '\\\\', $user['password']);
1142
					$pass = str_replace('"', '\"', $pass);
1143
					$mpdsecret .= "{$user['name']} \"{$pass}\" {$user['ip']}\n";
1144
				}
1145
			}
1146

    
1147
			fwrite($fd, $mpdsecret);
1148
			fclose($fd);
1149
			unset($mpdsecret);
1150
			chmod("{$g['varetc_path']}/pptp-vpn/mpd.secret", 0600);
1151

    
1152
			vpn_netgraph_support();
1153

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

    
1157
			break;
1158

    
1159
		case 'redir' :
1160
			break;
1161
	}
1162

    
1163
	if ($g['booting'])
1164
		echo "done\n";
1165

    
1166
	return 0;
1167
}
1168

    
1169
function vpn_pppoes_configure() {
1170
	global $config;
1171

    
1172
	if (is_array($config['pppoes']['pppoe'])) {
1173
		foreach ($config['pppoes']['pppoe'] as $pppoe)
1174
			vpn_pppoe_configure($pppoe);
1175
	}
1176
}
1177

    
1178
function vpn_pppoe_configure(&$pppoecfg) {
1179
	global $config, $g;
1180

    
1181
	$syscfg = $config['system'];
1182

    
1183
	/* create directory if it does not exist */
1184
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn"))
1185
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1186

    
1187
	if ($g['booting']) {
1188
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
1189
			return 0;
1190

    
1191
		echo gettext("Configuring PPPoE Server service... ");
1192
	} else {
1193
		/* kill mpd */
1194
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1195

    
1196
		/* wait for process to die */
1197
		sleep(2);
1198

    
1199
	}
1200

    
1201
	switch ($pppoecfg['mode']) {
1202

    
1203
		case 'server' :
1204

    
1205
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1206

    
1207
			if ($pppoecfg['paporchap'] == "chap")
1208
				$paporchap = "set link enable chap";
1209
			else
1210
				$paporchap = "set link enable pap";
1211

    
1212
			/* write mpd.conf */
1213
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1214
			if (!$fd) {
1215
				printf(gettext("Error: cannot open mpd.conf in vpn_pppoe_configure().") . "\n");
1216
				return 1;
1217
			}
1218
			$mpdconf = "\n\n";
1219
			$mpdconf .= "poes:\n";
1220

    
1221
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1222
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1223
			}
1224

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

    
1227
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1228

    
1229
				if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1230
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1231
				} else {
1232
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1233
				}
1234

    
1235
				$mpdconf .=<<<EOD
1236

    
1237
poes{$pppoecfg['pppoeid']}{$i}:
1238
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1239
	{$isssue_ip_type}
1240
	load pppoe_standard
1241

    
1242
EOD;
1243
			}
1244

    
1245
			$mpdconf .=<<<EOD
1246

    
1247
pppoe_standard:
1248
	set bundle no multilink
1249
	set bundle enable compression
1250
	set auth max-logins 1
1251
	set iface up-script /usr/local/sbin/vpn-linkup
1252
	set iface down-script /usr/local/sbin/vpn-linkdown
1253
	set iface idle 0
1254
	set iface disable on-demand
1255
	set iface disable proxy-arp
1256
	set iface enable tcpmssfix
1257
	set iface mtu 1500
1258
	set link no pap chap
1259
	{$paporchap}
1260
	set link keep-alive 60 180
1261
	set ipcp yes vjcomp
1262
	set ipcp no vjcomp
1263
	set link max-redial -1
1264
	set link mtu 1492
1265
	set link mru 1492
1266
	set ccp yes mpp-e40
1267
	set ccp yes mpp-e128
1268
	set ccp yes mpp-stateless
1269
	set link latency 1
1270
	#set ipcp dns 10.10.1.3
1271
	#set bundle accept encryption
1272

    
1273
EOD;
1274

    
1275
			if (!empty($pppoecfg['dns1'])) {
1276
				$mpdconf .= "	set ipcp dns " . $pppoecfg['dns1'];
1277
				if (!empty($pppoecfg['dns2']))
1278
					$mpdconf .= " " . $pppoecfg['dns2'];
1279
				$mpdconf .= "\n";
1280
			} elseif (isset ($config['dnsmasq']['enable'])) {
1281
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1282
				if ($syscfg['dnsserver'][0])
1283
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1284
				$mpdconf .= "\n";
1285
			} elseif (isset ($config['unbound']['enable'])) {
1286
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1287
				if ($syscfg['dnsserver'][0])
1288
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1289
				$mpdconf .= "\n";
1290
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1291
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1292
			}
1293

    
1294
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1295
				$radiusport = "";
1296
				$radiusacctport = "";
1297
				if (isset($pppoecfg['radius']['server']['port']))
1298
					$radiusport = $pppoecfg['radius']['server']['port'];
1299
				if (isset($pppoecfg['radius']['server']['acctport']))
1300
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1301
				$mpdconf .=<<<EOD
1302
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
1303
	set radius retries 3
1304
	set radius timeout 10
1305
	set auth enable radius-auth
1306

    
1307
EOD;
1308

    
1309
				if (isset ($pppoecfg['radius']['accounting'])) {
1310
					$mpdconf .=<<<EOD
1311
	set auth enable radius-acct
1312

    
1313
EOD;
1314
				}
1315
			}
1316

    
1317
			fwrite($fd, $mpdconf);
1318
			fclose($fd);
1319
			unset($mpdconf);
1320

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

    
1328
			$mpdlinks = "";
1329

    
1330
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1331
				$mpdlinks .=<<<EOD
1332

    
1333
poes{$pppoecfg['pppoeid']}{$i}:
1334
	set phys type pppoe
1335
	set pppoe iface {$pppoe_interface}
1336
	set pppoe service "*"
1337
	set pppoe disable originate
1338
	set pppoe enable incoming
1339

    
1340
EOD;
1341
			}
1342

    
1343
			fwrite($fd, $mpdlinks);
1344
			fclose($fd);
1345
			unset($mpdlinks);
1346

    
1347
			if ($pppoecfg['username']) {
1348
				/* write mpd.secret */
1349
				$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", "w");
1350
				if (!$fd) {
1351
					printf(gettext("Error: cannot open mpd.secret in vpn_pppoe_configure().") . "\n");
1352
					return 1;
1353
				}
1354

    
1355
				$mpdsecret = "\n\n";
1356

    
1357
				if (!empty($pppoecfg['username'])) {
1358
					$item = explode(" ", $pppoecfg['username']);
1359
					foreach($item as $userdata) {
1360
						$data = explode(":", $userdata);
1361
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1362
					}
1363
				}
1364

    
1365
				fwrite($fd, $mpdsecret);
1366
				fclose($fd);
1367
				unset($mpdsecret);
1368
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1369
			}
1370

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

    
1375
			/* Get support for netgraph(4) from the nic */
1376
			pfSense_ngctl_attach(".", $pppoe_interface);
1377
			/* fire up mpd */
1378
			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");
1379

    
1380
			break;
1381
	}
1382

    
1383
	if ($g['booting'])
1384
		echo gettext("done") . "\n";
1385

    
1386
	return 0;
1387
}
1388

    
1389
function vpn_l2tp_configure() {
1390
	global $config, $g;
1391

    
1392
	$syscfg = $config['system'];
1393
	$l2tpcfg = $config['l2tp'];
1394

    
1395
	/* create directory if it does not exist */
1396
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn"))
1397
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1398

    
1399
	if ($g['booting']) {
1400
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off"))
1401
			return 0;
1402

    
1403
		echo gettext("Configuring l2tp VPN service... ");
1404
	} else {
1405
		/* kill mpd */
1406
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1407

    
1408
		/* wait for process to die */
1409
		sleep(8);
1410

    
1411
	}
1412

    
1413
	/* make sure l2tp-vpn directory exists */
1414
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn"))
1415
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1416

    
1417
	switch ($l2tpcfg['mode']) {
1418

    
1419
		case 'server' :
1420
			if ($l2tpcfg['paporchap'] == "chap")
1421
				$paporchap = "set link enable chap";
1422
			else
1423
				$paporchap = "set link enable pap";
1424

    
1425
			/* write mpd.conf */
1426
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1427
			if (!$fd) {
1428
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
1429
				return 1;
1430
			}
1431
			$mpdconf = "\n\n";
1432
			$mpdconf .=<<<EOD
1433
l2tps:
1434

    
1435
EOD;
1436

    
1437
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1438
				$mpdconf .= "	load l2tp{$i}\n";
1439
			}
1440

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

    
1443
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1444

    
1445
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1446
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1447
				} else {
1448
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1449
				}
1450

    
1451
				$mpdconf .=<<<EOD
1452

    
1453
l2tp{$i}:
1454
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1455
	{$isssue_ip_type}
1456
	load l2tp_standard
1457

    
1458
EOD;
1459
			}
1460

    
1461
			$mpdconf .=<<<EOD
1462

    
1463
l2tp_standard:
1464
	set bundle disable multilink
1465
	set bundle enable compression
1466
	set bundle yes crypt-reqd
1467
	set ipcp yes vjcomp
1468
	# set ipcp ranges 131.188.69.161/32 131.188.69.170/28
1469
	set ccp yes mppc
1470
	set iface disable on-demand
1471
	set iface enable proxy-arp
1472
	set iface up-script /usr/local/sbin/vpn-linkup
1473
	set iface down-script /usr/local/sbin/vpn-linkdown
1474
	set link yes acfcomp protocomp
1475
	set link no pap chap
1476
	set link enable chap
1477
	set link keep-alive 10 180
1478

    
1479
EOD;
1480

    
1481
			if (is_ipaddr($l2tpcfg['wins'])) {
1482
				$mpdconf .= "	set ipcp nbns {$l2tpcfg['wins']}\n";
1483
			}
1484
			if (is_ipaddr($l2tpcfg['dns1'])) {
1485
				$mpdconf .= "	set ipcp dns " . $l2tpcfg['dns1'];
1486
				if (is_ipaddr($l2tpcfg['dns2']))
1487
					$mpdconf .= " " . $l2tpcfg['dns2'];
1488
				$mpdconf .= "\n";
1489
			} elseif (isset ($config['dnsmasq']['enable'])) {
1490
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1491
				if ($syscfg['dnsserver'][0])
1492
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1493
				$mpdconf .= "\n";
1494
			} elseif (isset ($config['unbound']['enable'])) {
1495
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1496
				if ($syscfg['dnsserver'][0])
1497
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1498
				$mpdconf .= "\n";
1499
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1500
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1501
			}
1502

    
1503
			if (isset ($l2tpcfg['radius']['enable'])) {
1504
				$mpdconf .=<<<EOD
1505
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1506
	set radius retries 3
1507
	set radius timeout 10
1508
	set auth enable radius-auth
1509

    
1510
EOD;
1511

    
1512
				if (isset ($l2tpcfg['radius']['accounting'])) {
1513
					$mpdconf .=<<<EOD
1514
	set auth enable radius-acct
1515

    
1516
EOD;
1517
				}
1518
			}
1519

    
1520
			fwrite($fd, $mpdconf);
1521
			fclose($fd);
1522
			unset($mpdconf);
1523

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

    
1531
			$mpdlinks = "";
1532

    
1533
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1534
				$mpdlinks .=<<<EOD
1535

    
1536
l2tp{$i}:
1537
	set link type l2tp
1538
	set l2tp enable incoming
1539
	set l2tp disable originate
1540

    
1541
EOD;
1542
			if (!empty($l2tpcfg['secret']))
1543
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
1544
			}
1545

    
1546
			fwrite($fd, $mpdlinks);
1547
			fclose($fd);
1548
			unset($mpdlinks);
1549

    
1550
			/* write mpd.secret */
1551
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.secret", "w");
1552
			if (!$fd) {
1553
				printf(gettext("Error: cannot open mpd.secret in vpn_l2tp_configure().") . "\n");
1554
				return 1;
1555
			}
1556

    
1557
			$mpdsecret = "\n\n";
1558

    
1559
			if (is_array($l2tpcfg['user'])) {
1560
				foreach ($l2tpcfg['user'] as $user)
1561
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1562
			}
1563

    
1564
			fwrite($fd, $mpdsecret);
1565
			fclose($fd);
1566
			unset($mpdsecret);
1567
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
1568

    
1569
			vpn_netgraph_support();
1570

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

    
1574
			break;
1575

    
1576
		case 'redir' :
1577
			break;
1578
	}
1579

    
1580
	if ($g['booting'])
1581
		echo "done\n";
1582

    
1583
	return 0;
1584
}
1585

    
1586
function vpn_ipsec_configure_preferoldsa() {
1587
	global $config;
1588
	if(isset($config['ipsec']['preferoldsa']))
1589
		set_single_sysctl("net.key.preferred_oldsa", "-30");
1590
	else
1591
		set_single_sysctl("net.key.preferred_oldsa", "0");
1592
}
1593

    
1594
?>
(59-59/68)