Projet

Général

Profil

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

univnautes / etc / inc / vpn.inc @ 9abaa8f7

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($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}"]))
52
			$forconfig ? $cfgtext[] = "{$lkey} = -1" : 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
		exec("/sbin/sysctl net.inet.ip.ipsec_in_use=0");
128

    
129
		return 0;
130
	} else {
131
		mwexec("/sbin/ifconfig enc0 up");
132
		mwexec("/sbin/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
		mwexec("/sbin/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
				$listeniflist = get_real_interface($a_phase1['interface']);
177

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

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

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

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

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

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

    
207
				if (is_array($a_phase2)) {
208
					/* step through each phase2 entry */
209
					foreach ($a_phase2 as $ph2ent) {
210
						$ikeid = $ph2ent['ikeid'];
211

    
212
						if (isset($ph2ent['disabled']))
213
							continue;
214

    
215
						if ($ikeid != $ph1ent['ikeid'])
216
							continue;
217

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

    
260
		$strongswan = <<<EOD
261

    
262
#Automatically generated please do not modify
263
starter {
264
    load_warning = no
265
}
266

    
267
charon {
268

    
269
        # number of worker threads in charon
270
        threads = 16
271

    
272
	# And two loggers using syslog. The subsections define the facility to log
273
	# to, currently one of: daemon, auth.
274
	syslog {
275

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

    
288
EOD;
289

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

    
293
		$strongswan .= "\tplugins {\n";
294

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

    
302
				$strongswan .= "\t\taddress = {$pool_address}\n";
303
				$strongswan .= "\t\tnetmask = {$pool_netmask}\n";
304
			}
305

    
306
			$cfgservers = array();
307
			if (!empty($a_client['dns_server1']))
308
				$cfgservers[] = $a_client['dns_server1'];
309
			if (!empty($a_client['dns_server2']))
310
				$cfgservers[] = $a_client['dns_server2'];
311
			if (!empty($a_client['dns_server3']))
312
				$cfgservers[] = $a_client['dns_server3'];
313
			if (!empty($a_client['dns_server4']))
314
				$cfgservers[] = $a_client['dns_server4'];
315

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

    
328
			if (!empty($a_client['net_list'])) {
329
				$net_list = '';
330
				foreach ($a_phase2 as $ph2ent) {
331
					if (isset($ph2ent['disabled']))
332
						continue;
333

    
334
					if (!isset($ph2ent['mobile']))
335
						continue;
336

    
337
					$localid = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
338

    
339
					if ($net_list)
340
						$net_list .= ", ";
341
					$net_list .= $localid;
342
				}
343

    
344
				if (!empty($net_list)) {
345
					$strongswan .= "\t\tsubnet = {$net_list}\n";
346
					$strongswan .= "\t\tsplit-include = {$net_list}\n";
347
					unset($net_list);
348
				}
349
			}
350

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

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

    
363
			if (!empty($a_client['login_banner']))
364
				$strongswan .= "\t\t28672 = {$a_client['login_banner']}\n";
365

    
366
			if (isset($a_client['save_passwd']))
367
				$strongswan .= "\t\t28673 = yes\n";
368

    
369
			if ($a_client['pfs_group'])
370
				$strongswan .= "\t\t28679 = {$a_client['pfs_group']}\n";
371
			$strongswan .= "\t\t}\n";
372

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

    
392
		$strongswan .= "\t}\n}\n";
393
		@file_put_contents("{$g['varetc_path']}/ipsec/strongswan.conf", $strongswan);
394
		unset($strongswan);
395

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

    
418
		$pskconf = "";
419

    
420
		if (is_array($a_phase1) && count($a_phase1)) {
421
			foreach ($a_phase1 as $ph1ent) {
422

    
423
				if (isset($ph1ent['disabled']))
424
					continue;
425

    
426
				if (strstr($ph1ent['authentication_method'],'rsa')) {
427
					$certline = '';
428

    
429
					if (strstr($authmethod,'rsa')) {
430

    
431
						$cert = lookup_cert($ph1ent['certref']);
432

    
433
						if (!$cert) {
434
							log_error(sprintf(gettext("Error: Invalid phase1 certificate reference for %s"), $ph1ent['name']));
435
							continue;
436
						}
437

    
438
						chmod($certpath, 0600);
439

    
440
						$keyfile = "cert-{$ikeid}.key";
441
						$keypath = "{$g['varetc_path']}/ipsec/{$keyfile}";
442

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

    
448
						chmod($keypath, 0600);
449
						/* XXX" Traffic selectors? */
450
						$pskconf .= " : RSA {$keypath}\n";
451

    
452
						$ca = lookup_ca($ph1ent['caref']);
453
						if ($ca) {
454
							$cafile = "ca-{$ikeid}.crt";
455
							$capath = "{$g['varetc_path']}/ipsec/ipsec.d/cacerts/{$cafile}";
456

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

    
463
							chmod($capath, 0600);
464
						}
465
					}
466
				} else {
467

    
468
					$peerid_type = $ph1ent['peerid_type'];
469

    
470
					switch ($peerid_type) {
471
						case "peeraddress":
472
							$peerid_type = "address";
473
							$peerid_data = $rgmap[$ph1ent['remote-gateway']];
474
							break;
475

    
476
						case "address";
477
							$peerid_data = $ph1ent['peerid_data'];
478
							break;
479

    
480
						case "fqdn";
481
						case "keyid tag";
482
						case "user_fqdn";
483
							$peerid_data = $ph1ent['peerid_data'];
484
							break;
485
					}
486

    
487
					if (!empty($peerid_data) && !empty($ph1ent['pre-shared-key']))
488
						$pskconf .= trim($peerid_data) . " : PSK \"" . trim($ph1ent['pre-shared-key']) . "\"\n";
489
				}
490
			}
491
		}
492

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

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

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

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

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

    
521
				foreach ($a_phase2 as $ph2ent) {
522
					$ikeid = $ph2ent['ikeid'];
523

    
524
					$ph1ent = false;
525
					if (!ipsec_lookup_phase1($ph2ent,$ph1ent))
526
						continue;
527

    
528
					if (isset($ph1ent['disabled']))
529
						continue;
530

    
531
					if (isset($ph2ent['disabled']))
532
						continue;
533

    
534
					$ikeid = $ph1ent['ikeid'];
535

    
536
					$ep = ipsec_get_phase1_src($ph1ent);
537
					if (!$ep)
538
						continue;
539

    
540
					if (!isset($ph1ent['mobile'])) {
541
						$rgip = $ph1ent['remote-gateway'];
542
						//$rgip = $rgmap[$ph1ent['remote-gateway']];
543
						//if (!$rgip)
544
						//	continue;
545
					}
546

    
547
					$myid_type = $ph1ent['myid_type'];
548

    
549
					switch ($myid_type) {
550
					case "myaddress":
551
						$myid_type = "address";
552
						$myid_data = $ep;
553
						break;
554

    
555
					case "dyn_dns":
556
						$myid_type = "address";
557
						$myid_data = resolve_retry($ph1ent['myid_data']);
558
						break;
559

    
560
					case "address";
561
						$myid_data = $ph1ent['myid_data'];
562
						break;
563

    
564
					case "fqdn";
565
					case "keyid tag";
566
					case "user_fqdn";
567
					case "asn1dn";
568
						$myid_data = $ph1ent['myid_data'];
569
						if( $myid_data )
570
							$myid_data = "{$myid_data}";
571
						break;
572
					}
573

    
574
					$peerid_type = $ph1ent['peerid_type'];
575

    
576
					switch ($peerid_type) {
577
					case "peeraddress":
578
						$peerid_type = "address";
579
						$peerid_data = $rgip;
580
						break;
581

    
582
					case "address";
583
						$peerid_data = $ph1ent['peerid_data'];
584
						break;
585

    
586
					case "fqdn";
587
					case "keyid tag";
588
					case "user_fqdn";
589
					case "asn1dn";
590
						$peerid_data = $ph1ent['peerid_data'];
591
						if( $peerid_data )
592
							$peerid_data = "{$peerid_data}";
593
						break;
594
					}
595

    
596
					$passive = "start";
597
					if (isset($ph1ent['mobile'])) {
598
						$rgip = "%any";
599
						$passive = "route";
600
					}
601

    
602
					$keyexchange = "ikev1";
603
					if (!empty($ph1ent['iketype']) && $ph1ent['iketype'] != "ikev1")
604
						$keyexchange = "ikev2";
605

    
606
					if (is_array($ph1ent['encryption-algorithm']) && !empty($ph1ent['encryption-algorithm']['name']) && !empty($ph1ent['hash-algorithm'])) {
607
						$ealgosp1 = '';
608
						$ealg_id = $ph1ent['encryption-algorithm']['name'];
609
						$ealg_kl = $ph1ent['encryption-algorithm']['keylen'];
610
						if ($ealg_kl)
611
							$ealgosp1 = "ike = {$ealg_id}{$ealg_kl}-{$ph1ent['hash-algorithm']}";
612
						else
613
							$ealgosp1 = "ike = {$ealg_id}-{$ph1ent['hash-algorithm']}";
614

    
615
						$modp = vpn_ipsec_convert_to_modp($ph1ent['dhgroup']);
616
						if (!empty($modp))
617
							$ealgosp1 .= "-{$modp}";
618

    
619
						if ($keyexchange == "ikev1")
620
							$ealgosp1 .= "!";
621
					}
622

    
623
					if ($ph1ent['dpd_delay'] && $ph1ent['dpd_maxfail']) {
624
						if ($passive == "start")
625
							$dpdline = "dpdaction = restart";
626
						else
627
							$dpdline = "dpdaction = clear";
628
						$dpdline .= "\n\tdpddelay = {$ph1ent['dpd_delay']}s";
629
						$dpdline .= "\n\tdpdtimeout = {$ph1ent['dpd_maxfail']}s";
630
					} else
631
						$dpdline = "dpdaction = none";
632

    
633
					if (!empty($ph1ent['authentication_method']) && (strstr($ph1ent['authentication_method'], "xauth") || strstr($ph1ent['authentication_method'], "hybrid")))
634
						$xauth = "xauth = server";
635

    
636

    
637
					$lifeline = '';
638
					if ($ph1ent['lifetime'])
639
						$lifeline = "ikelifetime = {$ph1ent['lifetime']}s";
640

    
641
					/* Only specify peer ID if we are not dealing with a mobile PSK-only tunnel */
642
					$peerid_spec = '';
643
					if (!(($ph1ent['authentication_method'] == "pre_shared_key") && isset($ph1ent['mobile']))) {
644
						$peerid_spec = $peerid_data;
645
					}
646

    
647
					if (empty($ph1ent['mode']))
648
						$aggressive = "no";
649
					else if ($ph1ent['mode'] == "aggressive")
650
						$aggressive = "yes";
651
					else if ($ph1ent['mode'] == "main")
652
						$aggressive = "no";
653
					else
654
						$aggressive = "no";
655

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

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

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

    
692
						if (!isset($ph2ent['mobile'])) {
693
							$remoteid_type = $ph2ent['remoteid']['type'];
694
							if ($remoteid_type != "address")
695
								$remoteid_type = "subnet";
696

    
697
							$remoteid_data = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']);
698
							$remoteid_spec = $remoteid_data;
699
						}
700

    
701
					} else {
702
						$tunneltype = "type = transport";
703
						//$rgip = $rgmap[$ph1ent['remote-gateway']];
704
						$rgip = $ph1ent['remote-gateway'];
705

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

    
741
					if (isset($a_client['pfs_group']))
742
						$ph2ent['pfsgroup'] = $a_client['pfs_group'];
743
					$ealgosp2 = '';
744
					if ($ph2ent['protocol'] == 'esp') {
745
						if (is_array($ph2ent['encryption-algorithm-option']) && is_array($ph2ent['hash-algorithm-option'])) {
746
							$ealgosp2arr = array();
747
							foreach ($ph2ent['encryption-algorithm-option'] as $ealg) {
748
								$ealg_id = $ealg['name'];
749
								$ealg_kl = $ealg['keylen'];
750

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

    
798

    
799
					if ($ph2ent['lifetime'])
800
						$lifeline = "ikelifetime = {$ph2ent['lifetime']}s";
801

    
802
					$ipsecconf .=<<<EOD
803

    
804
conn con{$ph2ent['ikeid']}-{$ph2ent['ikeid']}
805
	aggressive = {$aggressive}
806
	fragmentation = yes
807
	keyexchange = {$keyexchange}
808
	keyingtries = %forever
809
	reauth = yes
810
	reqid = {$ikeid}
811
	installpolicy = yes
812
	{$lifeline}
813
	{$tunneltype}
814
	{$dpdline}
815
	auto = {$passive}
816
	left = {$localid_spec}
817
	leftsubnet = {$localid_data}
818
	right = {$rgip}
819
	leftid = {$myid_data}
820

    
821
EOD;
822

    
823
					if (!empty($remoteid_spec))
824
						$ipsecconf .= "\trightsubnet = $remoteid_spec\n";
825
					if (!empty($ealgosp1))
826
						$ipsecconf .= "\t{$ealgosp1}\n";
827
					if (!empty($ealgosp2))
828
						$ipsecconf .= "\t{$ealgosp2}\n";
829
					if (!empty($authentication))
830
						$ipsecconf .= "\t{$authentication}\n";
831
					if (!empty($peerid_spec))
832
						$ipsecconf .= "\trightid = {$peerid_spec}\n";
833
				}
834
			}
835
		}
836
	}
837
	@file_put_contents("{$g['varetc_path']}/ipsec/ipsec.conf", $ipsecconf);
838
	unset($ipsecconf);
839
	/* end ipsec.conf */
840

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

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

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

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

    
876
	if ($g['booting'])
877
		echo "done\n";
878

    
879
	return count($filterdns_list);
880
}
881

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

    
891
	$ipseccfg = $config['ipsec'];
892

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

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

    
914
/* master setup for vpn (mpd) */
915
function vpn_setup() {
916
	global $g;
917

    
918
	if ($g['platform'] == 'jail')
919
		return;
920

    
921
	/* start pptpd */
922
	vpn_pptpd_configure();
923

    
924
	/* start pppoe server */
925
	vpn_pppoes_configure();
926

    
927
	/* setup l2tp */
928
	vpn_l2tp_configure();
929
}
930

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

    
942
function vpn_pptpd_configure() {
943
	global $config, $g;
944

    
945
	$syscfg = $config['system'];
946
	$pptpdcfg = $config['pptpd'];
947

    
948
	if ($g['booting']) {
949
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
950
			return 0;
951

    
952
		echo gettext("Configuring PPTP VPN service... ");
953
	} else {
954
		/* kill mpd */
955
		killbypid("{$g['varrun_path']}/pptp-vpn.pid");
956

    
957
		/* wait for process to die */
958
		sleep(3);
959

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

    
965
		/* remove mpd.conf, if it exists */
966
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.conf");
967
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.links");
968
		unlink_if_exists("{$g['varetc_path']}/pptp-vpn/mpd.secret");
969
	}
970

    
971
	if (empty($pptpdcfg['n_pptp_units'])) {
972
		log_error("Something wrong in the PPTPd configuration. Preventing starting the daemon because issues would arise.");
973
		return;
974
	}
975

    
976
	/* make sure pptp-vpn directory exists */
977
	if (!file_exists("{$g['varetc_path']}/pptp-vpn"))
978
		mkdir("{$g['varetc_path']}/pptp-vpn");
979

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

    
989
			$mpdconf = <<<EOD
990
pptps:
991

    
992
EOD;
993

    
994
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
995
				$mpdconf .= "	load pt{$i}\n";
996
			}
997

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

    
1000
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
1001

    
1002
				$mpdconf .= <<<EOD
1003

    
1004
pt{$i}:
1005
	new -i pptpd{$i} pt{$i} pt{$i}
1006
	set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
1007
	load pts
1008

    
1009
EOD;
1010
			}
1011

    
1012
			$mpdconf .=<<<EOD
1013

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

    
1034
EOD;
1035

    
1036
			if (!isset ($pptpdcfg['req128'])) {
1037
				$mpdconf .=<<<EOD
1038
	set ccp yes mpp-e40
1039
	set ccp yes mpp-e56
1040

    
1041
EOD;
1042
			}
1043

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

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

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

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

    
1079
EOD;
1080
			}
1081
			$mpdconf .=<<<EOD
1082
	set radius retries 3
1083
	set radius timeout 10
1084
	set auth enable radius-auth
1085

    
1086
EOD;
1087

    
1088
				if (isset ($pptpdcfg['radius']['accounting'])) {
1089
					$mpdconf .=<<<EOD
1090
	set auth enable radius-acct
1091
	set radius acct-update 300
1092

    
1093
EOD;
1094
				}
1095
			}
1096

    
1097
			fwrite($fd, $mpdconf);
1098
			fclose($fd);
1099
			unset($mpdconf);
1100

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

    
1108
			$mpdlinks = "";
1109

    
1110
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1111
				$mpdlinks .=<<<EOD
1112

    
1113
pt{$i}:
1114
	set link type pptp
1115
	set pptp enable incoming
1116
	set pptp disable originate
1117
	set pptp disable windowing
1118

    
1119
EOD;
1120
			}
1121

    
1122
			fwrite($fd, $mpdlinks);
1123
			fclose($fd);
1124
			unset($mpdlinks);
1125

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

    
1133
			$mpdsecret = "";
1134

    
1135
			if (is_array($pptpdcfg['user'])) {
1136
				foreach ($pptpdcfg['user'] as $user) {
1137
					$pass = str_replace('\\', '\\\\', $user['password']);
1138
					$pass = str_replace('"', '\"', $pass);
1139
					$mpdsecret .= "{$user['name']} \"{$pass}\" {$user['ip']}\n";
1140
				}
1141
			}
1142

    
1143
			fwrite($fd, $mpdsecret);
1144
			fclose($fd);
1145
			unset($mpdsecret);
1146
			chmod("{$g['varetc_path']}/pptp-vpn/mpd.secret", 0600);
1147

    
1148
			vpn_netgraph_support();
1149

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

    
1153
			break;
1154

    
1155
		case 'redir' :
1156
			break;
1157
	}
1158

    
1159
	if ($g['booting'])
1160
		echo "done\n";
1161

    
1162
	return 0;
1163
}
1164

    
1165
function vpn_pppoes_configure() {
1166
	global $config;
1167

    
1168
	if (is_array($config['pppoes']['pppoe'])) {
1169
		foreach ($config['pppoes']['pppoe'] as $pppoe)
1170
			vpn_pppoe_configure($pppoe);
1171
	}
1172
}
1173

    
1174
function vpn_pppoe_configure(&$pppoecfg) {
1175
	global $config, $g;
1176

    
1177
	$syscfg = $config['system'];
1178

    
1179
	/* create directory if it does not exist */
1180
	if (!is_dir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn"))
1181
		mkdir("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn");
1182

    
1183
	if ($g['booting']) {
1184
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
1185
			return 0;
1186

    
1187
		echo gettext("Configuring PPPoE VPN service... ");
1188
	} else {
1189
		/* kill mpd */
1190
		killbypid("{$g['varrun_path']}/pppoe{$pppoecfg['pppoeid']}-vpn.pid");
1191

    
1192
		/* wait for process to die */
1193
		sleep(2);
1194

    
1195
	}
1196

    
1197
	switch ($pppoecfg['mode']) {
1198

    
1199
		case 'server' :
1200

    
1201
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1202

    
1203
			if ($pppoecfg['paporchap'] == "chap")
1204
				$paporchap = "set link enable chap";
1205
			else
1206
				$paporchap = "set link enable pap";
1207

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

    
1217
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1218
				$mpdconf .= "	load poes{$pppoecfg['pppoeid']}{$i}\n";
1219
			}
1220

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

    
1223
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1224

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

    
1231
				$mpdconf .=<<<EOD
1232

    
1233
poes{$pppoecfg['pppoeid']}{$i}:
1234
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1235
	{$isssue_ip_type}
1236
	load pppoe_standard
1237

    
1238
EOD;
1239
			}
1240

    
1241
			$mpdconf .=<<<EOD
1242

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

    
1269
EOD;
1270

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

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

    
1303
EOD;
1304

    
1305
				if (isset ($pppoecfg['radius']['accounting'])) {
1306
					$mpdconf .=<<<EOD
1307
	set auth enable radius-acct
1308

    
1309
EOD;
1310
				}
1311
			}
1312

    
1313
			fwrite($fd, $mpdconf);
1314
			fclose($fd);
1315
			unset($mpdconf);
1316

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

    
1324
			$mpdlinks = "";
1325

    
1326
			for ($i = 0; $i < $pppoecfg['n_pppoe_units']; $i++) {
1327
				$mpdlinks .=<<<EOD
1328

    
1329
poes{$pppoecfg['pppoeid']}{$i}:
1330
	set phys type pppoe
1331
	set pppoe iface {$pppoe_interface}
1332
	set pppoe service "*"
1333
	set pppoe disable originate
1334
	set pppoe enable incoming
1335

    
1336
EOD;
1337
			}
1338

    
1339
			fwrite($fd, $mpdlinks);
1340
			fclose($fd);
1341
			unset($mpdlinks);
1342

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

    
1351
				$mpdsecret = "\n\n";
1352

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

    
1361
				fwrite($fd, $mpdsecret);
1362
				fclose($fd);
1363
				unset($mpdsecret);
1364
				chmod("{$g['varetc_path']}/pppoe{$pppoecfg['pppoeid']}-vpn/mpd.secret", 0600);
1365
			}
1366

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

    
1371
			/* Get support for netgraph(4) from the nic */
1372
			pfSense_ngctl_attach(".", $pppoe_interface);
1373
			/* fire up mpd */
1374
			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");
1375

    
1376
			break;
1377
	}
1378

    
1379
	if ($g['booting'])
1380
		echo gettext("done") . "\n";
1381

    
1382
	return 0;
1383
}
1384

    
1385
function vpn_l2tp_configure() {
1386
	global $config, $g;
1387

    
1388
	$syscfg = $config['system'];
1389
	$l2tpcfg = $config['l2tp'];
1390

    
1391
	/* create directory if it does not exist */
1392
	if (!is_dir("{$g['varetc_path']}/l2tp-vpn"))
1393
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1394

    
1395
	if ($g['booting']) {
1396
		if (!$l2tpcfg['mode'] || ($l2tpcfg['mode'] == "off"))
1397
			return 0;
1398

    
1399
		echo gettext("Configuring l2tp VPN service... ");
1400
	} else {
1401
		/* kill mpd */
1402
		killbypid("{$g['varrun_path']}/l2tp-vpn.pid");
1403

    
1404
		/* wait for process to die */
1405
		sleep(8);
1406

    
1407
	}
1408

    
1409
	/* make sure l2tp-vpn directory exists */
1410
	if (!file_exists("{$g['varetc_path']}/l2tp-vpn"))
1411
		mkdir("{$g['varetc_path']}/l2tp-vpn");
1412

    
1413
	switch ($l2tpcfg['mode']) {
1414

    
1415
		case 'server' :
1416
			if ($l2tpcfg['paporchap'] == "chap")
1417
				$paporchap = "set link enable chap";
1418
			else
1419
				$paporchap = "set link enable pap";
1420

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

    
1431
EOD;
1432

    
1433
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1434
				$mpdconf .= "	load l2tp{$i}\n";
1435
			}
1436

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

    
1439
				$clientip = long2ip32(ip2long($l2tpcfg['remoteip']) + $i);
1440

    
1441
				if (isset ($l2tpcfg['radius']['radiusissueips']) && isset ($l2tpcfg['radius']['enable'])) {
1442
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 0.0.0.0/0";
1443
				} else {
1444
					$isssue_ip_type = "set ipcp ranges {$l2tpcfg['localip']}/32 {$clientip}/32";
1445
				}
1446

    
1447
				$mpdconf .=<<<EOD
1448

    
1449
l2tp{$i}:
1450
	new -i l2tp{$i} l2tp{$i} l2tp{$i}
1451
	{$isssue_ip_type}
1452
	load l2tp_standard
1453

    
1454
EOD;
1455
			}
1456

    
1457
			$mpdconf .=<<<EOD
1458

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

    
1475
EOD;
1476

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

    
1499
			if (isset ($l2tpcfg['radius']['enable'])) {
1500
				$mpdconf .=<<<EOD
1501
	set radius server {$l2tpcfg['radius']['server']} "{$l2tpcfg['radius']['secret']}"
1502
	set radius retries 3
1503
	set radius timeout 10
1504
	set auth enable radius-auth
1505

    
1506
EOD;
1507

    
1508
				if (isset ($l2tpcfg['radius']['accounting'])) {
1509
					$mpdconf .=<<<EOD
1510
	set auth enable radius-acct
1511

    
1512
EOD;
1513
				}
1514
			}
1515

    
1516
			fwrite($fd, $mpdconf);
1517
			fclose($fd);
1518
			unset($mpdconf);
1519

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

    
1527
			$mpdlinks = "";
1528

    
1529
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1530
				$mpdlinks .=<<<EOD
1531

    
1532
l2tp{$i}:
1533
	set link type l2tp
1534
	set l2tp enable incoming
1535
	set l2tp disable originate
1536

    
1537
EOD;
1538
			if (!empty($l2tpcfg['secret']))
1539
					$mpdlinks .= "set l2tp secret {$l2tpcfg['secret']}\n";
1540
			}
1541

    
1542
			fwrite($fd, $mpdlinks);
1543
			fclose($fd);
1544
			unset($mpdlinks);
1545

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

    
1553
			$mpdsecret = "\n\n";
1554

    
1555
			if (is_array($l2tpcfg['user'])) {
1556
				foreach ($l2tpcfg['user'] as $user)
1557
					$mpdsecret .= "{$user['name']} \"{$user['password']}\" {$user['ip']}\n";
1558
			}
1559

    
1560
			fwrite($fd, $mpdsecret);
1561
			fclose($fd);
1562
			unset($mpdsecret);
1563
			chmod("{$g['varetc_path']}/l2tp-vpn/mpd.secret", 0600);
1564

    
1565
			vpn_netgraph_support();
1566

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

    
1570
			break;
1571

    
1572
		case 'redir' :
1573
			break;
1574
	}
1575

    
1576
	if ($g['booting'])
1577
		echo "done\n";
1578

    
1579
	return 0;
1580
}
1581

    
1582
function vpn_ipsec_configure_preferoldsa() {
1583
	global $config;
1584
	if(isset($config['ipsec']['preferoldsa']))
1585
		mwexec("/sbin/sysctl -w net.key.preferred_oldsa=-30");
1586
	else
1587
		mwexec("/sbin/sysctl net.key.preferred_oldsa=0");
1588
}
1589

    
1590
?>
(58-58/67)