Projet

Général

Profil

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

univnautes / etc / inc / vpn.inc @ f1bede03

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
				if ($key['ident'] == "allusers")
504
					$key['ident'] = '';
505
				$pskconf .= "{$key['ident']} : PSK \"{$key['pre-shared-key']}\"\n";
506
			}
507
		}
508

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

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

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

    
523
				foreach ($a_phase2 as $ph2ent) {
524
					$ikeid = $ph2ent['ikeid'];
525

    
526
					$ph1ent = false;
527
					if (!ipsec_lookup_phase1($ph2ent,$ph1ent))
528
						continue;
529

    
530
					if (isset($ph1ent['disabled']))
531
						continue;
532

    
533
					if (isset($ph2ent['disabled']))
534
						continue;
535

    
536
					if (isset($ph2ent['mobile']) && !isset($a_client['enable']))
537
						continue;
538

    
539
					$ikeid = $ph1ent['ikeid'];
540

    
541
					$ep = ipsec_get_phase1_src($ph1ent);
542
					if (!$ep)
543
						continue;
544

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

    
552
					$keyexchange = "ikev1";
553
					if (!empty($ph1ent['iketype']) && $ph1ent['iketype'] != "ikev1")
554
						$keyexchange = "ikev2";
555

    
556
					$myid_type = $ph1ent['myid_type'];
557
					switch ($myid_type) {
558
					case "myaddress":
559
						$myid_type = "address";
560
						$myid_data = $ep;
561
						break;
562

    
563
					case "dyn_dns":
564
						$myid_type = "address";
565
						$myid_data = resolve_retry($ph1ent['myid_data']);
566
						break;
567

    
568
					case "address";
569
						$myid_data = $ph1ent['myid_data'];
570
						break;
571

    
572
					case "fqdn";
573
					case "keyid tag";
574
					case "user_fqdn";
575
					case "asn1dn";
576
						$myid_data = $ph1ent['myid_data'];
577
						if( $myid_data )
578
							$myid_data = "{$myid_data}";
579
						break;
580
					}
581

    
582
					$peerid_type = $ph1ent['peerid_type'];
583
					switch ($peerid_type) {
584
					case "peeraddress":
585
						$peerid_type = "address";
586
						$peerid_data = $rgip;
587
						break;
588

    
589
					case "address";
590
						$peerid_data = $ph1ent['peerid_data'];
591
						break;
592

    
593
					case "fqdn";
594
					case "keyid tag";
595
					case "user_fqdn";
596
					case "asn1dn";
597
						$peerid_data = $ph1ent['peerid_data'];
598
						if( $peerid_data )
599
							$peerid_data = "{$peerid_data}";
600
						break;
601
					}
602

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

    
612
						$modp = vpn_ipsec_convert_to_modp($ph1ent['dhgroup']);
613
						if (!empty($modp))
614
							$ealgosp1 .= "-{$modp}";
615

    
616
						if ($keyexchange == "ikev1")
617
							$ealgosp1 .= "!";
618
					}
619

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

    
630
					if (!empty($ph1ent['authentication_method']) && (strpos($ph1ent['authentication_method'], "xauth") || strpos($ph1ent['authentication_method'], "hybrid")))
631
						$xauth = "xauth = server";
632

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

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

    
643
					if ($ph1ent['mode'] == "aggressive")
644
						$aggressive = "yes";
645
					else
646
						$aggressive = "no";
647

    
648
					if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) {
649
						$tunneltype = "type = tunnel";
650

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

    
681
						if (!isset($ph2ent['mobile'])) {
682
							$remoteid_type = $ph2ent['remoteid']['type'];
683
							if ($remoteid_type != "address")
684
								$remoteid_type = "subnet";
685

    
686
							$remoteid_data = ipsec_idinfo_to_cidr($ph2ent['remoteid'], false, $ph2ent['mode']);
687
							$remoteid_spec = $remoteid_data;
688
						} else
689
							/* XXX: Should check type of ip used on VPN? */
690
							$remoteid_spec = "0.0.0.0/0";
691

    
692
					} else {
693
						$tunneltype = "type = transport";
694
						$rgip = $ph1ent['remote-gateway'];
695

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

    
730
					if (isset($a_client['pfs_group']))
731
						$ph2ent['pfsgroup'] = $a_client['pfs_group'];
732

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

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

    
788

    
789
					if ($ph2ent['lifetime'])
790
						$lifeline = "ikelifetime = {$ph2ent['lifetime']}s";
791

    
792
					$ipsecconf .=<<<EOD
793

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

    
811
EOD;
812

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

    
831
	/* mange process */
832
	if (isvalidpid("{$g['varrun_path']}/charon.pid")) {
833
		/* Read secrets */
834
		mwexec("/usr/local/sbin/ipsec rereadall", false);
835
		/* Update configuration changes */
836
		mwexec("/usr/local/sbin/ipsec update", false);
837
	} else {
838
		mwexec("/usr/local/sbin/ipsec start", false); 
839
	}
840

    
841
	if ($natfilterrules == true)
842
		filter_configure();
843
	/* start filterdns, if necessary */
844
	if (count($filterdns_list) > 0) {
845
		$interval = 60;
846
		if (!empty($ipseccfg['dns-interval']) && is_numeric($ipseccfg['dns-interval']))
847
			$interval = $ipseccfg['dns-interval'];
848

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

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

    
866
	if ($g['booting'])
867
		echo "done\n";
868

    
869
	return count($filterdns_list);
870
}
871

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

    
881
	$ipseccfg = $config['ipsec'];
882

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

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

    
904
/* master setup for vpn (mpd) */
905
function vpn_setup() {
906
	global $g;
907

    
908
	if ($g['platform'] == 'jail')
909
		return;
910

    
911
	/* start pptpd */
912
	vpn_pptpd_configure();
913

    
914
	/* start pppoe server */
915
	vpn_pppoes_configure();
916

    
917
	/* setup l2tp */
918
	vpn_l2tp_configure();
919
}
920

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

    
932
function vpn_pptpd_configure() {
933
	global $config, $g;
934

    
935
	$syscfg = $config['system'];
936
	$pptpdcfg = $config['pptpd'];
937

    
938
	if ($g['booting']) {
939
		if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
940
			return 0;
941

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

    
947
		/* wait for process to die */
948
		sleep(3);
949

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

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

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

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

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

    
979
			$mpdconf = <<<EOD
980
pptps:
981

    
982
EOD;
983

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

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

    
990
				$clientip = long2ip32(ip2long($pptpdcfg['remoteip']) + $i);
991

    
992
				$mpdconf .= <<<EOD
993

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

    
999
EOD;
1000
			}
1001

    
1002
			$mpdconf .=<<<EOD
1003

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

    
1024
EOD;
1025

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

    
1031
EOD;
1032
			}
1033

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

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

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

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

    
1069
EOD;
1070
			}
1071
			$mpdconf .=<<<EOD
1072
	set radius retries 3
1073
	set radius timeout 10
1074
	set auth enable radius-auth
1075

    
1076
EOD;
1077

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

    
1083
EOD;
1084
				}
1085
			}
1086

    
1087
			fwrite($fd, $mpdconf);
1088
			fclose($fd);
1089
			unset($mpdconf);
1090

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

    
1098
			$mpdlinks = "";
1099

    
1100
			for ($i = 0; $i < $pptpdcfg['n_pptp_units']; $i++) {
1101
				$mpdlinks .=<<<EOD
1102

    
1103
pt{$i}:
1104
	set link type pptp
1105
	set pptp enable incoming
1106
	set pptp disable originate
1107
	set pptp disable windowing
1108

    
1109
EOD;
1110
			}
1111

    
1112
			fwrite($fd, $mpdlinks);
1113
			fclose($fd);
1114
			unset($mpdlinks);
1115

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

    
1123
			$mpdsecret = "";
1124

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

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

    
1138
			vpn_netgraph_support();
1139

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

    
1143
			break;
1144

    
1145
		case 'redir' :
1146
			break;
1147
	}
1148

    
1149
	if ($g['booting'])
1150
		echo "done\n";
1151

    
1152
	return 0;
1153
}
1154

    
1155
function vpn_pppoes_configure() {
1156
	global $config;
1157

    
1158
	if (is_array($config['pppoes']['pppoe'])) {
1159
		foreach ($config['pppoes']['pppoe'] as $pppoe)
1160
			vpn_pppoe_configure($pppoe);
1161
	}
1162
}
1163

    
1164
function vpn_pppoe_configure(&$pppoecfg) {
1165
	global $config, $g;
1166

    
1167
	$syscfg = $config['system'];
1168

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

    
1173
	if ($g['booting']) {
1174
		if (!$pppoecfg['mode'] || ($pppoecfg['mode'] == "off"))
1175
			return 0;
1176

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

    
1182
		/* wait for process to die */
1183
		sleep(2);
1184

    
1185
	}
1186

    
1187
	switch ($pppoecfg['mode']) {
1188

    
1189
		case 'server' :
1190

    
1191
			$pppoe_interface = get_real_interface($pppoecfg['interface']);
1192

    
1193
			if ($pppoecfg['paporchap'] == "chap")
1194
				$paporchap = "set link enable chap";
1195
			else
1196
				$paporchap = "set link enable pap";
1197

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

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

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

    
1213
				$clientip = long2ip32(ip2long($pppoecfg['remoteip']) + $i);
1214

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

    
1221
				$mpdconf .=<<<EOD
1222

    
1223
poes{$pppoecfg['pppoeid']}{$i}:
1224
	new -i poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i} poes{$pppoecfg['pppoeid']}{$i}
1225
	{$isssue_ip_type}
1226
	load pppoe_standard
1227

    
1228
EOD;
1229
			}
1230

    
1231
			$mpdconf .=<<<EOD
1232

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

    
1259
EOD;
1260

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

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

    
1293
EOD;
1294

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

    
1299
EOD;
1300
				}
1301
			}
1302

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

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

    
1314
			$mpdlinks = "";
1315

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

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

    
1326
EOD;
1327
			}
1328

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

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

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

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

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

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

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

    
1366
			break;
1367
	}
1368

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

    
1372
	return 0;
1373
}
1374

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

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

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

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

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

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

    
1397
	}
1398

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

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

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

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

    
1421
EOD;
1422

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

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

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

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

    
1437
				$mpdconf .=<<<EOD
1438

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

    
1444
EOD;
1445
			}
1446

    
1447
			$mpdconf .=<<<EOD
1448

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

    
1465
EOD;
1466

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

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

    
1496
EOD;
1497

    
1498
				if (isset ($l2tpcfg['radius']['accounting'])) {
1499
					$mpdconf .=<<<EOD
1500
	set auth enable radius-acct
1501

    
1502
EOD;
1503
				}
1504
			}
1505

    
1506
			fwrite($fd, $mpdconf);
1507
			fclose($fd);
1508
			unset($mpdconf);
1509

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

    
1517
			$mpdlinks = "";
1518

    
1519
			for ($i = 0; $i < $l2tpcfg['n_l2tp_units']; $i++) {
1520
				$mpdlinks .=<<<EOD
1521

    
1522
l2tp{$i}:
1523
	set link type l2tp
1524
	set l2tp enable incoming
1525
	set l2tp disable originate
1526

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

    
1532
			fwrite($fd, $mpdlinks);
1533
			fclose($fd);
1534
			unset($mpdlinks);
1535

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

    
1543
			$mpdsecret = "\n\n";
1544

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

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

    
1555
			vpn_netgraph_support();
1556

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

    
1560
			break;
1561

    
1562
		case 'redir' :
1563
			break;
1564
	}
1565

    
1566
	if ($g['booting'])
1567
		echo "done\n";
1568

    
1569
	return 0;
1570
}
1571

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

    
1580
?>
(58-58/67)