Projet

Général

Profil

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

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

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
		mwexec("/sbin/ifconfig enc0 up");
132
		set_single_sysctl("net.inet.ip.ipsec_in_use", "1");
133
		/* needed for config files */
134
		if (!is_dir("{$g['varetc_path']}/ipsec"))
135
			mkdir("{$g['varetc_path']}/ipsec");
136
		if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d"))
137
			mkdir("{$g['varetc_path']}/ipsec/ipsec.d");
138
		if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/cacerts"))
139
			mkdir("{$g['varetc_path']}/ipsec/ipsec.d/cacerts");
140
		if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/private"))
141
			mkdir("{$g['varetc_path']}/ipsec/ipsec.d/private");
142
		if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/crls"))
143
			mkdir("{$g['varetc_path']}/ipsec/ipsec.d/crls");
144
		if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/certs"))
145
			mkdir("{$g['varetc_path']}/ipsec/ipsec.d/certs");
146
		if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/aacerts"))
147
			mkdir("{$g['varetc_path']}/ipsec/ipsec.d/aacerts");
148
		if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/acerts"))
149
			mkdir("{$g['varetc_path']}/ipsec/ipsec.d/acerts");
150
		if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/ocspcerts"))
151
			mkdir("{$g['varetc_path']}/ipsec/ipsec.d/ocspcerts");
152
		if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/reqs"))
153
			mkdir("{$g['varetc_path']}/ipsec/ipsec.d/reqs");
154
		
155

    
156
		if ($g['booting'])
157
			echo gettext("Configuring IPsec VPN... ");
158

    
159
		/* fastforwarding is not compatible with ipsec tunnels */
160
		set_single_sysctl("net.inet.ip.fastforwarding", "0");
161

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

    
170
			$ipsecpinghosts = "";
171
			/* step through each phase1 entry */
172
			foreach ($a_phase1 as $ph1ent) {
173
				if (isset($ph1ent['disabled']))
174
					continue;
175

    
176
				$ikeid = $ph1ent['ikeid'];
177
				$listeniflist = get_real_interface($a_phase1['interface']);
178

    
179
				$ep = ipsec_get_phase1_src($ph1ent);
180
				if (!is_ipaddr($ep))
181
					continue;
182

    
183
				if(!in_array($ep,$ipmap))
184
					$ipmap[] = $ep;
185

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

    
189
				if (isset ($ph1ent['mobile']))
190
					continue;
191

    
192
				$rg = $ph1ent['remote-gateway'];
193

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

    
208
				if (is_array($a_phase2)) {
209
					/* step through each phase2 entry */
210
					foreach ($a_phase2 as $ph2ent) {
211
						if (isset($ph2ent['disabled']))
212
							continue;
213

    
214
						if ($ikeid != $ph2ent['ikeid'])
215
							continue;
216

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

    
271
		$strongswan = <<<EOD
272

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

    
278
charon {
279

    
280
        # number of worker threads in charon
281
        threads = 16
282
	ikesa_table_size = 32
283
	ikesa_table_segments = 4
284
	init_limit_half_open = 1000;
285

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

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

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

    
305
EOD;
306

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

    
310
		$strongswan .= "\tplugins {\n";
311

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

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

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

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

    
345
					if (!isset($ph2ent['mobile']))
346
						continue;
347

    
348
					$localid = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
349

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

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

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

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

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

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

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

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

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

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

    
428
		$pskconf = "";
429

    
430
		if (is_array($a_phase1) && count($a_phase1)) {
431
			foreach ($a_phase1 as $ph1ent) {
432

    
433
				if (isset($ph1ent['disabled']))
434
					continue;
435

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

    
439
					if (strstr($authmethod,'rsa')) {
440

    
441
						$ikeid = $ph1ent['ikeid'];
442
						$cert = lookup_cert($ph1ent['certref']);
443

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

    
449
						chmod($certpath, 0600);
450

    
451
						$keyfile = "cert-{$ikeid}.key";
452
						$keypath = "{$g['varetc_path']}/ipsec/{$keyfile}";
453

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

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

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

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

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

    
481
					if (empty($peerid_data))
482
						continue;
483

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

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

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

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

    
516
		$natfilterrules = false;
517
		/* begin ipsec.conf */
518
		$ipsecconf = "";
519
		if (is_array($a_phase1) && count($a_phase1))  {
520

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

    
525
			foreach ($a_phase1 as $ph1ent) {
526
				if (isset($ph1ent['disabled']))
527
					continue;
528

    
529
				if ($ph1ent['mode'] == "aggressive")
530
					$aggressive = "yes";
531
				else
532
					$aggressive = "no";
533

    
534
				$ep = ipsec_get_phase1_src($ph1ent);
535
				if (!$ep)
536
					continue;
537

    
538
				$ikeid = $ph1ent['ikeid'];
539
				$keyexchange = "ikev1";
540
				$passive = "route";
541
				if (!empty($ph1ent['iketype']) && $ph1ent['iketype'] != "ikev1") {
542
					$keyexchange = "ikev2";
543
					//$passive = "start";
544
				} else
545
					$passive = "route";
546

    
547
				if (isset($ph1ent['mobile'])) {
548
					$right_spec = "%any";
549
					$passive = 'add';
550
				} else
551
					$right_spec = $ph1ent['remote-gateway'];
552

    
553
				list ($myid_type, $myid_data) = ipsec_find_id($ph1ent, "local");
554
				list ($peerid_type, $peerid_data) = ipsec_find_id($ph1ent, "peer", $rgmap);
555

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

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

    
570
					$modp = vpn_ipsec_convert_to_modp($ph1ent['dhgroup']);
571
					if (!empty($modp))
572
						$ealgosp1 .= "-{$modp}";
573

    
574
					$ealgosp1 .= "!";
575
				}
576

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

    
588
				$ikelifeline = '';
589
				if ($ph1ent['lifetime'])
590
					$ikelifeline = "ikelifetime = {$ph1ent['lifetime']}s";
591

    
592
				$rightsourceip = NULL;
593
				if (!empty($a_client['pool_address'])) 
594
					$rightsourceip = "\trightsourceip = {$a_client['pool_address']}/{$a_client['pool_netbits']}\n";
595

    
596
				$authentication = "";
597
				switch ($ph1ent['authentication_method']) {
598
				case 'xauth_rsa_server':
599
					$authentication = "leftauth = pubkey\n\trightauth = pubkey";
600
					$authentication .= "\n\trightauth2 = xauth-generic";
601
					break;
602
				case 'xauth_psk_server':
603
					$authentication = "leftauth = psk\n\trightauth = psk";
604
					$authentication .= "\n\trightauth2 = xauth-generic";
605
					break;
606
				case 'pre_shared_key':
607
					$authentication = "leftauth = psk\n\trightauth = psk";
608
					break;
609
				case 'rsasig':
610
					$authentication = "leftauth = pubkey\n\trightauth = pubkey";
611
					break;
612
				case 'hybrid_rsa_server':
613
					$authentication = "leftauth = xauth-generic\n\trightauth = pubkey";
614
					$authentication .= "\n\trightauth2 = xauth";
615
					break;
616
				}
617

    
618
				$left_spec = $ep;
619

    
620
				$ipseclifetime = 0;
621
				$rightsubnet_spec = array();
622
				$leftsubnet_spec = array();
623
				$ealgoAHsp2arr = array();
624
				$ealgoESPsp2arr = array();
625
			if (is_array($a_phase2) && count($a_phase2)) {
626
				foreach ($a_phase2 as $ph2ent) {
627
					if ($ikeid != $ph2ent['ikeid'])
628
						continue;
629

    
630
					if (isset($ph2ent['disabled']))
631
						continue;
632

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

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

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

    
667
						if (empty($leftsubnet_spec[$leftsubnet_data]))
668
							$leftsubnet_spec[$leftsubnet_data] = $leftsubnet_data;
669

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

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

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

    
696
					if (isset($a_client['pfs_group']))
697
						$ph2ent['pfsgroup'] = $a_client['pfs_group'];
698

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

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

    
766

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

    
774
				$ipsecconf .=<<<EOD
775

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

    
791
EOD;
792

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

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

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

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

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

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

    
860
	return count($filterdns_list);
861
}
862

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

    
872
	$ipseccfg = $config['ipsec'];
873

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

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

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

    
899
	if ($g['platform'] == 'jail')
900
		return;
901

    
902
	/* start pptpd */
903
	vpn_pptpd_configure();
904

    
905
	/* start pppoe server */
906
	vpn_pppoes_configure();
907

    
908
	/* setup l2tp */
909
	vpn_l2tp_configure();
910
}
911

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

    
923
function vpn_pptpd_configure() {
924
	global $config, $g;
925

    
926
	$syscfg = $config['system'];
927
	$pptpdcfg = $config['pptpd'];
928

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

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

    
938
		/* wait for process to die */
939
		sleep(3);
940

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

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

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

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

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

    
970
			$mpdconf = <<<EOD
971
pptps:
972

    
973
EOD;
974

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

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

    
981
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
982

    
983
				$mpdconf .= <<<EOD
984

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

    
990
EOD;
991
			}
992

    
993
			$mpdconf .=<<<EOD
994

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

    
1015
EOD;
1016

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

    
1022
EOD;
1023
			}
1024

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

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

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

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

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

    
1067
EOD;
1068

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

    
1074
EOD;
1075
				}
1076
			}
1077

    
1078
			fwrite($fd, $mpdconf);
1079
			fclose($fd);
1080
			unset($mpdconf);
1081

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

    
1089
			$mpdlinks = "";
1090

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

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

    
1100
EOD;
1101
			}
1102

    
1103
			fwrite($fd, $mpdlinks);
1104
			fclose($fd);
1105
			unset($mpdlinks);
1106

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

    
1114
			$mpdsecret = "";
1115

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

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

    
1129
			vpn_netgraph_support();
1130

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

    
1134
			break;
1135

    
1136
		case 'redir' :
1137
			break;
1138
	}
1139

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

    
1143
	return 0;
1144
}
1145

    
1146
function vpn_pppoes_configure() {
1147
	global $config;
1148

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

    
1155
function vpn_pppoe_configure(&$pppoecfg) {
1156
	global $config, $g;
1157

    
1158
	$syscfg = $config['system'];
1159

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

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

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

    
1173
		/* wait for process to die */
1174
		sleep(2);
1175

    
1176
	}
1177

    
1178
	switch ($pppoecfg['mode']) {
1179

    
1180
		case 'server' :
1181

    
1182
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1183

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

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

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

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

    
1204
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1205

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

    
1212
				$mpdconf .=<<<EOD
1213

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

    
1219
EOD;
1220
			}
1221

    
1222
			$mpdconf .=<<<EOD
1223

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

    
1250
EOD;
1251

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

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

    
1284
EOD;
1285

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

    
1290
EOD;
1291
				}
1292
			}
1293

    
1294
			fwrite($fd, $mpdconf);
1295
			fclose($fd);
1296
			unset($mpdconf);
1297

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

    
1305
			$mpdlinks = "";
1306

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

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

    
1317
EOD;
1318
			}
1319

    
1320
			fwrite($fd, $mpdlinks);
1321
			fclose($fd);
1322
			unset($mpdlinks);
1323

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

    
1332
				$mpdsecret = "\n\n";
1333

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

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

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

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

    
1357
			break;
1358
	}
1359

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

    
1363
	return 0;
1364
}
1365

    
1366
function vpn_l2tp_configure() {
1367
	global $config, $g;
1368

    
1369
	$syscfg = $config['system'];
1370
	$l2tpcfg = $config['l2tp'];
1371

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

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

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

    
1385
		/* wait for process to die */
1386
		sleep(8);
1387

    
1388
	}
1389

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

    
1394
	switch ($l2tpcfg['mode']) {
1395

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

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

    
1412
EOD;
1413

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

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

    
1420
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1421

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

    
1428
				$mpdconf .=<<<EOD
1429

    
1430
l2tp{$i}:
1431
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1432
	{$isssue_ip_type}
1433
	load l2tp_standard
1434

    
1435
EOD;
1436
			}
1437

    
1438
			$mpdconf .=<<<EOD
1439

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

    
1456
EOD;
1457

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

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

    
1487
EOD;
1488

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

    
1493
EOD;
1494
				}
1495
			}
1496

    
1497
			fwrite($fd, $mpdconf);
1498
			fclose($fd);
1499
			unset($mpdconf);
1500

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

    
1508
			$mpdlinks = "";
1509

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

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

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

    
1523
			fwrite($fd, $mpdlinks);
1524
			fclose($fd);
1525
			unset($mpdlinks);
1526

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

    
1534
			$mpdsecret = "\n\n";
1535

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

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

    
1546
			vpn_netgraph_support();
1547

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

    
1551
			break;
1552

    
1553
		case 'redir' :
1554
			break;
1555
	}
1556

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

    
1560
	return 0;
1561
}
1562

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

    
1571
?>
(59-59/68)