Project

General

Profile

Download (43.9 KB) Statistics
| Branch: | Tag: | Revision:
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:	/usr/bin/killall	/usr/local/sbin/sasyncd	/sbin/ifconfig	/sbin/sysctl
38
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/setkey	/sbin/route	/bin/mkdir
39
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/ipsec	/usr/local/libexec/ipsec/charon /usr/local/libexec/ipsec/starter
40
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/filterdns	/usr/local/sbin/mpd4
41
	pfSense_MODULE:	vpn
42
*/
43

    
44
require_once("ipsec.inc");
45

    
46
function vpn_ipsec_configure_loglevels()
47
{
48
	global $config, $ipsec_loglevels;
49

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

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

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

    
91
	return $convertion;
92
}
93

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

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

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

    
105
	vpn_ipsec_configure_preferoldsa();
106

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

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

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

    
122
		/* flush SPD and SAD 
123
		mwexec("/usr/local/sbin/setkey -F");
124
		mwexec("/usr/local/sbin/setkey -FP");
125
		*/
126

    
127
		/* disallow IPSEC, it is off */
128
		mwexec("/sbin/ifconfig enc0 down");
129
		exec("/sbin/sysctl net.inet.ip.ipsec_in_use=0");
130

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

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

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

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

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

    
174
				$listeniflist = get_real_interface($a_phase1['interface']);
175

    
176
				$ep = ipsec_get_phase1_src($ph1ent);
177
				if (!is_ipaddr($ep))
178
					continue;
179

    
180
				if(!in_array($ep,$ipmap))
181
					$ipmap[] = $ep;
182

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

    
186
				if (isset ($ph1ent['mobile']))
187
					continue;
188

    
189
				$rg = $ph1ent['remote-gateway'];
190

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

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

    
210
						if (isset($ph2ent['disabled']))
211
							continue;
212

    
213
						if ($ikeid != $ph1ent['ikeid'])
214
							continue;
215

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

    
258
		$strongswan = <<<EOD
259

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

    
265
charon {
266

    
267
        # number of worker threads in charon
268
        threads = 16
269

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

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

    
286
EOD;
287

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

    
291
		$strongswan .= "\tplugins {\n";
292

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

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

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

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

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

    
332
					if (!isset($ph2ent['mobile']))
333
						continue;
334

    
335
					$localid = ipsec_idinfo_to_cidr($ph2ent['localid'], true, $ph2ent['mode']);
336

    
337
					if ($net_list)
338
						$net_list .= ", ";
339
					$net_list .= $localid;
340
				}
341

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

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

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

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

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

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

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

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

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

    
416
		$pskconf = "";
417

    
418
		if (is_array($a_phase1) && count($a_phase1)) {
419
			foreach ($a_phase1 as $ph1ent) {
420

    
421
				if (isset($ph1ent['disabled']))
422
					continue;
423

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

    
427
					if (strstr($authmethod,'rsa')) {
428

    
429
						$cert = lookup_cert($ph1ent['certref']);
430

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

    
436
						chmod($certpath, 0600);
437

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

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

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

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

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

    
461
							chmod($capath, 0600);
462
						}
463
					}
464
				} else {
465

    
466
					$peerid_type = $ph1ent['peerid_type'];
467

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

    
474
						case "address";
475
							$peerid_data = $ph1ent['peerid_data'];
476
							break;
477

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

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

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

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

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

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

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

    
518
				foreach ($a_phase2 as $ph2ent) {
519
					$ikeid = $ph2ent['ikeid'];
520

    
521
					$ph1ent = false;
522
					if (!ipsec_lookup_phase1($ph2ent,$ph1ent))
523
						continue;
524

    
525
					if (isset($ph1ent['disabled']))
526
						continue;
527

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

    
531
					$ikeid = $ph1ent['ikeid'];
532

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

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

    
543
					$myid_type = $ph1ent['myid_type'];
544

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

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

    
556
					case "address";
557
						$myid_data = $ph1ent['myid_data'];
558
						break;
559

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

    
570
					$peerid_type = $ph1ent['peerid_type'];
571

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

    
578
					case "address";
579
						$peerid_data = $ph1ent['peerid_data'];
580
						break;
581

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

    
592
					$genp = "no";
593
					if (!empty($ph1ent['generate_policy']) && $ph1ent['generate_policy'] != "off")
594
						$genp = "yes";
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

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

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

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

    
797

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

    
801
					$ipsecconf .=<<<EOD
802

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

    
820
EOD;
821

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

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

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

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

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

    
878
	return count($filterdns_list);
879
}
880

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
991
EOD;
992

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

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

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

    
1001
				$mpdconf .= <<<EOD
1002

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

    
1008
EOD;
1009
			}
1010

    
1011
			$mpdconf .=<<<EOD
1012

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

    
1033
EOD;
1034

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

    
1040
EOD;
1041
			}
1042

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

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

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

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

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

    
1080
EOD;
1081

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

    
1087
EOD;
1088
				}
1089
			}
1090

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

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

    
1102
			$mpdlinks = "";
1103

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

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

    
1113
EOD;
1114
			}
1115

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

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

    
1127
			$mpdsecret = "";
1128

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

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

    
1142
			vpn_netgraph_support();
1143

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

    
1147
			break;
1148

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

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

    
1156
	return 0;
1157
}
1158

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

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

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

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

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

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

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

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

    
1189
	}
1190

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

    
1193
		case 'server' :
1194

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

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

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

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

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

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

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

    
1225
				$mpdconf .=<<<EOD
1226

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

    
1232
EOD;
1233
			}
1234

    
1235
			$mpdconf .=<<<EOD
1236

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

    
1263
EOD;
1264

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

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

    
1292
EOD;
1293

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

    
1298
EOD;
1299
				}
1300
			}
1301

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

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

    
1313
			$mpdlinks = "";
1314

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

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

    
1325
EOD;
1326
			}
1327

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

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

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

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

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

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

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

    
1365
			break;
1366
	}
1367

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

    
1371
	return 0;
1372
}
1373

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

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

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

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

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

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

    
1396
	}
1397

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

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

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

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

    
1420
EOD;
1421

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

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

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

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

    
1436
				$mpdconf .=<<<EOD
1437

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

    
1443
EOD;
1444
			}
1445

    
1446
			$mpdconf .=<<<EOD
1447

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

    
1464
EOD;
1465

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

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

    
1490
EOD;
1491

    
1492
				if (isset ($l2tpcfg['radius']['accounting'])) {
1493
					$mpdconf .=<<<EOD
1494
	set auth enable radius-acct
1495

    
1496
EOD;
1497
				}
1498
			}
1499

    
1500
			fwrite($fd, $mpdconf);
1501
			fclose($fd);
1502
			unset($mpdconf);
1503

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

    
1511
			$mpdlinks = "";
1512

    
1513
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1514
				$mpdlinks .=<<<EOD
1515

    
1516
l2tp{$i}:
1517
	set link type l2tp
1518
	set l2tp enable incoming
1519
	set l2tp disable originate
1520

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

    
1526
			fwrite($fd, $mpdlinks);
1527
			fclose($fd);
1528
			unset($mpdlinks);
1529

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

    
1537
			$mpdsecret = "\n\n";
1538

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

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

    
1549
			vpn_netgraph_support();
1550

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

    
1554
			break;
1555

    
1556
		case 'redir' :
1557
			break;
1558
	}
1559

    
1560
	if ($g['booting'])
1561
		echo "done\n";
1562

    
1563
	return 0;
1564
}
1565

    
1566
function vpn_ipsec_configure_preferoldsa() {
1567
	global $config;
1568
	if(isset($config['ipsec']['preferoldsa']))
1569
		mwexec("/sbin/sysctl -w net.key.preferred_oldsa=-30");
1570
	else
1571
		mwexec("/sbin/sysctl net.key.preferred_oldsa=0");
1572
}
1573

    
1574
?>
(58-58/67)