Projet

Général

Profil

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

univnautes / etc / inc / vpn.inc @ 3b9ef0ef

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
		$strongswan = <<<EOD
276

    
277
#Automatically generated please do not modify
278
starter {
279
    load_warning = no
280
}
281

    
282
charon {
283

    
284
        # number of worker threads in charon
285
        threads = 16
286
	ikesa_table_size = 32
287
	ikesa_table_segments = 4
288
	init_limit_half_open = 1000;
289

    
290
	# XXX: There is not much choice here really users win their security!
291
	i_dont_care_about_security_and_use_aggressive_mode_psk=yes
292

    
293
	# And two loggers using syslog. The subsections define the facility to log
294
	# to, currently one of: daemon, auth.
295
	syslog {
296

    
297
		identifier = charon
298
		# default level to the LOG_DAEMON facility
299
		daemon {
300
		}
301
		# very minimalistic IKE auditing logs to LOG_AUTHPRIV
302
		auth {
303
		    default = -1
304
		    ike = 1
305
		    ike_name = yes
306
		}
307
	}
308

    
309
EOD;
310

    
311
		if (is_array($a_client) && isset($a_client['enable']) && isset($a_client['net_list']))
312
			$strongswan .= "\tcisco_unity = yes\n";
313

    
314
		$strongswan .= "\tplugins {\n";
315

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

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

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

    
343
			if (isset($a_client['net_list'])) {
344
				$net_list = '';
345
				foreach ($a_phase2 as $ph2ent) {
346
					if (isset($ph2ent['disabled']))
347
						continue;
348

    
349
					if (!isset($ph2ent['mobile']))
350
						continue;
351

    
352
					$localid = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
353

    
354
					if (!empty($net_list))
355
						$net_list .= ",";
356
					$net_list .= $localid;
357
				}
358

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

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

    
373
			if (!empty($a_client['dns_split'])) {
374
				$strongswan .= "\t\t28675 = {$a_client['dns_split']}\n";
375
			}
376

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

    
380
			if (isset($a_client['save_passwd']))
381
				$strongswan .= "\t\t28673 = yes\n";
382

    
383
			if ($a_client['pfs_group'])
384
				$strongswan .= "\t\t28679 = {$a_client['pfs_group']}\n";
385
			$strongswan .= "\t\t}\n";
386

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

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

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

    
432
		$pskconf = "";
433

    
434
		if (is_array($a_phase1) && count($a_phase1)) {
435
			foreach ($a_phase1 as $ph1ent) {
436

    
437
				if (isset($ph1ent['disabled']))
438
					continue;
439

    
440
				if (strpos($ph1ent['authentication_method'], 'rsa') || $ph1ent['authentication_method'] == 'eap-tls') {
441
					$certline = '';
442

    
443
					$ikeid = $ph1ent['ikeid'];
444
					$cert = lookup_cert($ph1ent['certref']);
445

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

    
451
					@chmod($certpath, 0600);
452

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

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

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

    
474
					if (empty($peerid_data))
475
						continue;
476

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

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

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

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

    
509
		$natfilterrules = false;
510
		/* begin ipsec.conf */
511
		$ipsecconf = "";
512
		if (is_array($a_phase1) && count($a_phase1))  {
513

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

    
518
			foreach ($a_phase1 as $ph1ent) {
519
				if (isset($ph1ent['disabled']))
520
					continue;
521

    
522
				if ($ph1ent['mode'] == "aggressive")
523
					$aggressive = "yes";
524
				else
525
					$aggressive = "no";
526

    
527
				$ep = ipsec_get_phase1_src($ph1ent);
528
				if (!$ep)
529
					continue;
530

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

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

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

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

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

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

    
567
					$ealgosp1 .= "!";
568
				}
569

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

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

    
585
				$rightsourceip = NULL;
586
				if (!empty($a_client['pool_address'])) 
587
					$rightsourceip = "\trightsourceip = {$a_client['pool_address']}/{$a_client['pool_netbits']}\n";
588

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

    
616
				$left_spec = $ep;
617

    
618
				if (isset($ph1ent['reauth_enable']))
619
					$reauth = "reauth = no";
620
				else
621
					$reauth = "reauth = yes";
622
				if (isset($ph1ent['rekey_enable']))
623
					$rekey = "rekey = no";
624
				else
625
					$rekey = "rekey = yes";
626

    
627
				$ipseclifetime = 0;
628
				$rightsubnet_spec = array();
629
				$leftsubnet_spec = array();
630
				$ealgoAHsp2arr = array();
631
				$ealgoESPsp2arr = array();
632
			if (is_array($a_phase2) && count($a_phase2)) {
633
				foreach ($a_phase2 as $ph2ent) {
634
					if ($ikeid != $ph2ent['ikeid'])
635
						continue;
636

    
637
					if (isset($ph2ent['disabled']))
638
						continue;
639

    
640
					if (isset($ph2ent['mobile']) && !isset($a_client['enable']))
641
						continue;
642

    
643
					if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
644
						$tunneltype = "type = tunnel";
645

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

    
674
						if (empty($leftsubnet_spec[$leftsubnet_data]))
675
							$leftsubnet_spec[$leftsubnet_data] = $leftsubnet_data;
676

    
677
						if (!isset($ph2ent['mobile'])) {
678
							$tmpsubnet = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']);
679
							if (empty($rightsubnet_spec[$tmpsubnet]))
680
								$rightsubnet_spec[$tmpsubnet] = $tmpsubnet;
681
						} else if (!empty($a_client['pool_address'])) {
682
							if (empty($rightsubnet_spec["{$a_client['pool_address']}/{$a_client['pool_netbits']}"]))
683
								$rightsubnet_spec["{$a_client['pool_address']}/{$a_client['pool_netbits']}"] = "{$a_client['pool_address']}/{$a_client['pool_netbits']}";
684
						}
685
					} else {
686
						$tunneltype = "type = transport";
687

    
688
						if ((($ph1ent['authentication_method'] == "xauth_psk_server") ||
689
						    ($ph1ent['authentication_method'] == "pre_shared_key")) && isset($ph1ent['mobile'])) {
690
							$left_spec = "%any";
691
						} else {
692
							$tmpsubnet = ipsec_get_phase1_src($ph1ent);
693
							if ($leftsubnet_spec[$tmpsubnet])
694
								$leftsubnet_spec[$tmpsubnet] = $tmpsubnet;
695
						}
696

    
697
						if (!isset($ph2ent['mobile'])) {
698
							if (empty($rightsubnet_spec[$right_spec]))
699
								$rightsubnet_spec[$right_spec] = $right_spec;
700
						}
701
					}
702

    
703
					if (isset($a_client['pfs_group']))
704
						$ph2ent['pfsgroup'] = $a_client['pfs_group'];
705

    
706
					if ($ph2ent['protocol'] == 'esp') {
707
						if (is_array($ph2ent['encryption-algorithm-option'])) {
708
							foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
709
								$ealg_id = $ealg['name'];
710
								$ealg_kl = $ealg['keylen'];
711

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

    
773

    
774
					if (!empty($ph2ent['lifetime'])) {
775
						if ($ipseclifetime == 0 || intval($ipseclifetime) > intval($ph2ent['lifetime']))
776
							$ipseclifetime = intval($ph2ent['lifetime']);
777
					}
778
				}
779
			}
780

    
781
				$ipsecconf .=<<<EOD
782

    
783
conn con{$ph1ent['ikeid']}
784
	aggressive = {$aggressive}
785
	fragmentation = yes
786
	keyexchange = {$keyexchange}
787
	{$reauth}
788
	{$rekey}
789
	reqid = {$ikeid}
790
	installpolicy = yes
791
	{$tunneltype}
792
	{$dpdline}
793
	auto = {$passive}
794
	left = {$left_spec}
795
	right = {$right_spec}
796
	leftid = {$myid_data}
797

    
798
EOD;
799

    
800
				if (!empty($ikelifeline))
801
					$ipsecconf .= "\t{$ikelifeline}\n";
802
				if ($ipseclifetime > 0)
803
					$ipsecconf .= "\tlifetime = {$ipseclifetime}s\n";
804
				if (!empty($rightsourceip))
805
					$ipsecconf .= "{$rightsourceip}";
806
				if (!empty($rightsubnet_spec))
807
					$ipsecconf .= "\trightsubnet = " . join(",", $rightsubnet_spec) . "\n";
808
				if (!empty($leftsubnet_spec))
809
					$ipsecconf .= "\tleftsubnet = " . join(",", $leftsubnet_spec) . "\n";
810
				if (!empty($ealgosp1))
811
					$ipsecconf .= "\t{$ealgosp1}\n";
812
				if (!empty($ealgoAHsp2arr))
813
					$ipsecconf .= "\tah = " . join(',', $ealgoAHsp2arr) . "!\n";
814
				if (!empty($ealgoESPsp2arr)) {
815
					file_put_contents("/var/etc/ipsec/dump_test", print_r($ealgoESPsp2arr, true));
816
					$ipsecconf .= "\tesp = " . join(',', $ealgoESPsp2arr) . "!\n";
817
				}
818
				if (!empty($authentication))
819
					$ipsecconf .= "\t{$authentication}\n";
820
				if (!empty($peerid_spec))
821
					$ipsecconf .= "\trightid = {$peerid_spec}\n";
822
			}
823
		}
824
	}
825
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.conf", $ipsecconf);
826
	unset($ipsecconf);
827
	/* end ipsec.conf */
828

    
829
	/* mange process */
830
	if (isvalidpid("{$g['varrun_path']}/charon.pid")) {
831
		/* Read secrets */
832
		mwexec("/usr/local/sbin/ipsec rereadall", false);
833
		/* Update configuration changes */
834
		mwexec("/usr/local/sbin/ipsec reload", false);
835
	} else {
836
		mwexec("/usr/local/sbin/ipsec start", false); 
837
	}
838

    
839
	if ($natfilterrules == true)
840
		filter_configure();
841
	/* start filterdns, if necessary */
842
	if (count($filterdns_list) > 0) {
843
		$interval = 60;
844
		if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval']))
845
			$interval = $ipseccfg['dns-interval'];
846

    
847
		$hostnames = "";
848
		array_unique($filterdns_list);
849
		foreach ($filterdns_list as $hostname)
850
			$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload ipsecdns\"'\n";
851
		file_put_contents("{$g['varetc_path']}/ipsec/filterdns-ipsec.hosts", $hostnames);
852
		unset($hostnames);
853

    
854
		if (isvalidpid("{$g['varrun_path']}/filterdns-ipsec.pid"))
855
			sigkillbypid("{$g['varrun_path']}/filterdns-ipsec.pid", "HUP");
856
		else {
857
			mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-ipsec.pid -i {$interval} -c {$g['varetc_path']}/ipsec/filterdns-ipsec.hosts -d 1");
858
		}
859
	} else {
860
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
861
		@unlink("{$g['varrun_path']}/filterdns-ipsec.pid");
862
	}
863

    
864
	if ($g['booting'])
865
		echo "done\n";
866

    
867
	return count($filterdns_list);
868
}
869

    
870
/*
871
 * Forcefully restart IPsec
872
 * This is required for when dynamic interfaces reload
873
 * For all other occasions the normal vpn_ipsec_configure()
874
 * will gracefully reload the settings without restarting
875
 */
876
function vpn_ipsec_force_reload($interface = "") {
877
	global $g, $config;
878

    
879
	$ipseccfg = $config['ipsec'];
880

    
881
	if (!empty($interface) && is_array($ipseccfg['phase1'])) {
882
		$found = false;
883
		foreach ($ipseccfg['phase1'] as $ipsec) {
884
			if (!isset($ipsec['disabled']) && ($ipsec['interface'] == $interface)) {
885
				$found = true;
886
				break;
887
			}
888
		}
889
		if (!$found) {
890
			log_error(sprintf(gettext("Ignoring IPsec reload since there are no tunnels on interface %s"), $interface));
891
			return;
892
		}
893
	}
894

    
895
	/* if ipsec is enabled, start up again */
896
	if (isset($ipseccfg['enable'])) {
897
		log_error(gettext("Forcefully reloading IPsec"));
898
		vpn_ipsec_configure();
899
	}
900
}
901

    
902
/* master setup for vpn (mpd) */
903
function vpn_setup() {
904
	global $g;
905

    
906
	if ($g['platform'] == 'jail')
907
		return;
908

    
909
	/* start pptpd */
910
	vpn_pptpd_configure();
911

    
912
	/* start pppoe server */
913
	vpn_pppoes_configure();
914

    
915
	/* setup l2tp */
916
	vpn_l2tp_configure();
917
}
918

    
919
function vpn_netgraph_support() {
920
	$iflist = get_configured_interface_list();
921
	foreach ($iflist as $iface) {
922
		$realif = get_real_interface($iface);
923
		/* Get support for netgraph(4) from the nic */
924
		$ifinfo = pfSense_get_interface_addresses($realif);
925
		if (!empty($ifinfo) && in_array($ifinfo['iftype'], array("ether", "vlan", "bridge")))
926
			pfSense_ngctl_attach(".", $realif);
927
	}
928
}
929

    
930
function vpn_pptpd_configure() {
931
	global $config, $g;
932

    
933
	$syscfg = $config['system'];
934
	$pptpdcfg = $config['pptpd'];
935

    
936
	if ($g['booting']) {
937
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
938
			return 0;
939

    
940
		echo gettext("Configuring PPTP VPN service... ");
941
	} else {
942
		/* kill mpd */
943
		killbypid("{$g['varrun_path']}/pptp-vpn.pid");
944

    
945
		/* wait for process to die */
946
		sleep(3);
947

    
948
		if (is_process_running("mpd -b")) {
949
			killbypid("{$g['varrun_path']}/pptp-vpn.pid");
950
			log_error(gettext("Could not kill mpd within 3 seconds.   Trying again."));
951
		}
952

    
953
		/* remove mpd.conf, if it exists */
954
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.conf");
955
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.links");
956
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.secret");
957
	}
958

    
959
	if (empty($pptpdcfg['n_pptp_units'])) {
960
		log_error("Something wrong in the PPTPd configuration. Preventing starting the daemon because issues would arise.");
961
		return;
962
	}
963

    
964
	/* make sure pptp-vpn directory exists */
965
	if (!file_exists("{$g['varetc_path']}/pptp-vpn"))
966
		mkdir("{$g['varetc_path']}/pptp-vpn");
967

    
968
	switch ($pptpdcfg['mode']) {
969
		case 'server' :
970
			/* write mpd.conf */
971
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.conf", "w");
972
			if (!$fd) {
973
				printf(gettext("Error: cannot open mpd.conf in vpn_pptpd_configure().") . "\n");
974
				return 1;
975
			}
976

    
977
			$mpdconf = <<<EOD
978
pptps:
979

    
980
EOD;
981

    
982
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
983
				$mpdconf .= "	load pt{$i}\n";
984
			}
985

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

    
988
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
989

    
990
				$mpdconf .= <<<EOD
991

    
992
pt{$i}:
993
	new -i pptpd{$i} pt{$i} pt{$i}
994
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
995
	load pts
996

    
997
EOD;
998
			}
999

    
1000
			$mpdconf .=<<<EOD
1001

    
1002
pts:
1003
	set iface disable on-demand
1004
	set iface enable proxy-arp
1005
	set iface enable tcpmssfix
1006
	set iface idle 1800
1007
	set iface up-script /usr/local/sbin/vpn-linkup
1008
	set iface down-script /usr/local/sbin/vpn-linkdown
1009
	set bundle enable multilink
1010
	set bundle enable crypt-reqd
1011
	set link yes acfcomp protocomp
1012
	set link no pap chap
1013
	set link enable chap-msv2
1014
	set link mtu 1460
1015
	set link keep-alive 10 60
1016
	set ipcp yes vjcomp
1017
	set bundle enable compression
1018
	set ccp yes mppc
1019
	set ccp yes mpp-e128
1020
	set ccp yes mpp-stateless
1021

    
1022
EOD;
1023

    
1024
			if (!isset ($pptpdcfg['req128'])) {
1025
				$mpdconf .=<<<EOD
1026
	set ccp yes mpp-e40
1027
	set ccp yes mpp-e56
1028

    
1029
EOD;
1030
			}
1031

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

    
1035
			if (!empty($pptpdcfg['dns1'])) {
1036
				$mpdconf .= "	set ipcp dns " . $pptpdcfg['dns1'];
1037
				if (!empty($pptpdcfg['dns2']))
1038
					$mpdconf .= " " . $pptpdcfg['dns2'];
1039
				$mpdconf .= "\n";
1040
			} elseif (isset ($config['dnsmasq']['enable'])) {
1041
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1042
				if ($syscfg['dnsserver'][0])
1043
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1044
				$mpdconf .= "\n";
1045
			} elseif (isset($config['unbound']['enable'])) {
1046
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1047
				if ($syscfg['dnsserver'][0])
1048
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1049
				$mpdconf .= "\n";
1050
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1051
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1052
			}
1053

    
1054
			if (isset ($pptpdcfg['radius']['server']['enable'])) {
1055
				$authport = (isset($pptpdcfg['radius']['server']['port']) && strlen($pptpdcfg['radius']['server']['port']) > 1) ? $pptpdcfg['radius']['server']['port'] : 1812;
1056
				$acctport = $authport + 1;
1057
				$mpdconf .=<<<EOD
1058
	set radius server {$pptpdcfg['radius']['server']['ip']} "{$pptpdcfg['radius']['server']['secret']}" {$authport} {$acctport}
1059

    
1060
EOD;
1061
			if (isset ($pptpdcfg['radius']['server2']['enable'])) {
1062
				$authport = (isset($pptpdcfg['radius']['server2']['port']) && strlen($pptpdcfg['radius']['server2']['port']) > 1) ? $pptpdcfg['radius']['server2']['port'] : 1812;
1063
				$acctport = $authport + 1;
1064
				$mpdconf .=<<<EOD
1065
	set radius server {$pptpdcfg['radius']['server2']['ip']} "{$pptpdcfg['radius']['server2']['secret2']}" {$authport} {$acctport}
1066

    
1067
EOD;
1068
			}
1069
			$mpdconf .=<<<EOD
1070
	set radius retries 3
1071
	set radius timeout 10
1072
	set auth enable radius-auth
1073

    
1074
EOD;
1075

    
1076
				if (isset ($pptpdcfg['radius']['accounting'])) {
1077
					$mpdconf .=<<<EOD
1078
	set auth enable radius-acct
1079
	set radius acct-update 300
1080

    
1081
EOD;
1082
				}
1083
			}
1084

    
1085
			fwrite($fd, $mpdconf);
1086
			fclose($fd);
1087
			unset($mpdconf);
1088

    
1089
			/* write mpd.links */
1090
			$fd = fopen("{$g['varetc_path']}/pptp-vpn/mpd.links", "w");
1091
			if (!$fd) {
1092
				printf(gettext("Error: cannot open mpd.links in vpn_pptpd_configure().") . "\n");
1093
				return 1;
1094
			}
1095

    
1096
			$mpdlinks = "";
1097

    
1098
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1099
				$mpdlinks .=<<<EOD
1100

    
1101
pt{$i}:
1102
	set link type pptp
1103
	set pptp enable incoming
1104
	set pptp disable originate
1105
	set pptp disable windowing
1106

    
1107
EOD;
1108
			}
1109

    
1110
			fwrite($fd, $mpdlinks);
1111
			fclose($fd);
1112
			unset($mpdlinks);
1113

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

    
1121
			$mpdsecret = "";
1122

    
1123
			if (is_array($pptpdcfg['user'])) {
1124
				foreach ($pptpdcfg['user'] as $user) {
1125
					$pass = str_replace('\\', '\\\\', $user['password']);
1126
					$pass = str_replace('"', '\"', $pass);
1127
					$mpdsecret .= "{$user['name']} \"{$pass}\" {$user['ip']}\n";
1128
				}
1129
			}
1130

    
1131
			fwrite($fd, $mpdsecret);
1132
			fclose($fd);
1133
			unset($mpdsecret);
1134
			chmod("{$g['varetc_path']}/pptp-vpn/mpd.secret", 0600);
1135

    
1136
			vpn_netgraph_support();
1137

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

    
1141
			break;
1142

    
1143
		case 'redir' :
1144
			break;
1145
	}
1146

    
1147
	if ($g['booting'])
1148
		echo "done\n";
1149

    
1150
	return 0;
1151
}
1152

    
1153
function vpn_pppoes_configure() {
1154
	global $config;
1155

    
1156
	if (is_array($config['pppoes']['pppoe'])) {
1157
		foreach ($config['pppoes']['pppoe'] as $pppoe)
1158
			vpn_pppoe_configure($pppoe);
1159
	}
1160
}
1161

    
1162
function vpn_pppoe_configure(&$pppoecfg) {
1163
	global $config, $g;
1164

    
1165
	$syscfg = $config['system'];
1166

    
1167
	/* create directory if it does not exist */
1168
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn"))
1169
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1170

    
1171
	if ($g['booting']) {
1172
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
1173
			return 0;
1174

    
1175
		echo gettext("Configuring PPPoE VPN service... ");
1176
	} else {
1177
		/* kill mpd */
1178
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1179

    
1180
		/* wait for process to die */
1181
		sleep(2);
1182

    
1183
	}
1184

    
1185
	switch ($pppoecfg['mode']) {
1186

    
1187
		case 'server' :
1188

    
1189
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1190

    
1191
			if ($pppoecfg['paporchap'] == "chap")
1192
				$paporchap = "set link enable chap";
1193
			else
1194
				$paporchap = "set link enable pap";
1195

    
1196
			/* write mpd.conf */
1197
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.conf", "w");
1198
			if (!$fd) {
1199
				printf(gettext("Error: cannot open mpd.conf in vpn_pppoe_configure().") . "\n");
1200
				return 1;
1201
			}
1202
			$mpdconf = "\n\n";
1203
			$mpdconf .= "poes:\n";
1204

    
1205
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1206
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1207
			}
1208

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

    
1211
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1212

    
1213
				if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1214
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1215
				} else {
1216
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1217
				}
1218

    
1219
				$mpdconf .=<<<EOD
1220

    
1221
poes{$pppoecfg['pppoeid']}{$i}:
1222
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1223
	{$isssue_ip_type}
1224
	load pppoe_standard
1225

    
1226
EOD;
1227
			}
1228

    
1229
			$mpdconf .=<<<EOD
1230

    
1231
pppoe_standard:
1232
	set bundle no multilink
1233
	set bundle enable compression
1234
	set auth max-logins 1
1235
	set iface up-script /usr/local/sbin/vpn-linkup
1236
	set iface down-script /usr/local/sbin/vpn-linkdown
1237
	set iface idle 0
1238
	set iface disable on-demand
1239
	set iface disable proxy-arp
1240
	set iface enable tcpmssfix
1241
	set iface mtu 1500
1242
	set link no pap chap
1243
	{$paporchap}
1244
	set link keep-alive 60 180
1245
	set ipcp yes vjcomp
1246
	set ipcp no vjcomp
1247
	set link max-redial -1
1248
	set link mtu 1492
1249
	set link mru 1492
1250
	set ccp yes mpp-e40
1251
	set ccp yes mpp-e128
1252
	set ccp yes mpp-stateless
1253
	set link latency 1
1254
	#set ipcp dns 10.10.1.3
1255
	#set bundle accept encryption
1256

    
1257
EOD;
1258

    
1259
			if (!empty($pppoecfg['dns1'])) {
1260
				$mpdconf .= "	set ipcp dns " . $pppoecfg['dns1'];
1261
				if (!empty($pppoecfg['dns2']))
1262
					$mpdconf .= " " . $pppoecfg['dns2'];
1263
				$mpdconf .= "\n";
1264
			} elseif (isset ($config['dnsmasq']['enable'])) {
1265
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1266
				if ($syscfg['dnsserver'][0])
1267
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1268
				$mpdconf .= "\n";
1269
			} elseif (isset ($config['unbound']['enable'])) {
1270
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1271
				if ($syscfg['dnsserver'][0])
1272
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1273
				$mpdconf .= "\n";
1274
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1275
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1276
			}
1277

    
1278
			if (isset ($pppoecfg['radius']['server']['enable'])) {
1279
				$radiusport = "";
1280
				$radiusacctport = "";
1281
				if (isset($pppoecfg['radius']['server']['port']))
1282
					$radiusport = $pppoecfg['radius']['server']['port'];
1283
				if (isset($pppoecfg['radius']['server']['acctport']))
1284
					$radiusacctport = $pppoecfg['radius']['server']['acctport'];
1285
				$mpdconf .=<<<EOD
1286
	set radius server {$pppoecfg['radius']['server']['ip']} "{$pppoecfg['radius']['server']['secret']}" {$radiusport} {$radiusacctport}
1287
	set radius retries 3
1288
	set radius timeout 10
1289
	set auth enable radius-auth
1290

    
1291
EOD;
1292

    
1293
				if (isset ($pppoecfg['radius']['accounting'])) {
1294
					$mpdconf .=<<<EOD
1295
	set auth enable radius-acct
1296

    
1297
EOD;
1298
				}
1299
			}
1300

    
1301
			fwrite($fd, $mpdconf);
1302
			fclose($fd);
1303
			unset($mpdconf);
1304

    
1305
			/* write mpd.links */
1306
			$fd = fopen("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.links", "w");
1307
			if (!$fd) {
1308
				printf(gettext("Error: cannot open mpd.links in vpn_pppoe_configure().") . "\n");
1309
				return 1;
1310
			}
1311

    
1312
			$mpdlinks = "";
1313

    
1314
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1315
				$mpdlinks .=<<<EOD
1316

    
1317
poes{$pppoecfg['pppoeid']}{$i}:
1318
	set phys type pppoe
1319
	set pppoe iface {$pppoe_interface}
1320
	set pppoe service "*"
1321
	set pppoe disable originate
1322
	set pppoe enable incoming
1323

    
1324
EOD;
1325
			}
1326

    
1327
			fwrite($fd, $mpdlinks);
1328
			fclose($fd);
1329
			unset($mpdlinks);
1330

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

    
1339
				$mpdsecret = "\n\n";
1340

    
1341
				if (!empty($pppoecfg['username'])) {
1342
					$item = explode(" ", $pppoecfg['username']);
1343
					foreach($item as $userdata) {
1344
						$data = explode(":", $userdata);
1345
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1346
					}
1347
				}
1348

    
1349
				fwrite($fd, $mpdsecret);
1350
				fclose($fd);
1351
				unset($mpdsecret);
1352
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1353
			}
1354

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

    
1359
			/* Get support for netgraph(4) from the nic */
1360
			pfSense_ngctl_attach(".", $pppoe_interface);
1361
			/* fire up mpd */
1362
			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");
1363

    
1364
			break;
1365
	}
1366

    
1367
	if ($g['booting'])
1368
		echo gettext("done") . "\n";
1369

    
1370
	return 0;
1371
}
1372

    
1373
function vpn_l2tp_configure() {
1374
	global $config, $g;
1375

    
1376
	$syscfg = $config['system'];
1377
	$l2tpcfg = $config['l2tp'];
1378

    
1379
	/* create directory if it does not exist */
1380
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn"))
1381
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1382

    
1383
	if ($g['booting']) {
1384
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off"))
1385
			return 0;
1386

    
1387
		echo gettext("Configuring l2tp VPN service... ");
1388
	} else {
1389
		/* kill mpd */
1390
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1391

    
1392
		/* wait for process to die */
1393
		sleep(8);
1394

    
1395
	}
1396

    
1397
	/* make sure l2tp-vpn directory exists */
1398
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn"))
1399
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1400

    
1401
	switch ($l2tpcfg['mode']) {
1402

    
1403
		case 'server' :
1404
			if ($l2tpcfg['paporchap'] == "chap")
1405
				$paporchap = "set link enable chap";
1406
			else
1407
				$paporchap = "set link enable pap";
1408

    
1409
			/* write mpd.conf */
1410
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.conf", "w");
1411
			if (!$fd) {
1412
				printf(gettext("Error: cannot open mpd.conf in vpn_l2tp_configure().") . "\n");
1413
				return 1;
1414
			}
1415
			$mpdconf = "\n\n";
1416
			$mpdconf .=<<<EOD
1417
l2tps:
1418

    
1419
EOD;
1420

    
1421
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1422
				$mpdconf .= "	load l2tp{$i}\n";
1423
			}
1424

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

    
1427
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1428

    
1429
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1430
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1431
				} else {
1432
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1433
				}
1434

    
1435
				$mpdconf .=<<<EOD
1436

    
1437
l2tp{$i}:
1438
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1439
	{$isssue_ip_type}
1440
	load l2tp_standard
1441

    
1442
EOD;
1443
			}
1444

    
1445
			$mpdconf .=<<<EOD
1446

    
1447
l2tp_standard:
1448
	set bundle disable multilink
1449
	set bundle enable compression
1450
	set bundle yes crypt-reqd
1451
	set ipcp yes vjcomp
1452
	# set ipcp ranges 131.188.69.161/32 131.188.69.170/28
1453
	set ccp yes mppc
1454
	set iface disable on-demand
1455
	set iface enable proxy-arp
1456
	set iface up-script /usr/local/sbin/vpn-linkup
1457
	set iface down-script /usr/local/sbin/vpn-linkdown
1458
	set link yes acfcomp protocomp
1459
	set link no pap chap
1460
	set link enable chap
1461
	set link keep-alive 10 180
1462

    
1463
EOD;
1464

    
1465
			if (is_ipaddr($l2tpcfg['wins'])) {
1466
				$mpdconf .= "	set ipcp nbns {$l2tpcfg['wins']}\n";
1467
			}
1468
			if (is_ipaddr($l2tpcfg['dns1'])) {
1469
				$mpdconf .= "	set ipcp dns " . $l2tpcfg['dns1'];
1470
				if (is_ipaddr($l2tpcfg['dns2']))
1471
					$mpdconf .= " " . $l2tpcfg['dns2'];
1472
				$mpdconf .= "\n";
1473
			} elseif (isset ($config['dnsmasq']['enable'])) {
1474
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1475
				if ($syscfg['dnsserver'][0])
1476
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1477
				$mpdconf .= "\n";
1478
			} elseif (isset ($config['unbound']['enable'])) {
1479
				$mpdconf .= "	set ipcp dns " . get_interface_ip("lan");
1480
				if ($syscfg['dnsserver'][0])
1481
					$mpdconf .= " " . $syscfg['dnsserver'][0];
1482
				$mpdconf .= "\n";
1483
			} elseif (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
1484
					$mpdconf .= "	set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
1485
			}
1486

    
1487
			if (isset ($l2tpcfg['radius']['enable'])) {
1488
				$mpdconf .=<<<EOD
1489
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1490
	set radius retries 3
1491
	set radius timeout 10
1492
	set auth enable radius-auth
1493

    
1494
EOD;
1495

    
1496
				if (isset ($l2tpcfg['radius']['accounting'])) {
1497
					$mpdconf .=<<<EOD
1498
	set auth enable radius-acct
1499

    
1500
EOD;
1501
				}
1502
			}
1503

    
1504
			fwrite($fd, $mpdconf);
1505
			fclose($fd);
1506
			unset($mpdconf);
1507

    
1508
			/* write mpd.links */
1509
			$fd = fopen("{$g['varetc_path']}/l2tp-vpn/mpd.links", "w");
1510
			if (!$fd) {
1511
				printf(gettext("Error: cannot open mpd.links in vpn_l2tp_configure().") . "\n");
1512
				return 1;
1513
			}
1514

    
1515
			$mpdlinks = "";
1516

    
1517
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1518
				$mpdlinks .=<<<EOD
1519

    
1520
l2tp{$i}:
1521
	set link type l2tp
1522
	set l2tp enable incoming
1523
	set l2tp disable originate
1524

    
1525
EOD;
1526
			if (!empty($l2tpcfg['secret']))
1527
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
1528
			}
1529

    
1530
			fwrite($fd, $mpdlinks);
1531
			fclose($fd);
1532
			unset($mpdlinks);
1533

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

    
1541
			$mpdsecret = "\n\n";
1542

    
1543
			if (is_array($l2tpcfg['user'])) {
1544
				foreach ($l2tpcfg['user'] as $user)
1545
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1546
			}
1547

    
1548
			fwrite($fd, $mpdsecret);
1549
			fclose($fd);
1550
			unset($mpdsecret);
1551
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
1552

    
1553
			vpn_netgraph_support();
1554

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

    
1558
			break;
1559

    
1560
		case 'redir' :
1561
			break;
1562
	}
1563

    
1564
	if ($g['booting'])
1565
		echo "done\n";
1566

    
1567
	return 0;
1568
}
1569

    
1570
function vpn_ipsec_configure_preferoldsa() {
1571
	global $config;
1572
	if(isset($config['ipsec']['preferoldsa']))
1573
		set_single_sysctl("net.key.preferred_oldsa", "-30");
1574
	else
1575
		set_single_sysctl("net.key.preferred_oldsa", "0");
1576
}
1577

    
1578
?>
(59-59/68)