Projet

Général

Profil

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

univnautes / etc / inc / vpn.inc @ 484e6adc

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	/sbin/sysctl
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()
46
{
47
	global $config, $ipsec_loglevels;
48

    
49
	foreach ($ipsec_loglevels as $lkey => $ldescr) {
50
		if (empty($config['ipsec']["ipsec_{$lkey}"]))
51
			mwexec("/usr/local/sbin/ipsec stroke loglevel {$lkey} -1", false);
52
		else if (is_numeric($config['ipsec']["ipsec_{$lkey}"]) &&
53
		    intval($config['ipsec']["ipsec_{$lkey}"]) >= 1 && intval($config['ipsec']["ipsec_{$lkey}"]) <= 5)
54
			mwexec("/usr/local/sbin/ipsec stroke loglevel {$lkey} " . (intval($config['ipsec']["ipsec_{$lkey}"]) - 1) , false);
55
	}
56
}
57

    
58
/* include all configuration functions */
59
function vpn_ipsec_convert_to_modp($index)
60
{
61

    
62
	$convertion = "";
63
	switch ($index) {
64
	case '1':
65
		$convertion = "modp768";
66
		break;
67
	case '2':
68
		$convertion = "modp1024";
69
		break;
70
	case '5':
71
		$convertion = "modp1536";
72
		break;
73
	case '14':
74
		$convertion = "modp2048";
75
		break;
76
	case '15':
77
		$convertion = "modp3072";
78
		break;
79
	case '16':      
80
		$convertion = "modp4096";
81
		break;
82
	case '17':
83
		$convertion = "modp6144";
84
		break;
85
	case '18':
86
		$convertion = "modp8192";
87
		break;
88
	}
89

    
90
	return $convertion;
91
}
92

    
93
function vpn_ipsec_configure($ipchg = false)
94
{
95
	global $config, $g, $sa, $sn, $p1_ealgos, $p2_ealgos;
96

    
97
	if ($g['platform'] == 'jail')
98
		return;
99

    
100
	/* get the automatic ping_hosts.sh ready */
101
	unlink_if_exists("{$g['vardb_path']}/ipsecpinghosts");
102
	touch("{$g['vardb_path']}/ipsecpinghosts");
103

    
104
	vpn_ipsec_configure_preferoldsa();
105

    
106
	$syscfg = $config['system'];
107
	$ipseccfg = $config['ipsec'];
108
	$a_phase1 = $config['ipsec']['phase1'];
109
	$a_phase2 = $config['ipsec']['phase2'];
110
	$a_client = $config['ipsec']['client'];
111

    
112
	if (!isset($ipseccfg['enable'])) {
113
		/* try to stop charon */
114
		mwexec("/usr/local/sbin/ipsec stop");
115
		/* Stop dynamic monitoring */
116
		killbypid("{$g['varrun_path']}/filterdns-ipsec.pid");
117

    
118
		/* wait for process to die */
119
		sleep(2);
120

    
121
		/* disallow IPSEC, it is off */
122
		mwexec("/sbin/ifconfig enc0 down");
123
		exec("/sbin/sysctl net.inet.ip.ipsec_in_use=0");
124

    
125
		return 0;
126
	} else {
127
		mwexec("/sbin/ifconfig enc0 up");
128
		mwexec("/sbin/sysctl net.inet.ip.ipsec_in_use=1");
129
		/* needed for config files */
130
		if (!is_dir("{$g['varetc_path']}/ipsec"))
131
			mkdir("{$g['varetc_path']}/ipsec");
132
		if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d"))
133
			mkdir("{$g['varetc_path']}/ipsec/ipsec.d");
134
		if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/cacerts"))
135
			mkdir("{$g['varetc_path']}/ipsec/ipsec.d/cacerts");
136
		if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/private"))
137
			mkdir("{$g['varetc_path']}/ipsec/ipsec.d/private");
138
		if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/crls"))
139
			mkdir("{$g['varetc_path']}/ipsec/ipsec.d/crls");
140
		if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/certs"))
141
			mkdir("{$g['varetc_path']}/ipsec/ipsec.d/certs");
142
		if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/aacerts"))
143
			mkdir("{$g['varetc_path']}/ipsec/ipsec.d/aacerts");
144
		if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/acerts"))
145
			mkdir("{$g['varetc_path']}/ipsec/ipsec.d/acerts");
146
		if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/ocspcerts"))
147
			mkdir("{$g['varetc_path']}/ipsec/ipsec.d/ocspcerts");
148
		if (!is_dir("{$g['varetc_path']}/ipsec/ipsec.d/reqs"))
149
			mkdir("{$g['varetc_path']}/ipsec/ipsec.d/reqs");
150
		
151

    
152
		if ($g['booting'])
153
			echo gettext("Configuring IPsec VPN... ");
154

    
155
		/* fastforwarding is not compatible with ipsec tunnels */
156
		mwexec("/sbin/sysctl net.inet.ip.fastforwarding=0");
157

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

    
166
			$ipsecpinghosts = "";
167
			/* step through each phase1 entry */
168
			foreach ($a_phase1 as $ph1ent) {
169
				if (isset($ph1ent['disabled']))
170
					continue;
171

    
172
				$listeniflist = get_real_interface($a_phase1['interface']);
173

    
174
				$ep = ipsec_get_phase1_src($ph1ent);
175
				if (!is_ipaddr($ep))
176
					continue;
177

    
178
				if(!in_array($ep,$ipmap))
179
					$ipmap[] = $ep;
180

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

    
184
				if (isset ($ph1ent['mobile']))
185
					continue;
186

    
187
				$rg = $ph1ent['remote-gateway'];
188

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

    
203
				if (is_array($a_phase2)) {
204
					/* step through each phase2 entry */
205
					foreach ($a_phase2 as $ph2ent) {
206
						$ikeid = $ph2ent['ikeid'];
207

    
208
						if (isset($ph2ent['disabled']))
209
							continue;
210

    
211
						if ($ikeid != $ph1ent['ikeid'])
212
							continue;
213

    
214
						/* add an ipsec pinghosts entry */
215
						if ($ph2ent['pinghost']) {
216
							if (!is_array($iflist))
217
								$iflist = get_configured_interface_list();
218
							foreach ($iflist as $ifent => $ifname) {
219
								if(is_ipaddrv6($ph2ent['pinghost'])) {
220
									$interface_ip = get_interface_ipv6($ifent);
221
									if(!is_ipaddrv6($interface_ip))
222
										continue;
223
									$local_subnet = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
224
									if (ip_in_subnet($interface_ip, $local_subnet)) {
225
										$srcip = $interface_ip;
226
										break;
227
									}
228
								} else {
229
									$interface_ip = get_interface_ip($ifent);
230
									if(!is_ipaddrv4($interface_ip))
231
										continue;
232
									$local_subnet = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
233
									if ($local_subnet == "0.0.0.0/0" || ip_in_subnet($interface_ip, $local_subnet)) {
234
										$srcip = $interface_ip;
235
										break;
236
									}
237
								}
238
							}
239
							$dstip = $ph2ent['pinghost'];
240
							if(is_ipaddrv6($dstip)) {
241
								$family = "inet6";
242
							} else {
243
								$family = "inet";
244
							}
245
							if (is_ipaddr($srcip))
246
								$ipsecpinghosts[] = "{$srcip}|{$dstip}|3|||||{$family}|\n";
247
						}
248
					}
249
				}
250
			}
251
			@file_put_contents("{$g['vardb_path']}/ipsecpinghosts", $ipsecpinghosts);
252
			unset($ipsecpinghosts);
253
		}
254
		unset($iflist);
255

    
256
		$strongswan = <<<EOD
257

    
258
#Automatically generated please do not modify
259
starter {
260
    load_warning = no
261
}
262

    
263
charon {
264

    
265
        # number of worker threads in charon
266
        threads = 16
267

    
268
	# And two loggers using syslog. The subsections define the facility to log
269
	# to, currently one of: daemon, auth.
270
	syslog {
271

    
272
		identifier = charon
273
		# default level to the LOG_DAEMON facility
274
		daemon {
275
		}
276
		# very minimalistic IKE auditing logs to LOG_AUTHPRIV
277
		auth {
278
		    default = -1
279
		    ike = 1
280
		    ike_name = yes
281
		}
282
	}
283

    
284
EOD;
285

    
286
		if (is_array($a_client) && isset($a_client['enable']) && !empty($a_client['net_list']))
287
			$strongswan .= "\tcisco_unity = yes\n";
288

    
289
		$strongswan .= "\tplugins {\n";
290

    
291
		if (is_array($a_client) && isset($a_client['enable'])) {
292
			$strongswan .= "\t\tattr {\n";
293
			if ($a_client['pool_address'] && $a_client['pool_netbits']) {
294
				$pool_address = $a_client['pool_address'];
295
				$pool_netmask = gen_subnet_mask($a_client['pool_netbits']);
296
				$pool_address = long2ip32(ip2long($pool_address)+1);
297

    
298
				$strongswan .= "\t\taddress = {$pool_address}\n";
299
				$strongswan .= "\t\tnetmask = {$pool_netmask}\n";
300
			}
301

    
302
			$cfgservers = array();
303
			if (!empty($a_client['dns_server1']))
304
				$cfgservers[] = $a_client['dns_server1'];
305
			if (!empty($a_client['dns_server2']))
306
				$cfgservers[] = $a_client['dns_server2'];
307
			if (!empty($a_client['dns_server3']))
308
				$cfgservers[] = $a_client['dns_server3'];
309
			if (!empty($a_client['dns_server4']))
310
				$cfgservers[] = $a_client['dns_server4'];
311

    
312
			if (!empty($cfgservers))
313
				$strongswan .= "\t\tdns = " . implode(",", $cfgservers) . "\n";
314
			unset($cfgservers);
315
			$cfgservers = array();
316
			if (!empty($a_client['wins_server1']))
317
				$cfgservers[] = $a_client['wins_server1'];
318
			if (!empty($a_client['wins_server2']))
319
				$cfgservers[] = $a_client['wins_server2'];
320
			if (!empty($cfgservers))
321
				$strongswan .= "\t\tnbns = " . implode(",", $cfgservers) . "\n";
322
			unset($cfgservers);
323

    
324
			if (!empty($a_client['net_list'])) {
325
				$net_list = '';
326
				foreach ($a_phase2 as $ph2ent) {
327
					if (isset($ph2ent['disabled']))
328
						continue;
329

    
330
					if (!isset($ph2ent['mobile']))
331
						continue;
332

    
333
					$localid = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
334

    
335
					if ($net_list)
336
						$net_list .= ", ";
337
					$net_list .= $localid;
338
				}
339

    
340
				if (!empty($net_list)) {
341
					$strongswan .= "\t\tsubnet = {$net_list}\n";
342
					$strongswan .= "\t\tsplit-include = {$net_list}\n";
343
					unset($net_list);
344
				}
345
			}
346

    
347
			if (!empty($a_client['dns_domain'])) {
348
				$strongswan .= "\t\t# Search domain and default domain\n";
349
				$strongswan .= "\t\t28674 = {$a_client['dns_domain']}\n";
350
				if (empty($a_client['dns_split']))
351
					$strongswan .= "\t\t28675 = {$a_client['dns_domain']}";
352
				$strongswan .= "\n";
353
			}
354

    
355
			if (!empty($a_client['dns_split'])) {
356
				$strongswan .= "\t\t28675 = {$a_client['dns_split']}\n";
357
			}
358

    
359
			if (!empty($a_client['login_banner']))
360
				$strongswan .= "\t\t28672 = {$a_client['login_banner']}\n";
361

    
362
			if (isset($a_client['save_passwd']))
363
				$strongswan .= "\t\t28673 = yes\n";
364

    
365
			if ($a_client['pfs_group'])
366
				$strongswan .= "\t\t28679 = {$a_client['pfs_group']}\n";
367
			$strongswan .= "\t\t}\n";
368

    
369
			if ($a_client['user_source'] != "none") {
370
				$strongswan .= "\txauth-generic {\n";
371
				$strongswan .= "\t\tscript = /etc/inc/ipsec.auth-user.php\n";
372
				$strongswan .= "\t\tauthcfg = ";
373
				$firstsed = 0;
374
				$authcfgs = explode(",", $a_client['user_source']);
375
				foreach ($authcfgs as $authcfg) {
376
					if ($firstsed > 0)
377
						$strongswan .= ",";
378
					if ($authcfg == "system")
379
						$authcfg = "Local Database";
380
					$strongswan .= $authcfg;
381
					$firstsed = 1;
382
				}
383
				$strongswan .= "\n";
384
				$strongswan .= "\t}\n";
385
			}
386
		}
387

    
388
		$strongswan .= "\t}\n}\n";
389
		@file_put_contents("{$g['varetc_path']}/ipsec/strongswan.conf", $strongswan);
390
		unset($strongswan);
391

    
392
		/* generate CA certificates files */
393
		if (is_array($config['ca']) && count($config['ca'])) {
394
			foreach ($config['ca'] as $ca) {
395
				if (!isset($ca['crt'])) {
396
					log_error(sprintf(gettext("Error: Invalid certificate info for %s"), $ca['descr']));
397
					continue;
398
				}
399
				$cert = base64_decode($ca['crt']);
400
				$x509cert = openssl_x509_parse(openssl_x509_read($cert));
401
				if (!is_array($x509cert) || !isset($x509cert['hash'])) {
402
					log_error(sprintf(gettext("Error: Invalid certificate hash info for %s"), $ca['descr']));
403
					continue;
404
				}
405
				$fname = "{$g['varetc_path']}/ipsec/ipsec.d/cacerts/{$x509cert['hash']}.0";
406
				if (!@file_put_contents($fname, $cert)) {
407
					log_error(sprintf(gettext("Error: Cannot write IPsec CA file for %s"), $ca['descr']));
408
					continue;
409
				}
410
				unset($cert);
411
			}
412
		}
413

    
414
		$pskconf = "";
415

    
416
		if (is_array($a_phase1) && count($a_phase1)) {
417
			foreach ($a_phase1 as $ph1ent) {
418

    
419
				if (isset($ph1ent['disabled']))
420
					continue;
421

    
422
				if (strstr($ph1ent['authentication_method'],'rsa')) {
423
					$certline = '';
424

    
425
					if (strstr($authmethod,'rsa')) {
426

    
427
						$cert = lookup_cert($ph1ent['certref']);
428

    
429
						if (!$cert) {
430
							log_error(sprintf(gettext("Error: Invalid phase1 certificate reference for %s"), $ph1ent['name']));
431
							continue;
432
						}
433

    
434
						chmod($certpath, 0600);
435

    
436
						$keyfile = "cert-{$ikeid}.key";
437
						$keypath = "{$g['varetc_path']}/ipsec/{$keyfile}";
438

    
439
						if (!file_put_contents($keypath, base64_decode($cert['prv']))) {
440
							log_error(sprintf(gettext("Error: Cannot write phase1 key file for %s"), $ph1ent['name']));
441
							continue;
442
						}
443

    
444
						chmod($keypath, 0600);
445
						/* XXX" Traffic selectors? */
446
						$pskconf .= " : RSA {$keypath}\n";
447

    
448
						$ca = lookup_ca($ph1ent['caref']);
449
						if ($ca) {
450
							$cafile = "ca-{$ikeid}.crt";
451
							$capath = "{$g['varetc_path']}/ipsec/ipsec.d/cacerts/{$cafile}";
452

    
453
							if (!file_put_contents($capath, base64_decode($ca['crt'])))
454
							{
455
								log_error(sprintf(gettext("Error: Cannot write phase1 CA certificate file for %s"), $ph1ent['name']));
456
								continue;
457
							}
458

    
459
							chmod($capath, 0600);
460
						}
461
					}
462
				} else {
463

    
464
					$peerid_type = $ph1ent['peerid_type'];
465

    
466
					switch ($peerid_type) {
467
						case "peeraddress":
468
							$peerid_type = "address";
469
							$peerid_data = $rgmap[$ph1ent['remote-gateway']];
470
							break;
471

    
472
						case "address";
473
							$peerid_data = $ph1ent['peerid_data'];
474
							break;
475

    
476
						case "fqdn";
477
						case "keyid tag";
478
						case "user_fqdn";
479
							$peerid_data = $ph1ent['peerid_data'];
480
							break;
481
					}
482

    
483
					if (!empty($peerid_data) && !empty($ph1ent['pre-shared-key']))
484
						$pskconf .= trim($peerid_data) . " : PSK \"" . trim($ph1ent['pre-shared-key']) . "\"\n";
485
				}
486
			}
487
		}
488

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

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

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

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

    
512
			$ipsecconf .= "# This file is automatically generated. Do not edit\n";
513
			if (is_array($a_phase2) && count($a_phase2)) {
514
				$ipsecconf .= "config setup\n\tuniqueids = yes\n";
515

    
516
				foreach ($a_phase2 as $ph2ent) {
517
					$ikeid = $ph2ent['ikeid'];
518

    
519
					$ph1ent = false;
520
					if (!ipsec_lookup_phase1($ph2ent,$ph1ent))
521
						continue;
522

    
523
					if (isset($ph1ent['disabled']))
524
						continue;
525

    
526
					if (isset($ph2ent['disabled']))
527
						continue;
528

    
529
					$ikeid = $ph1ent['ikeid'];
530

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

    
535
					if (!isset($ph1ent['mobile'])) {
536
						$rgip = $rgmap[$ph1ent['remote-gateway']];
537
						if (!$rgip)
538
							continue;
539
					}
540

    
541
					$myid_type = $ph1ent['myid_type'];
542

    
543
					switch ($myid_type) {
544
					case "myaddress":
545
						$myid_type = "address";
546
						$myid_data = $ep;
547
						break;
548

    
549
					case "dyn_dns":
550
						$myid_type = "address";
551
						$myid_data = resolve_retry($ph1ent['myid_data']);
552
						break;
553

    
554
					case "address";
555
						$myid_data = $ph1ent['myid_data'];
556
						break;
557

    
558
					case "fqdn";
559
					case "keyid tag";
560
					case "user_fqdn";
561
					case "asn1dn";
562
						$myid_data = $ph1ent['myid_data'];
563
						if( $myid_data )
564
							$myid_data = "{$myid_data}";
565
						break;
566
					}
567

    
568
					$peerid_type = $ph1ent['peerid_type'];
569

    
570
					switch ($peerid_type) {
571
					case "peeraddress":
572
						$peerid_type = "address";
573
						$peerid_data = $rgip;
574
						break;
575

    
576
					case "address";
577
						$peerid_data = $ph1ent['peerid_data'];
578
						break;
579

    
580
					case "fqdn";
581
					case "keyid tag";
582
					case "user_fqdn";
583
					case "asn1dn";
584
						$peerid_data = $ph1ent['peerid_data'];
585
						if( $peerid_data )
586
							$peerid_data = "{$peerid_data}";
587
						break;
588
					}
589

    
590
					$passive = "start";
591
					if (isset($ph1ent['mobile'])) {
592
						$rgip = "%any";
593
						$passive = "route";
594
					}
595

    
596
					$keyexchange = "ikev1";
597
					if (!empty($ph1ent['iketype']) && $ph1ent['iketype'] != "ikev1")
598
						$keyexchange = "ikev2";
599

    
600
					if (is_array($ph1ent['encryption-algorithm']) && !empty($ph1ent['encryption-algorithm']['name']) && !empty($ph1ent['hash-algorithm'])) {
601
						$ealgosp1 = '';
602
						$ealg_id = $ph1ent['encryption-algorithm']['name'];
603
						$ealg_kl = $ph1ent['encryption-algorithm']['keylen'];
604
						if ($ealg_kl)
605
							$ealgosp1 = "ike = {$ealg_id}{$ealg_kl}-{$ph1ent['hash-algorithm']}";
606
						else
607
							$ealgosp1 = "ike = {$ealg_id}-{$ph1ent['hash-algorithm']}";
608

    
609
						$modp = vpn_ipsec_convert_to_modp($ph1ent['dhgroup']);
610
						if (!empty($modp))
611
							$ealgosp1 .= "-{$modp}";
612

    
613
						if ($keyexchange == "ikev1")
614
							$ealgosp1 .= "!";
615
					}
616

    
617
					if ($ph1ent['dpd_delay'] && $ph1ent['dpd_maxfail']) {
618
						if ($passive == "start")
619
							$dpdline = "dpdaction = restart";
620
						else
621
							$dpdline = "dpdaction = clear";
622
						$dpdline .= "\n\tdpddelay = {$ph1ent['dpd_delay']}s";
623
						$dpdline .= "\n\tdpdtimeout = {$ph1ent['dpd_maxfail']}s";
624
					} else
625
						$dpdline = "dpdaction = none";
626

    
627
					if (!empty($ph1ent['authentication_method']) && (strstr($ph1ent['authentication_method'], "xauth") || strstr($ph1ent['authentication_method'], "hybrid")))
628
						$xauth = "xauth = server";
629

    
630

    
631
					$lifeline = '';
632
					if ($ph1ent['lifetime'])
633
						$lifeline = "ikelifetime = {$ph1ent['lifetime']}s";
634

    
635
					/* Only specify peer ID if we are not dealing with a mobile PSK-only tunnel */
636
					$peerid_spec = '';
637
					if (!(($ph1ent['authentication_method'] == "pre_shared_key") && isset($ph1ent['mobile']))) {
638
						$peerid_spec = $peerid_data;
639
					}
640

    
641
					if (empty($ph1ent['mode']))
642
						$aggressive = "no";
643
					else if ($ph1ent['mode'] == "aggressive")
644
						$aggressive = "yes";
645
					else if ($ph1ent['mode'] == "main")
646
						$aggressive = "no";
647
					else
648
						$aggressive = "no";
649

    
650
					if (isset($ph2ent['mobile']) && !isset($a_client['enable']))
651
						continue;
652

    
653
					if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
654
						$tunneltype = "type = tunnel";
655

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

    
686
						if (!isset($ph2ent['mobile'])) {
687
							$remoteid_type = $ph2ent['remoteid']['type'];
688
							if ($remoteid_type != "address")
689
								$remoteid_type = "subnet";
690

    
691
							$remoteid_data = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']);
692
							$remoteid_spec = $remoteid_data;
693
						}
694

    
695
					} else {
696
						$tunneltype = "type = transport";
697
						$rgip = $rgmap[$ph1ent['remote-gateway']];
698

    
699
						if ((($ph1ent['authentication_method'] == "xauth_psk_server") ||
700
							($ph1ent['authentication_method'] == "pre_shared_key"))
701
							&& isset($ph1ent['mobile']))
702
							$localid_spec = "%any";
703
						else {
704
							$localid_data = ipsec_get_phase1_src($ph1ent);
705
							$localid_spec = $ep;
706
						}
707
						if (!isset($ph2ent['mobile'])) {
708
							$remoteid_data = $rgmap[$ph1ent['remote-gateway']];
709
							$remoteid_spec = $remoteid_data;
710
						}
711
					}
712
					$authentication = "";
713
					switch ($ph1ent['authentication_method']) {
714
					case 'xauth_rsa_server':
715
						$authentication = "leftauth = pubkey\n\trightauth = pubkey";
716
						$authentication .= "\n\leftauth2 = xauth-generic";
717
						break;
718
					case 'xauth_psk_server':
719
						$authentication = "leftauth = psk\n\trightauth = psk";
720
						$authentication .= "\n\tleftauth2 = xauth-generic";
721
						break;
722
					case 'pre_shared_key':
723
						$authentication = "leftauth = psk\n\trightauth = psk";
724
						break;
725
					case 'rsasig':
726
						$authentication = "leftauth = pubkey\n\trightauth = pubkey";
727
						break;
728
					case 'hybrid_rsa_server':
729
						$authentication = "leftauth = xauth-generic\n\trightauth = pubkey";
730
						$authentication .= "\n\trightauth2 = xauth";
731
						break;
732
					}
733

    
734
					if (isset($a_client['pfs_group']))
735
						$ph2ent['pfsgroup'] = $a_client['pfs_group'];
736
					$ealgosp2 = '';
737
					if ($ph2ent['protocol'] == 'esp') {
738
						if (is_array($ph2ent['encryption-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
739
							$ealgosp2arr = array();
740
							foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
741
								$ealg_id = $ealg['name'];
742
								$ealg_kl = $ealg['keylen'];
743

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

    
791

    
792
					if ($ph2ent['lifetime'])
793
						$lifeline = "ikelifetime = {$ph2ent['lifetime']}s";
794

    
795
					$ipsecconf .=<<<EOD
796

    
797
conn con{$ph2ent['ikeid']}-{$ph2ent['ikeid']}
798
	aggressive = {$aggressive}
799
	fragmentation = yes
800
	keyexchange = {$keyexchange}
801
	keyingtries = %forever
802
	reauth = yes
803
	reqid = {$ikeid}
804
	installpolicy = yes
805
	{$lifeline}
806
	{$tunneltype}
807
	{$dpdline}
808
	auto = {$passive}
809
	left = {$localid_spec}
810
	leftsubnet = {$localid_data}
811
	right = {$rgip}
812
	leftid = {$myid_data}
813

    
814
EOD;
815

    
816
					if (!empty($remoteid_spec))
817
						$ipsecconf .= "\trightsubnet = $remoteid_spec\n";
818
					if (!empty($ealgosp1))
819
						$ipsecconf .= "\t{$ealgosp1}\n";
820
					if (!empty($ealgosp2))
821
						$ipsecconf .= "\t{$ealgosp2}\n";
822
					if (!empty($authentication))
823
						$ipsecconf .= "\t{$authentication}\n";
824
					if (!empty($peerid_spec))
825
						$ipsecconf .= "\trightid = {$peerid_spec}\n";
826
				}
827
			}
828
		}
829
	}
830
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.conf", $ipsecconf);
831
	unset($ipsecconf);
832
	/* end ipsec.conf */
833

    
834
	/* mange process */
835
	if (isvalidpid("{$g['varrun_path']}/charon.pid")) {
836
		/* Read secrets */
837
		mwexec("/usr/local/sbin/ipsec rereadall", false);
838
		/* Update configuration changes */
839
		mwexec("/usr/local/sbin/ipsec update", false);
840
	} else {
841
		mwexec("/usr/local/sbin/ipsec start", false); 
842
	}
843
	vpn_ipsec_configure_loglevels();
844
	if ($natfilterrules == true)
845
		filter_configure();
846
	/* start filterdns, if necessary */
847
	if (count($filterdns_list) > 0) {
848
		$interval = 60;
849
		if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval']))
850
			$interval = $ipseccfg['dns-interval'];
851

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

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

    
869
	if ($g['booting'])
870
		echo "done\n";
871

    
872
	return count($filterdns_list);
873
}
874

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

    
884
	$ipseccfg = $config['ipsec'];
885

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

    
900
	/* if ipsec is enabled, start up again */
901
	if (isset($ipseccfg['enable'])) {
902
		log_error(gettext("Forcefully reloading IPsec"));
903
		vpn_ipsec_configure();
904
	}
905
}
906

    
907
/* master setup for vpn (mpd) */
908
function vpn_setup() {
909
	global $g;
910

    
911
	if ($g['platform'] == 'jail')
912
		return;
913

    
914
	/* start pptpd */
915
	vpn_pptpd_configure();
916

    
917
	/* start pppoe server */
918
	vpn_pppoes_configure();
919

    
920
	/* setup l2tp */
921
	vpn_l2tp_configure();
922
}
923

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

    
935
function vpn_pptpd_configure() {
936
	global $config, $g;
937

    
938
	$syscfg = $config['system'];
939
	$pptpdcfg = $config['pptpd'];
940

    
941
	if ($g['booting']) {
942
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
943
			return 0;
944

    
945
		echo gettext("Configuring PPTP VPN service... ");
946
	} else {
947
		/* kill mpd */
948
		killbypid("{$g['varrun_path']}/pptp-vpn.pid");
949

    
950
		/* wait for process to die */
951
		sleep(3);
952

    
953
		if (is_process_running("mpd -b")) {
954
			killbypid("{$g['varrun_path']}/pptp-vpn.pid");
955
			log_error(gettext("Could not kill mpd within 3 seconds.   Trying again."));
956
		}
957

    
958
		/* remove mpd.conf, if it exists */
959
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.conf");
960
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.links");
961
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.secret");
962
	}
963

    
964
	if (empty($pptpdcfg['n_pptp_units'])) {
965
		log_error("Something wrong in the PPTPd configuration. Preventing starting the daemon because issues would arise.");
966
		return;
967
	}
968

    
969
	/* make sure pptp-vpn directory exists */
970
	if (!file_exists("{$g['varetc_path']}/pptp-vpn"))
971
		mkdir("{$g['varetc_path']}/pptp-vpn");
972

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

    
982
			$mpdconf = <<<EOD
983
pptps:
984

    
985
EOD;
986

    
987
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
988
				$mpdconf .= "	load pt{$i}\n";
989
			}
990

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

    
993
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
994

    
995
				$mpdconf .= <<<EOD
996

    
997
pt{$i}:
998
	new -i pptpd{$i} pt{$i} pt{$i}
999
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
1000
	load pts
1001

    
1002
EOD;
1003
			}
1004

    
1005
			$mpdconf .=<<<EOD
1006

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

    
1027
EOD;
1028

    
1029
			if (!isset ($pptpdcfg['req128'])) {
1030
				$mpdconf .=<<<EOD
1031
	set ccp yes mpp-e40
1032
	set ccp yes mpp-e56
1033

    
1034
EOD;
1035
			}
1036

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

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

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

    
1065
EOD;
1066
			if (isset ($pptpdcfg['radius']['server2']['enable'])) {
1067
				$authport = (isset($pptpdcfg['radius']['server2']['port']) && strlen($pptpdcfg['radius']['server2']['port']) > 1) ? $pptpdcfg['radius']['server2']['port'] : 1812;
1068
				$acctport = $authport + 1;
1069
				$mpdconf .=<<<EOD
1070
	set radius server {$pptpdcfg['radius']['server2']['ip']} "{$pptpdcfg['radius']['server2']['secret2']}" {$authport} {$acctport}
1071

    
1072
EOD;
1073
			}
1074
			$mpdconf .=<<<EOD
1075
	set radius retries 3
1076
	set radius timeout 10
1077
	set auth enable radius-auth
1078

    
1079
EOD;
1080

    
1081
				if (isset ($pptpdcfg['radius']['accounting'])) {
1082
					$mpdconf .=<<<EOD
1083
	set auth enable radius-acct
1084
	set radius acct-update 300
1085

    
1086
EOD;
1087
				}
1088
			}
1089

    
1090
			fwrite($fd, $mpdconf);
1091
			fclose($fd);
1092
			unset($mpdconf);
1093

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

    
1101
			$mpdlinks = "";
1102

    
1103
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1104
				$mpdlinks .=<<<EOD
1105

    
1106
pt{$i}:
1107
	set link type pptp
1108
	set pptp enable incoming
1109
	set pptp disable originate
1110
	set pptp disable windowing
1111

    
1112
EOD;
1113
			}
1114

    
1115
			fwrite($fd, $mpdlinks);
1116
			fclose($fd);
1117
			unset($mpdlinks);
1118

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

    
1126
			$mpdsecret = "";
1127

    
1128
			if (is_array($pptpdcfg['user'])) {
1129
				foreach ($pptpdcfg['user'] as $user) {
1130
					$pass = str_replace('\\', '\\\\', $user['password']);
1131
					$pass = str_replace('"', '\"', $pass);
1132
					$mpdsecret .= "{$user['name']} \"{$pass}\" {$user['ip']}\n";
1133
				}
1134
			}
1135

    
1136
			fwrite($fd, $mpdsecret);
1137
			fclose($fd);
1138
			unset($mpdsecret);
1139
			chmod("{$g['varetc_path']}/pptp-vpn/mpd.secret", 0600);
1140

    
1141
			vpn_netgraph_support();
1142

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

    
1146
			break;
1147

    
1148
		case 'redir' :
1149
			break;
1150
	}
1151

    
1152
	if ($g['booting'])
1153
		echo "done\n";
1154

    
1155
	return 0;
1156
}
1157

    
1158
function vpn_pppoes_configure() {
1159
	global $config;
1160

    
1161
	if (is_array($config['pppoes']['pppoe'])) {
1162
		foreach ($config['pppoes']['pppoe'] as $pppoe)
1163
			vpn_pppoe_configure($pppoe);
1164
	}
1165
}
1166

    
1167
function vpn_pppoe_configure(&$pppoecfg) {
1168
	global $config, $g;
1169

    
1170
	$syscfg = $config['system'];
1171

    
1172
	/* create directory if it does not exist */
1173
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn"))
1174
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1175

    
1176
	if ($g['booting']) {
1177
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
1178
			return 0;
1179

    
1180
		echo gettext("Configuring PPPoE VPN service... ");
1181
	} else {
1182
		/* kill mpd */
1183
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1184

    
1185
		/* wait for process to die */
1186
		sleep(2);
1187

    
1188
	}
1189

    
1190
	switch ($pppoecfg['mode']) {
1191

    
1192
		case 'server' :
1193

    
1194
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1195

    
1196
			if ($pppoecfg['paporchap'] == "chap")
1197
				$paporchap = "set link enable chap";
1198
			else
1199
				$paporchap = "set link enable pap";
1200

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

    
1210
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1211
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1212
			}
1213

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

    
1216
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1217

    
1218
				if (isset($pppoecfg['radius']['radiusissueips']) && isset($pppoecfg['radius']['server']['enable'])) {
1219
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 0.0.0.0/0";
1220
				} else {
1221
					$isssue_ip_type = "set ipcp ranges {$pppoecfg['localip']}/32 {$clientip}/32";
1222
				}
1223

    
1224
				$mpdconf .=<<<EOD
1225

    
1226
poes{$pppoecfg['pppoeid']}{$i}:
1227
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1228
	{$isssue_ip_type}
1229
	load pppoe_standard
1230

    
1231
EOD;
1232
			}
1233

    
1234
			$mpdconf .=<<<EOD
1235

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

    
1262
EOD;
1263

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

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

    
1296
EOD;
1297

    
1298
				if (isset ($pppoecfg['radius']['accounting'])) {
1299
					$mpdconf .=<<<EOD
1300
	set auth enable radius-acct
1301

    
1302
EOD;
1303
				}
1304
			}
1305

    
1306
			fwrite($fd, $mpdconf);
1307
			fclose($fd);
1308
			unset($mpdconf);
1309

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

    
1317
			$mpdlinks = "";
1318

    
1319
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1320
				$mpdlinks .=<<<EOD
1321

    
1322
poes{$pppoecfg['pppoeid']}{$i}:
1323
	set phys type pppoe
1324
	set pppoe iface {$pppoe_interface}
1325
	set pppoe service "*"
1326
	set pppoe disable originate
1327
	set pppoe enable incoming
1328

    
1329
EOD;
1330
			}
1331

    
1332
			fwrite($fd, $mpdlinks);
1333
			fclose($fd);
1334
			unset($mpdlinks);
1335

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

    
1344
				$mpdsecret = "\n\n";
1345

    
1346
				if (!empty($pppoecfg['username'])) {
1347
					$item = explode(" ", $pppoecfg['username']);
1348
					foreach($item as $userdata) {
1349
						$data = explode(":", $userdata);
1350
						$mpdsecret .= "{$data[0]} \"" . base64_decode($data[1]) . "\" {$data[2]}\n";
1351
					}
1352
				}
1353

    
1354
				fwrite($fd, $mpdsecret);
1355
				fclose($fd);
1356
				unset($mpdsecret);
1357
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1358
			}
1359

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

    
1364
			/* Get support for netgraph(4) from the nic */
1365
			pfSense_ngctl_attach(".", $pppoe_interface);
1366
			/* fire up mpd */
1367
			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");
1368

    
1369
			break;
1370
	}
1371

    
1372
	if ($g['booting'])
1373
		echo gettext("done") . "\n";
1374

    
1375
	return 0;
1376
}
1377

    
1378
function vpn_l2tp_configure() {
1379
	global $config, $g;
1380

    
1381
	$syscfg = $config['system'];
1382
	$l2tpcfg = $config['l2tp'];
1383

    
1384
	/* create directory if it does not exist */
1385
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn"))
1386
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1387

    
1388
	if ($g['booting']) {
1389
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off"))
1390
			return 0;
1391

    
1392
		echo gettext("Configuring l2tp VPN service... ");
1393
	} else {
1394
		/* kill mpd */
1395
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1396

    
1397
		/* wait for process to die */
1398
		sleep(8);
1399

    
1400
	}
1401

    
1402
	/* make sure l2tp-vpn directory exists */
1403
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn"))
1404
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1405

    
1406
	switch ($l2tpcfg['mode']) {
1407

    
1408
		case 'server' :
1409
			if ($l2tpcfg['paporchap'] == "chap")
1410
				$paporchap = "set link enable chap";
1411
			else
1412
				$paporchap = "set link enable pap";
1413

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

    
1424
EOD;
1425

    
1426
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1427
				$mpdconf .= "	load l2tp{$i}\n";
1428
			}
1429

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

    
1432
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1433

    
1434
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1435
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1436
				} else {
1437
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1438
				}
1439

    
1440
				$mpdconf .=<<<EOD
1441

    
1442
l2tp{$i}:
1443
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1444
	{$isssue_ip_type}
1445
	load l2tp_standard
1446

    
1447
EOD;
1448
			}
1449

    
1450
			$mpdconf .=<<<EOD
1451

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

    
1468
EOD;
1469

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

    
1492
			if (isset ($l2tpcfg['radius']['enable'])) {
1493
				$mpdconf .=<<<EOD
1494
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1495
	set radius retries 3
1496
	set radius timeout 10
1497
	set auth enable radius-auth
1498

    
1499
EOD;
1500

    
1501
				if (isset ($l2tpcfg['radius']['accounting'])) {
1502
					$mpdconf .=<<<EOD
1503
	set auth enable radius-acct
1504

    
1505
EOD;
1506
				}
1507
			}
1508

    
1509
			fwrite($fd, $mpdconf);
1510
			fclose($fd);
1511
			unset($mpdconf);
1512

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

    
1520
			$mpdlinks = "";
1521

    
1522
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1523
				$mpdlinks .=<<<EOD
1524

    
1525
l2tp{$i}:
1526
	set link type l2tp
1527
	set l2tp enable incoming
1528
	set l2tp disable originate
1529

    
1530
EOD;
1531
			if (!empty($l2tpcfg['secret']))
1532
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
1533
			}
1534

    
1535
			fwrite($fd, $mpdlinks);
1536
			fclose($fd);
1537
			unset($mpdlinks);
1538

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

    
1546
			$mpdsecret = "\n\n";
1547

    
1548
			if (is_array($l2tpcfg['user'])) {
1549
				foreach ($l2tpcfg['user'] as $user)
1550
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1551
			}
1552

    
1553
			fwrite($fd, $mpdsecret);
1554
			fclose($fd);
1555
			unset($mpdsecret);
1556
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
1557

    
1558
			vpn_netgraph_support();
1559

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

    
1563
			break;
1564

    
1565
		case 'redir' :
1566
			break;
1567
	}
1568

    
1569
	if ($g['booting'])
1570
		echo "done\n";
1571

    
1572
	return 0;
1573
}
1574

    
1575
function vpn_ipsec_configure_preferoldsa() {
1576
	global $config;
1577
	if(isset($config['ipsec']['preferoldsa']))
1578
		mwexec("/sbin/sysctl -w net.key.preferred_oldsa=-30");
1579
	else
1580
		mwexec("/sbin/sysctl net.key.preferred_oldsa=0");
1581
}
1582

    
1583
?>
(58-58/67)