Projet

Général

Profil

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

univnautes / etc / inc / vpn.inc @ fa4e059e

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
				$ipseclifetime = 0;
619
				$rightsubnet_spec = array();
620
				$leftsubnet_spec = array();
621
				$ealgoAHsp2arr = array();
622
				$ealgoESPsp2arr = array();
623
			if (is_array($a_phase2) && count($a_phase2)) {
624
				foreach ($a_phase2 as $ph2ent) {
625
					if ($ikeid != $ph2ent['ikeid'])
626
						continue;
627

    
628
					if (isset($ph2ent['disabled']))
629
						continue;
630

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

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

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

    
665
						if (empty($leftsubnet_spec[$leftsubnet_data]))
666
							$leftsubnet_spec[$leftsubnet_data] = $leftsubnet_data;
667

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

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

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

    
694
					if (isset($a_client['pfs_group']))
695
						$ph2ent['pfsgroup'] = $a_client['pfs_group'];
696

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

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

    
764

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

    
772
				$ipsecconf .=<<<EOD
773

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

    
789
EOD;
790

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

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

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

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

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

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

    
858
	return count($filterdns_list);
859
}
860

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

    
870
	$ipseccfg = $config['ipsec'];
871

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

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

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

    
897
	if ($g['platform'] == 'jail')
898
		return;
899

    
900
	/* start pptpd */
901
	vpn_pptpd_configure();
902

    
903
	/* start pppoe server */
904
	vpn_pppoes_configure();
905

    
906
	/* setup l2tp */
907
	vpn_l2tp_configure();
908
}
909

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

    
921
function vpn_pptpd_configure() {
922
	global $config, $g;
923

    
924
	$syscfg = $config['system'];
925
	$pptpdcfg = $config['pptpd'];
926

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

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

    
936
		/* wait for process to die */
937
		sleep(3);
938

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

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

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

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

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

    
968
			$mpdconf = <<<EOD
969
pptps:
970

    
971
EOD;
972

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

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

    
979
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
980

    
981
				$mpdconf .= <<<EOD
982

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

    
988
EOD;
989
			}
990

    
991
			$mpdconf .=<<<EOD
992

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

    
1013
EOD;
1014

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

    
1020
EOD;
1021
			}
1022

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

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

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

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

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

    
1065
EOD;
1066

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

    
1072
EOD;
1073
				}
1074
			}
1075

    
1076
			fwrite($fd, $mpdconf);
1077
			fclose($fd);
1078
			unset($mpdconf);
1079

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

    
1087
			$mpdlinks = "";
1088

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

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

    
1098
EOD;
1099
			}
1100

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

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

    
1112
			$mpdsecret = "";
1113

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

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

    
1127
			vpn_netgraph_support();
1128

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

    
1132
			break;
1133

    
1134
		case 'redir' :
1135
			break;
1136
	}
1137

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

    
1141
	return 0;
1142
}
1143

    
1144
function vpn_pppoes_configure() {
1145
	global $config;
1146

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

    
1153
function vpn_pppoe_configure(&$pppoecfg) {
1154
	global $config, $g;
1155

    
1156
	$syscfg = $config['system'];
1157

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

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

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

    
1171
		/* wait for process to die */
1172
		sleep(2);
1173

    
1174
	}
1175

    
1176
	switch ($pppoecfg['mode']) {
1177

    
1178
		case 'server' :
1179

    
1180
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1181

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

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

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

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

    
1202
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1203

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

    
1210
				$mpdconf .=<<<EOD
1211

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

    
1217
EOD;
1218
			}
1219

    
1220
			$mpdconf .=<<<EOD
1221

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

    
1248
EOD;
1249

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

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

    
1282
EOD;
1283

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

    
1288
EOD;
1289
				}
1290
			}
1291

    
1292
			fwrite($fd, $mpdconf);
1293
			fclose($fd);
1294
			unset($mpdconf);
1295

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

    
1303
			$mpdlinks = "";
1304

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

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

    
1315
EOD;
1316
			}
1317

    
1318
			fwrite($fd, $mpdlinks);
1319
			fclose($fd);
1320
			unset($mpdlinks);
1321

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

    
1330
				$mpdsecret = "\n\n";
1331

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

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

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

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

    
1355
			break;
1356
	}
1357

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

    
1361
	return 0;
1362
}
1363

    
1364
function vpn_l2tp_configure() {
1365
	global $config, $g;
1366

    
1367
	$syscfg = $config['system'];
1368
	$l2tpcfg = $config['l2tp'];
1369

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

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

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

    
1383
		/* wait for process to die */
1384
		sleep(8);
1385

    
1386
	}
1387

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

    
1392
	switch ($l2tpcfg['mode']) {
1393

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

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

    
1410
EOD;
1411

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

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

    
1418
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1419

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

    
1426
				$mpdconf .=<<<EOD
1427

    
1428
l2tp{$i}:
1429
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1430
	{$isssue_ip_type}
1431
	load l2tp_standard
1432

    
1433
EOD;
1434
			}
1435

    
1436
			$mpdconf .=<<<EOD
1437

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

    
1454
EOD;
1455

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

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

    
1485
EOD;
1486

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

    
1491
EOD;
1492
				}
1493
			}
1494

    
1495
			fwrite($fd, $mpdconf);
1496
			fclose($fd);
1497
			unset($mpdconf);
1498

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

    
1506
			$mpdlinks = "";
1507

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

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

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

    
1521
			fwrite($fd, $mpdlinks);
1522
			fclose($fd);
1523
			unset($mpdlinks);
1524

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

    
1532
			$mpdsecret = "\n\n";
1533

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

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

    
1544
			vpn_netgraph_support();
1545

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

    
1549
			break;
1550

    
1551
		case 'redir' :
1552
			break;
1553
	}
1554

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

    
1558
	return 0;
1559
}
1560

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

    
1569
?>
(59-59/68)