Project

General

Profile

Download (40.3 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
	openvpn.inc
4
	
5
	Copyright (C) 2004 Peter Curran (peter@closeconsultants.com).
6
	Copyright (C) 2005 Peter Allgeyer (allgeyer@web.de).
7
	All rights reserved.
8
	
9
	Redistribution and use in source and binary forms, with or without
10
	modification, are permitted provided that the following conditions are met:
11
	
12
	1. Redistributions of source code must retain the above copyright notice,
13
	   this list of conditions and the following disclaimer.
14
	
15
	2. Redistributions in binary form must reproduce the above copyright
16
	   notice, this list of conditions and the following disclaimer in the
17
	   documentation and/or other materials provided with the distribution.
18
	
19
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
20
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
21
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
23
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28
	POSSIBILITY OF SUCH DAMAGE.
29
*/
30
	
31
/* include all configuration functions */
32
require_once("globals.inc");
33
require_once("config.inc");
34
require_once("functions.inc");
35

    
36
function ovpn_configure($reconfigure) {
37
	global $config;
38
	if (is_array($config['ovpn']['server']))
39
		ovpn_server_crl_add();
40
		ovpn_server_ccd_add();
41
		ovpn_config_server($reconfigure);
42
	if (is_array($config['ovpn']['client']))
43
		ovpn_config_client();
44
	return;
45
}
46

    
47
function ovpn_link_tap() {
48
	/* Add a reference to the tap KLM.  If ref count = 1, load it */
49
	global $g;
50
	
51
	if (!is_file($g['vardb_path'] ."/ovpn_tap_link")){
52
		$link_count = 1;
53
		mwexec("/sbin/kldload if_tap");
54
		$fd = fopen($g['vardb_path'] ."/ovpn_tap_link", 'w');
55
	}
56
	return true;
57
}
58

    
59
function ovpn_unlink_tap() {
60
	/* Remove a reference to the tap KLM.  If ref count = 0, unload it */
61
	global $g;
62
	
63
	if (!is_file($g['vardb_path'] ."/ovpn_tap_link"))
64
		return false;  //no file, no links so why are we called?
65
		
66
	$fd = fopen($g['vardb_path'] ."/ovpn_tap_link", 'r+');
67
	$link_count = fread($fd, filesize($g['vardb_path'] ."/ovpn_tap_link"));
68
	$link_count--;
69
	fwrite($fd, $link_count);
70
	fclose($fd);
71
		
72
	if ($link_count == 0)
73
		mwexec("/sbin/kldunload if_tap");
74
	return true;
75
}
76

    
77
/*****************************/	
78
/*  Server related functions */
79
/*****************************/
80

    
81
/* Configure the server */
82
function ovpn_config_server($reconfigure) {
83
	global $config, $g, $d_ovpnsrvdirty_path;
84

    
85
	if($config['ovpn']['server']['tunnel'])
86
	foreach ($config['ovpn']['server']['tunnel'] as $id => $server) {
87
		/* get tunnel interface */
88
		$tun = $server['tun_iface'];
89
			
90
		if (isset($server['enable'])) {
91

    
92
			if ($g['booting']) {
93
				echo "Starting OpenVPN server $id... ";
94

    
95
				/* define configuration options */
96
				ovpn_srv_config_generate($id);
97

    
98
				/* Start the openvpn daemon */
99
				mwexec("/usr/local/sbin/openvpn {$g['varetc_path']}/ovpn_srv_{$tun}.conf");
100

    
101
				/* Send the boot message */
102
				echo "done\n";
103

    
104
				/* next server */
105
				continue;
106
			}
107

    
108
			/* send SIGUSR1 to running openvpn daemon */
109
			if ( $reconfigure == "true" && isset($server['dynip'])) {
110
				sigkillbypid($g['varrun_path']."/ovpn_srv_{$tun}.pid", "SIGUSR1");
111
				continue;
112
			}
113

    
114
			/* read dirtyfile */
115
			if (is_readable($d_ovpnsrvdirty_path))
116
				$lines = file($d_ovpnsrvdirty_path);
117

    
118
			/* reconfigure server */
119
			if (is_array($lines) && in_array($tun . "\n", $lines)) {
120

    
121
				/* kill running server */
122
				ovpn_server_kill($tun);
123

    
124
				/* remove old certs & keys */
125
				ovpn_server_certs_del($tun);
126

    
127
				/* define configuration options */
128
				ovpn_srv_config_generate($id);
129
			}
130

    
131
			/* Start the openvpn daemon */
132
			if (!is_readable("{$g['varrun_path']}/ovpn_srv_{$tun}.pid"))
133
				mwexec("/usr/local/sbin/openvpn {$g['varetc_path']}/ovpn_srv_{$tun}.conf");
134

    
135
			/* next server */
136
			continue;
137
		}
138

    
139
		/* server disabled */
140
		if (!$g['booting']) {
141
			/* kill running server */
142
			ovpn_server_kill($tun);
143

    
144
			/* Remove old certs & keys */
145
			ovpn_server_certs_del($tun);
146

    
147
			/* stop any processes, unload the tap module */
148
			//if ($server['type'] == "tap")
149
			//	ovpn_unlink_tap();
150
		}
151
	}
152
	return 0;
153
}
154

    
155
/* Kill off a running server process */
156
function ovpn_server_certs_del($tun) {
157
	global $g;
158
	
159
	/* Remove old certs & keys */
160
	unlink_if_exists("{$g['vardb_path']}/ovpn_ca_cert_{$tun}.pem");
161
	unlink_if_exists("{$g['vardb_path']}/ovpn_srv_cert_{$tun}.pem");
162
	unlink_if_exists("{$g['vardb_path']}/ovpn_srv_key_{$tun}.pem");
163
	unlink_if_exists("{$g['vardb_path']}/ovpn_dh_{$tun}.pem");
164
	unlink_if_exists("{$g['vardb_path']}/ovpn_srv_psk_{$tun}.pem");
165
	unlink_if_exists("{$g['varetc_path']}/ovpn_srv_up_{$tun}.sh");
166
	unlink_if_exists("{$g['varetc_path']}/ovpn_srv_{$tun}.conf");
167

    
168
	return 0;
169
}
170

    
171
/* Kill off a running server process */
172
function ovpn_server_kill($tun) {
173
	global $g;
174

    
175
	/* kill running server */
176
	killbypid("{$g['varrun_path']}/ovpn_srv_{$tun}.pid");
177
}
178

    
179
/* Generate the config for a OpenVPN server */
180
function ovpn_srv_config_generate($id) {
181
	global $config, $g;
182
	$server = $config['ovpn']['server']['tunnel'][$id];
183

    
184
	/* get tunnel interface */
185
	$tun = $server['tun_iface'];
186

    
187
	/* get optional interface name */
188
	$iface = ovpn_get_opt_interface($tun);
189

    
190
	/* Copy the TLS-Server certs & keys to disk */
191
	if ($server['authentication_method'] != "pre_shared_key" ) {
192

    
193
		$fd = fopen("{$g['vardb_path']}/ovpn_ca_cert_{$tun}.pem", "w");
194
		if ($fd) {
195
			fwrite($fd, base64_decode($server['ca_cert'])."\n");
196
			fclose($fd);	
197
		}
198

    
199
		$fd = fopen("{$g['vardb_path']}/ovpn_srv_cert_{$tun}.pem", "w");
200
		if ($fd) {
201
			fwrite($fd, base64_decode($server['srv_cert'])."\n");
202
			fclose($fd);	
203
		}
204

    
205
		touch ("{$g['vardb_path']}/ovpn_srv_key_{$tun}.pem");
206
		chmod ("{$g['vardb_path']}/ovpn_srv_key_{$tun}.pem", 0600);
207
		$fd = fopen("{$g['vardb_path']}/ovpn_srv_key_{$tun}.pem", "w");
208
		if ($fd) {
209
			fwrite($fd, base64_decode($server['srv_key'])."\n");
210
			fclose($fd);	
211
		}
212

    
213
		$fd = fopen("{$g['vardb_path']}/ovpn_dh_{$tun}.pem", "w");
214
		if ($fd) {
215
			fwrite($fd, base64_decode($server['dh_param'])."\n");
216
			fclose($fd);	
217
		}
218
	}
219

    
220
	if ($server['authentication_method'] == "pre_shared_key" || isset($server['tlsauth'])) {
221
		touch ("{$g['vardb_path']}/ovpn_srv_psk_{$tun}.pem");
222
		chmod ("{$g['vardb_path']}/ovpn_srv_psk_{$tun}.pem", 0600);
223
		$fd = fopen("{$g['vardb_path']}/ovpn_srv_psk_{$tun}.pem", "w");
224
		if ($fd) {
225
			fwrite($fd, base64_decode($server['pre-shared-key'])."\n");
226
			fclose($fd);	
227
		}
228
	}
229

    
230
	$fd = fopen("{$g['varetc_path']}/ovpn_srv_{$tun}.conf", "w");
231
	if (!$fd) {
232
		printf("Error: cannot open ovpn_srv_{$tun}.conf in ovpn_srv_config_generate($id).\n");
233
		return 1;
234
	}
235

    
236
	/* First the generic stuff:
237
		- We are a server
238
		- We will run without privilege
239
	*/
240
	$ovpn_config = "";
241
	$ovpn_config .= <<<EOD
242
daemon
243
user nobody
244
group nobody
245
verb {$server['verb']}
246
persist-tun
247
persist-key
248
status /var/log/openvpn_{$tun}.log 60
249
writepid {$g['varrun_path']}/ovpn_srv_{$tun}.pid
250
dev {$server['tun_iface']}
251
port {$server['port']}
252
cipher {$server['crypto']}
253

    
254
EOD;
255

    
256
	/* Set protocol being used (p = udp (default), tcp-server) */
257
	if ($server['proto'] == "tcp")
258
		$ovpn_config .= "proto tcp-server\n";
259

    
260
	/* Interface binding - 1 or all */
261
	if ($server['bind_iface'] != 'all')
262
		if ($ipaddr = ovpn_get_ip($server['bind_iface']))
263
			$ovpn_config .= "local {$ipaddr}\n";
264

    
265
	/* are we using dynamic ip addresses? */
266
	if (isset($server['dynip']))
267
		$ovpn_config .= "persist-remote-ip\n";
268

    
269
	/* LZO compression (off by default) */
270
	if (isset($server['comp_method'])) {
271
		switch ($server['comp_method']) {
272

    
273
			case 'lzo':
274
				$ovpn_config .= "comp-lzo\n";
275
				break;
276
			case 'noadapt':
277
				$ovpn_config .= "comp-lzo\n" . "comp-noadapt\n";
278
				break;
279
		}
280
	}
281

    
282
	/* Client to client routing (off by default) */
283
	if (isset($server['cli2cli']))
284
		$ovpn_config .= "client-to-client\n";
285

    
286
	/* Limit server to a maximum of n concurrent clients. */
287
	if (!empty($server['maxcli']))
288
		$ovpn_config .= "max-clients {$server['maxcli']}\n";
289

    
290
	/* Authentication method */
291
	if ($server['authentication_method'] != "pre_shared_key") {
292

    
293
		$ovpn_config .= <<<EOD
294
client-config-dir {$g['vardb_path']}/ccd
295
ca {$g['vardb_path']}/ovpn_ca_cert_{$tun}.pem
296
cert {$g['vardb_path']}/ovpn_srv_cert_{$tun}.pem
297
key {$g['vardb_path']}/ovpn_srv_key_{$tun}.pem
298
dh {$g['vardb_path']}/ovpn_dh_{$tun}.pem
299

    
300
EOD;
301

    
302
		/* CRL list */
303
		if (isset($server['crlname']) &&
304
		    is_readable("{$g['vardb_path']}/{$server['crlname']}.crl.pem")) {
305
			$ovpn_config .= "crl-verify {$g['vardb_path']}/{$server['crlname']}.crl.pem\n";
306
		}
307

    
308
		/* TLS auth */
309
		if (isset($server['tlsauth']))
310
			$ovpn_config .= "tls-auth {$g['vardb_path']}/ovpn_srv_psk_{$tun}.pem 0\n";
311

    
312
		/* bridging enabled? */
313
		if ($server['bridge'] && $server['type'] == "tap") {
314
			if ($server['method'] == "ovpn") {
315
				$netmask = gen_subnet_mask($config['interfaces'][$server['bridge']]['subnet']);
316
				$ovpn_config .= "server-bridge {$server['gateway']} {$netmask} {$server['range_from']} {$server['range_to']}\n";
317
			} else {
318
				$ovpn_config .= <<<EOD
319
mode server
320
tls-server
321

    
322
EOD;
323
			}
324

    
325
			$lastdigits = substr($tun, 3) + 2;
326
			$ovpn_srv_up = "/sbin/ifconfig " . $tun . " 127.0.0." . $lastdigits . "/32\n";
327

    
328
			$fdo = fopen("{$g['varetc_path']}/ovpn_srv_up_{$tun}.sh", "w");
329
			if ($fdo) {
330
				fwrite($fdo, $ovpn_srv_up);
331
				fclose($fdo);	
332
				chmod ("{$g['varetc_path']}/ovpn_srv_up_{$tun}.sh", 0755);
333
				$ovpn_config .= "up /var/etc/ovpn_srv_up_{$tun}.sh\n";
334
			}
335

    
336
		} else {
337
			/* Not bridged, can be tun or tap, doesn't matter */
338
			$netmask = gen_subnet_mask($server['prefix']);
339

    
340
			if ($server['method'] == "ovpn") {
341
				/* new --server macro simplifies config */
342
				$ovpn_config .= "server {$server['ipblock']} {$netmask}\n";
343
			} else {
344
				$ovpn_config .= <<<EOD
345
mode server
346
tls-server
347
ifconfig {$server['ipblock']} {$netmask}
348

    
349
EOD;
350
			}
351
		} /* end bridging */
352

    
353
		/* Duplicate CNs */
354
		if (isset($server['dupcn']))
355
			$ovpn_config .= "duplicate-cn\n";
356

    
357
		$push_options = "";
358
	
359
		/* Client push - redirect gateway */
360
		if (isset($server['psh_options']['redir']))  {
361
			if (isset($server['psh_options']['redir_loc']))
362
				$push_config .= "push \"redirect-gateway local\"\n";
363
			else
364
				$push_config .= "push \"redirect-gateway\"\n";
365
		}
366

    
367
		/* Client push - route delay */
368
		if (isset($server['psh_options']['rte_delay']))
369
			$push_config .= "push \"route-delay {$server['psh_options']['rte_delay_int']}\"\n";
370

    
371
		/* Client push - ping (note we set both server and client) */
372
		if (isset ($server['psh_options']['ping'])){
373
			$conflict = true;
374
			$interval = $server['psh_options']['ping_int'];
375
			$ovpn_config .= "ping {$server['psh_options']['ping_int']}\n ";
376
			$push_config .= "push \"ping {$server['psh_options']['ping_int']}\"\n";
377
		}
378

    
379
		/* Client push - ping-restart (note server uses 2 x client interval) */
380
		if (isset ($server['psh_options']['pingrst'])){
381
			$conflict = true;
382
			$interval = $server['psh_options']['pingrst_int'];
383
			$ovpn_config .= "ping-restart " . ($interval * 2) . "\n";
384
			$push_config .= "push \"ping-restart $interval\"\n";
385
		}
386
	
387
		/* Client push - ping-exit (set on client) */
388
		if (isset ($server['psh_options']['pingexit'])){
389
			$conflict = true;
390
			$ovpn_config .= "ping-exit {$server['psh_options']['pingexit_int']}\n";
391
			$push_config .= "push \"ping-exit {$server['psh_options']['pingexit_int']}\"\n";
392
		}
393

    
394
		/* Client push - inactive (set on client) */
395
		if (isset ($server['psh_options']['inact'])){
396
			$ovpn_config .= "inactive {$server['psh_options']['inact_int']}\n";
397
			$push_config .= "push \"inactive {$server['psh_options']['inact_int']}\"\n";
398
		}
399

    
400
		if (isset($server['client-to-client']))
401
			$push_config .= "push \"route {$network} {$netmask}\"\n";
402

    
403
		if (isset($push_config))
404
			$ovpn_config .= $push_config;
405

    
406
	} else {
407
		/* 'authentication_method' == "pre_shared_key" */
408
		$network = gen_subnet($server['lipaddr'], $server['netmask']);
409
		$netmask = gen_subnet_mask($server['netmask']);
410

    
411
		$ovpn_config .= "secret {$g['vardb_path']}/ovpn_srv_psk_{$tun}.pem 0\n";
412

    
413
		if (strstr($server['type'], "tun")) {
414
			$ovpn_config .= "ifconfig {$server['lipaddr']} {$server['ripaddr']}\n";
415
			$ovpn_config .= "route {$network} {$netmask}\n";
416
		} else {
417
			$ovpn_config .= "ifconfig {$server['lipaddr']} {$netmask}\n";
418
		}
419

    
420
	} /* end authentication_method */
421

    
422
	if (!isset($conflict))
423
		$ovpn_config .= "keepalive 10 60\n";
424

    
425
	/* Expert mode paramters */
426
	if (isset($server['expertmode_enabled']) && is_array($server['expertmode'])) {
427
		$ovpn_config .= ";begin expertmode\n";
428
		foreach ($server['expertmode']['option'] as $option) {
429
			$ovpn_config .= "{$option}\n";
430
		}
431
		$ovpn_config .= ";end expertmode\n";
432
	}
433

    
434
	fwrite($fd, $ovpn_config);
435
	fclose($fd);
436

    
437
	//trigger_error("OVPN: $ovpn_config", E_USER_NOTICE);
438
}
439

    
440
/* Define an OVPN Server tunnel interface in the interfaces array and assign a name */
441
function ovpn_server_iface(){
442
	global $config, $g;
443

    
444
	unset($filter_configure);
445
	unset($bridge_configure);
446
	
447
	foreach ($config['ovpn']['server']['tunnel'] as $id => $server) {
448
		if (isset($server['enable'])) {
449

    
450
			/* get tunnel interface */
451
			$tun = $server['tun_iface'];
452
			
453
			$i = 1;
454
			while (true) {
455
				$ifname = 'opt' . $i;
456
				if (is_array($config['interfaces'][$ifname])) {
457
					if ((isset($config['interfaces'][$ifname]['ovpn']))
458
					     && ($config['interfaces'][$ifname]['ovpn'] == "server_{$tun}"))
459
						/* Already an interface defined - overwrite */
460
						break;
461
				} else {
462

    
463
					/* No existing entry, this is first unused */
464
					$config['interfaces'][$ifname] = array();
465

    
466
					/* add new filter rules */
467
					$filter_configure = true;
468
					break;
469
				}
470
				$i++;
471
			}
472
			$config['interfaces'][$ifname]['descr'] = strtoupper($server['tun_iface']);
473
			$config['interfaces'][$ifname]['if'] = $server['tun_iface'];
474
			if ($server['method'] == "ovpn")
475
				$config['interfaces'][$ifname]['ipaddr'] = long2ip( ip2long($server['ipblock']) + 1);
476
			else
477
				$config['interfaces'][$ifname]['ipaddr'] = $server['ipblock'];
478
			if (isset($server['bridge'])) {
479
				$config['interfaces'][$ifname]['bridge'] = $server['bridge'];
480
				$bridge_configure = true;
481
			} else if (isset($config['interfaces'][$ifname]['bridge'])) {
482
				/* bridge config removed */
483
				unset ($config['interfaces'][$ifname]['bridge']);
484
				$bridge_configure = true;
485
			}
486
			$config['interfaces'][$ifname]['subnet'] = $server['prefix'];
487
			$config['interfaces'][$ifname]['enable'] = isset($server['enable']) ? true : false;
488
			$config['interfaces'][$ifname]['ovpn'] = "server_{$tun}";
489

    
490
			write_config();
491
		}
492
	}
493

    
494
	/* do we have to reconfigure filter rules? */
495
	if (isset($bridge_configure))
496
		interfaces_optional_configure();
497
	else if (isset($filter_configure))
498
		filter_configure();
499

    
500
	return "OpenVPN server interface defined";
501
}
502

    
503
/* Delete a server interface definition */
504
function ovpn_server_iface_del($tun) {
505
	global $config;
506

    
507
	for ($i = 1; is_array($config['interfaces']['opt' . $i]); $i++) {
508
		$ifname = 'opt' . $i;
509
		if ((isset($config['interfaces'][$ifname]['ovpn']))
510
		     && ($config['interfaces'][$ifname]['if'] == "$tun")) {
511
			unset($config['interfaces'][$ifname]);
512
			break;
513
		}
514
	}
515

    
516
	/* shift down other OPTn interfaces to get rid of holes */
517
	$i++;
518

    
519
	/* look at the following OPTn ports */
520
	while (is_array($config['interfaces']['opt' . $i])) {
521
		$config['interfaces']['opt' . ($i - 1)] =
522
			$config['interfaces']['opt' . $i];
523

    
524
		unset($config['interfaces']['opt' . $i]);
525
		$i++;
526
	}
527

    
528
	/* reconfigure filter rules */
529
	interfaces_optional_configure();
530
}
531

    
532
/* Add client config file */
533
function ovpn_server_ccd_add() {
534
	global $config, $g;
535

    
536
	if (is_array($config['ovpn']['server']['ccd'])) {
537
		foreach ($config['ovpn']['server']['ccd'] as $id => $server) {
538
			/* define configuration options */
539
			ovpn_server_ccd_generate($id);
540
		}
541
	}
542
}
543

    
544

    
545
/* Construct client config file */
546
function ovpn_server_ccd_generate($id) {
547
	global $config, $g;
548
	$ovpnccd = $config['ovpn']['server']['ccd'][$id];
549

    
550
	$cn = $ovpnccd['cn'];
551
	$ccd_config = "";
552
        $push_options = "";
553
        
554
	/* Push reset */
555
	if (!isset($ovpnccd['disable']) && isset($ovpnccd['psh_reset']))  {
556
		$ccd_config .= "push-reset\n";
557

    
558
		/* Client push - redirect gateway */
559
		if (isset($ovpnccd['psh_options']['redir']))  {
560
			if (isset($ovpnccd['psh_options']['redir_loc']))
561
				$push_config .= "push \"redirect-gateway local\"\n";
562
			else
563
				$push_config .= "push \"redirect-gateway\"\n";
564
		}
565

    
566
		/* Client push - route delay */
567
		if (isset($ovpnccd['psh_options']['rte_delay']))
568
			$push_config .= "push \"route-delay {$ovpnccd['psh_options']['rte_delay_int']}\"\n";
569

    
570
		/* Client push - ping (note we set both server and client) */
571
		if (isset ($ovpnccd['psh_options']['ping'])){
572
			$ccd_config .= "ping {$server['psh_options']['ping_int']}\n ";
573
			$push_config .= "push \"ping {$ovpnccd['psh_options']['ping_int']}\"\n";
574
		}
575

    
576
		/* Client push - ping-restart (note server uses 2 x client interval) */
577
		if (isset ($ovpnccd['psh_options']['pingrst'])){
578
			$interval = $ovpnccd['psh_options']['pingrst_int'];
579
			$ccd_config .= "ping-restart " . ($interval * 2) . "\n";
580
			$push_config .= "push \"ping-restart $interval\"\n";
581
		}
582

    
583
		/* Client push - ping-exit (set on client) */
584
		if (isset ($ovpnccd['psh_options']['pingexit'])){
585
			$ccd_config .= "ping-exit {$ovpnccd['psh_options']['pingexit_int']}\n";
586
			$push_config .= "push \"ping-exit {$ovpnccd['psh_options']['pingexit_int']}\"\n";
587
		}
588

    
589
		/* Client push - inactive (set on client) */
590
		if (isset ($ovpnccd['psh_options']['inact'])){
591
			$ccd_config .= "inactive {$ovpnccd['psh_options']['inact_int']}\n";
592
			$push_config .= "push \"inactive {$ovpnccd['psh_options']['inact_int']}\"\n";
593
		}
594

    
595
		if (isset($push_config))
596
			$ccd_config .= $push_config;
597
	}
598

    
599
        if (!isset($ovpnccd['disable']) && is_array($ovpnccd['options'])) {
600
                foreach ($ovpnccd['options']['option'] as $option) {
601
                        $ccd_config .= "{$option}\n";
602
                }
603
        }
604

    
605
	/* Disable client from connecting */
606
	if (isset($ovpnccd['disable']))
607
		$ccd_config = "disable\n";
608

    
609
	unlink_if_exists("{$g['vardb_path']}/ccd/{$cn}");
610

    
611
	if (isset($ccd_config) && isset($ovpnccd['enable'])) {
612
		$fd = fopen("{$g['vardb_path']}/ccd/{$cn}", "w");
613
		if ($fd) {
614
			fwrite($fd, $ccd_config."\n");
615
			fclose($fd);    
616
		}
617
	}
618
}
619

    
620
/* Delete client config file */
621
function ovpn_server_ccd_del($cn) {
622
	global $g;
623
	
624
	unlink_if_exists("{$g['vardb_path']}/ccd/{$cn}");
625
	return 0;
626
}
627

    
628
/* Add CRL file */
629
function ovpn_server_crl_add() {
630
	global $config, $g, $d_ovpncrldirty_path;
631

    
632
	if (is_array($config['ovpn']['server']['crl'])) {
633
		foreach ($config['ovpn']['server']['crl'] as $id => $crlent) {
634
			/* get crl file name */
635
			$name = $crlent['crlname'];
636

    
637
			if (isset($crlent['enable'])) {
638
			
639
				/* add file */
640
				ovpn_server_crl_generate($id);
641

    
642
				if ($g['booting']) {
643
					/* next crl file */
644
					continue;
645
				}
646
				
647
				/* read dirtyfile */
648
				if (is_readable($d_ovpncrldirty_path))
649
					$lines = file($d_ovpncrldirty_path);
650

    
651
				/* reconfigure crl file */
652
				if (is_array($lines) && in_array($name . "\n", $lines)) {
653

    
654
					/* restart running openvpn daemon */
655
					foreach ($config['ovpn']['server']['tunnel'] as $id => $server) {
656
						$tun = $server['tun_iface'];
657

    
658
						if ($server['enable'] &&
659
						    isset($server['crlname']) && $server['crlname'] == $name)
660
							/* kill running server */
661
							ovpn_server_kill($tun);
662

    
663
							/* Start the openvpn daemon */
664
							mwexec("/usr/local/sbin/openvpn {$g['varetc_path']}/ovpn_srv_{$tun}.conf");
665
					}
666

    
667
				}
668
			
669
				/* next crl file */
670
				continue;
671
			}
672
			
673
			/* crl file disabled: remove file */
674
			ovpn_server_crl_del($name);
675
		}
676
	}
677
	return 0;
678
}
679

    
680
/* Write CRL to file */
681
function ovpn_server_crl_generate($id) {
682
	global $config, $g;
683

    
684
	$ovpncrl = $config['ovpn']['server']['crl'][$id];
685

    
686
	$fd = fopen("{$g['vardb_path']}/{$ovpncrl['crlname']}.crl.pem", "w");
687
	if ($fd) {
688
		fwrite($fd, base64_decode($ovpncrl['crl_list'])."\n");
689
		fclose($fd);
690
	}
691
}
692

    
693
/* Delete CRL file */
694
function ovpn_server_crl_del($name) {
695
	global $config, $g;
696

    
697
	/* have to wipe out the crl from the server config */
698
	foreach ($config['ovpn']['server']['tunnel'] as $id => $server) {
699
		if (isset($server['crlname']) && $server['crlname'] == $name) {
700

    
701
			/* get tunnel interface */
702
			$tun = $server['tun_iface'];
703

    
704
			/* remove crl file entry */
705
			unset($config['ovpn']['server']['tunnel'][$id]['crlname']);
706
			write_config();
707
			
708
			/* kill running server */
709
			ovpn_server_kill($tun);
710

    
711
			/* remove old certs & keys */
712
			ovpn_server_certs_del($tun);
713
			
714
			/* reconfigure daemon */
715
			ovpn_srv_config_generate($id);
716

    
717
			/* Start the openvpn daemon */
718
			mwexec("/usr/local/sbin/openvpn {$g['varetc_path']}/ovpn_srv_{$tun}.conf");
719
		}
720
	}
721

    
722
	unlink_if_exists("{$g['vardb_path']}/{$name}.crl.pem");
723
	return 0;
724
}
725

    
726

    
727
/* Get a list of crl files */
728
function ovpn_get_crl_list() {
729
	global $config;
730

    
731
	$crl_list = array();
732

    
733
	if (is_array($config['ovpn']['server']['crl'])) {
734
		foreach ($config['ovpn']['server']['crl'] as $crlent) {
735
			if (isset($crlent['enable']))
736
				$crl_list[] = $crlent['crlname'];
737
		}
738
	}
739
	return $crl_list;
740
}
741

    
742
/* append interface to $_ovpnsrvdirty_path */
743
function ovpn_srv_dirty($tun) {
744
	global $d_ovpnsrvdirty_path;
745
	
746
	$fd = fopen($d_ovpnsrvdirty_path, 'a');
747
	if ($fd) {
748
		fwrite($fd, $tun ."\n");
749
		fclose($fd);
750
	}
751
}
752

    
753
/* append file name to $_ovpncrldirty_path */
754
function ovpn_crl_dirty($name) {
755
	global $d_ovpncrldirty_path;
756
	
757
	$fd = fopen($d_ovpncrldirty_path, 'a');
758
	if ($fd) {
759
		fwrite($fd, $name ."\n");
760
		fclose($fd);
761
	}
762
}
763

    
764

    
765
/****************************/
766
/* Client related functions */
767
/****************************/
768

    
769
function ovpn_config_client() {
770
	/* Boot time configuration */
771
	global $config, $g, $d_ovpnclidirty_path;;
772
	
773
	foreach ($config['ovpn']['client']['tunnel'] as $id => $client) {
774

    
775
		/* get tunnel interface */
776
		$tun = $client['if'];
777

    
778
		if (isset($client['enable'])) {
779

    
780
			if ($g['booting']) {
781
				echo "Starting OpenVPN client $id... ";
782
		
783
				/* define configuration options */
784
				ovpn_cli_config_generate($id);
785

    
786
				/* Start openvpn for this client */
787
				mwexec("/usr/local/sbin/openvpn {$g['varetc_path']}/ovpn_cli_{$tun}.conf");
788
		
789
				/* Send the boot message */
790
				echo "done\n";
791

    
792
				/* next client */
793
				continue;
794
			}
795

    
796
			/* read dirtyfile */
797
			if (is_readable($d_ovpnclidirty_path))
798
				$lines = file($d_ovpnclidirty_path);
799

    
800
			/* reconfigure client */
801
			if (is_array($lines) && in_array($tun . "\n", $lines)) {
802

    
803
				/* kill running client */
804
				ovpn_client_kill($tun);
805

    
806
				/* remove old certs & keys */
807
				ovpn_client_certs_del($tun);
808

    
809
				/* define configuration options */
810
				ovpn_cli_config_generate($id);
811
			}
812

    
813
			/* Start the openvpn daemon */
814
			if (!is_readable("{$g['varrun_path']}/ovpn_cli_{$tun}.pid"))
815
				mwexec("/usr/local/sbin/openvpn {$g['varetc_path']}/ovpn_cli_{$tun}.conf");
816

    
817
			/* next client */
818
			continue;
819
		}
820

    
821
		/* client disabled */
822
		if (!$g['booting']) {
823
			/* kill running client */
824
			ovpn_client_kill($tun);
825
			
826
			/* remove old certs & keys */
827
			ovpn_client_certs_del($tun);
828

    
829
			/* stop any processes, unload the tap module */
830
			//if ($client['type'] == "tap")
831
			//	ovpn_unlink_tap();
832
		}
833
	}
834
	return 0;
835
}
836

    
837
/* Kill off a running client process */
838
function ovpn_client_certs_del($tun) {
839
	global $g;
840
	
841
	/* Remove old certs & keys */
842
	unlink_if_exists("{$g['vardb_path']}/ovpn_cli_ca_cert_{$tun}.pem");
843
	unlink_if_exists("{$g['vardb_path']}/ovpn_cli_cert_{$tun}.pem");
844
	unlink_if_exists("{$g['vardb_path']}/ovpn_cli_key_{$tun}.pem");
845
	unlink_if_exists("{$g['vardb_path']}/ovpn_cli_psk_{$tun}.pem");
846
	unlink_if_exists("{$g['varetc_path']}/ovpn_cli_up_{$tun}.pem");
847
	unlink_if_exists("{$g['varetc_path']}/ovpn_cli_{$tun}.conf");
848

    
849
	return 0;
850
}
851

    
852
/* Kill off a running client process */
853
function ovpn_client_kill($tun) {
854
	global $g;
855

    
856
	/* kill running client */
857
	killbypid("{$g['varrun_path']}/ovpn_cli_{$tun}.pid");
858
}
859

    
860
/* Generate the config for a OpenVPN client */
861
function ovpn_cli_config_generate($id) {
862
	/* configure the named client */
863
	global $config, $g;
864
	$client = $config['ovpn']['client']['tunnel'][$id];
865

    
866
	/* get tunnel interface */
867
	$tun = $client['if'];
868

    
869
	/* get optional interface name */
870
	$iface = ovpn_get_opt_interface($tun);
871

    
872
	/* Copy the TLS-Client certs & keys to disk */
873
	if ($client['authentication_method'] != "pre_shared_key" ) {
874

    
875
		$fd = fopen("{$g['vardb_path']}/ovpn_cli_ca_cert_{$tun}.pem", "w");
876
		if ($fd) {
877
			fwrite($fd, base64_decode($client['ca_cert'])."\n");
878
			fclose($fd);	
879
		}
880

    
881
		$fd = fopen("{$g['vardb_path']}/ovpn_cli_cert_{$tun}.pem", "w");
882
		if ($fd) {
883
			fwrite($fd, base64_decode($client['cli_cert'])."\n");
884
			fclose($fd);	
885
		}
886

    
887
		touch ("{$g['vardb_path']}/ovpn_cli_key_{$tun}.pem");
888
		chmod ("{$g['vardb_path']}/ovpn_cli_key_{$tun}.pem", 0600);
889
		$fd = fopen("{$g['vardb_path']}/ovpn_cli_key_{$tun}.pem", "w");
890
		if ($fd) {
891
			fwrite($fd, base64_decode($client['cli_key'])."\n");
892
			fclose($fd);	
893
		}
894
	}
895

    
896
	if ($client['authentication_method'] == "pre_shared_key" || isset($client['tlsauth'])) {
897
		touch ("{$g['vardb_path']}/ovpn_cli_psk_{$tun}.pem");
898
		chmod ("{$g['vardb_path']}/ovpn_cli_psk_{$tun}.pem", 0600);
899
		$fd = fopen("{$g['vardb_path']}/ovpn_cli_psk_{$tun}.pem", "w");
900
		if ($fd) {
901
			fwrite($fd, base64_decode($client['pre-shared-key'])."\n");
902
			fclose($fd);	
903
		}
904
	}
905

    
906
	$fd = fopen("{$g['varetc_path']}/ovpn_cli_{$tun}.conf", "w");
907
	if (!$fd) {
908
		printf("Error: cannot open ovpn_cli_{$tun}.conf in ovpn_cli_config_generate($id).\n");
909
		return 1;
910
	}
911

    
912
	/* Client support in 2.0 is very simple */
913
	$ovpn_config = "";
914
	$ovpn_config .= <<<EOD
915
daemon
916
verb 1
917
status /var/log/openvpn_{$tun}.log 60
918
writepid {$g['varrun_path']}/ovpn_cli_{$tun}.pid
919
dev {$client['if']}
920
lport {$client['cport']}
921
remote {$client['saddr']} {$client['sport']}
922
cipher {$client['crypto']}
923

    
924
EOD;
925

    
926
	/* Version 1.0 compatibility; http://openvpn.net/compat.html */
927
	if ($client['ver'] != "2") {
928
		$ovpn_config .= <<<EOD
929
key-method 1
930
tun-mtu 1500
931
tun-mtu-extra 32
932
mssfix 1450
933

    
934
EOD;
935
	}
936

    
937
	/* Set protocol being used (p = udp (default), tcp-client) */
938
	if ($client['proto'] == "tcp")
939
		$ovpn_config .= "proto tcp-client\n";
940

    
941
	/* TLS-Client params */
942
	if ($client['authentication_method'] != "pre_shared_key") {
943
		$ovpn_config .= <<<EOD
944
ca {$g['vardb_path']}/ovpn_cli_ca_cert_{$tun}.pem
945
cert {$g['vardb_path']}/ovpn_cli_cert_{$tun}.pem
946
key {$g['vardb_path']}/ovpn_cli_key_{$tun}.pem
947

    
948
EOD;
949

    
950
		if (isset($client['pull']))
951
			$ovpn_config .= "client\n";
952
		else
953
			$ovpn_config .= "tls-client\n";
954

    
955
		/* TLS auth */
956
		if (isset($client['ns_cert_type']))
957
			$ovpn_config .= "ns-cert-type server\n";
958

    
959
		/* TLS auth */
960
		if (isset($client['tlsauth']))
961
			$ovpn_config .= "tls-auth {$g['vardb_path']}/ovpn_cli_psk_{$tun}.pem 1\n";
962

    
963
		/* bridging enabled? */
964
		if ($client['bridge'] && $client['type'] == "tap") {
965
			$lastdigits = substr($tun, 3) + 2;
966
			$ovpn_cli_up = "/sbin/ifconfig " . $tun . " 127.0.0." . $lastdigits . "/32\n";
967

    
968
			$fdo = fopen("{$g['varetc_path']}/ovpn_cli_up_{$tun}.sh", "w");
969
			if ($fdo) {
970
				fwrite($fdo, $ovpn_cli_up);
971
				fclose($fdo);   
972
				chmod ("{$g['varetc_path']}/ovpn_cli_up_{$tun}.sh", 0755);
973
				$ovpn_config .= "up /var/etc/ovpn_cli_up_{$tun}.sh\n";
974
			}
975
		}
976

    
977
	} else {
978
		/* 'authentication_method' == "pre_shared_key" */
979
		$ovpn_config .= "secret {$g['vardb_path']}/ovpn_cli_psk_{$tun}.pem 0\n";
980

    
981
		$network = gen_subnet($client['lipaddr'], $client['netmask']);
982
		$netmask = gen_subnet_mask($client['netmask']);
983

    
984
		if (strstr($client['type'], "tap"))
985
			$ovpn_config .= "ifconfig {$client['lipaddr']} {$netmask}\n";
986
		else
987
			$ovpn_config .= "ifconfig {$client['lipaddr']} {$client['ripaddr']}\n";
988

    
989
	} /* end authentication_method */
990

    
991
	/* LZO compression (off by default) */
992
	if (isset($client['comp_method'])) {
993
		switch ($client['comp_method']) {
994

    
995
			case 'lzo':
996
				$ovpn_config .= "comp-lzo\n";
997
				break;
998
			case 'noadapt':
999
				$ovpn_config .= "comp-lzo\n" . "comp-noadapt\n";
1000
				break;
1001
		}
1002
	}
1003

    
1004
	/* Expert mode paramters */
1005
	if (isset($client['expertmode_enabled']) && is_array($client['expertmode'])) {
1006
		$ovpn_config .= ";begin expertmode\n";
1007
		foreach ($client['expertmode']['option'] as $option) {
1008
			$ovpn_config .= "{$option}\n";
1009
		}
1010
		$ovpn_config .= ";end expertmode\n";
1011
	}
1012

    
1013
	fwrite($fd, $ovpn_config);
1014
	fclose($fd);
1015

    
1016
	/* trigger_error("OVPN: $ovpn_config", E_USER_NOTICE); */
1017
}
1018

    
1019
/* Define an OVPN tunnel interface in the interfaces array for each client */
1020
function ovpn_client_iface(){
1021
	global $config;
1022
		
1023
	unset($filter_configure);
1024
	unset($bridge_configure);
1025

    
1026
	foreach ($config['ovpn']['client']['tunnel'] as $id => $client) {
1027
		if (isset($client['enable'])) {
1028

    
1029
			/* get tunnel interface */
1030
			$tun = $client['if'];
1031

    
1032
			$i = 1;
1033
			while (true) {
1034
				$ifname = 'opt' . $i;
1035
				if (is_array($config['interfaces'][$ifname])) {
1036
					if ((isset($config['interfaces'][$ifname]['ovpn']))
1037
			     		     && ($config['interfaces'][$ifname]['ovpn'] == "client_{$tun}"))
1038
						/* Already an interface defined - overwrite */
1039
						break;
1040
				} else {
1041

    
1042
					/* No existing entry, this is first unused */
1043
					$config['interfaces'][$ifname] = array();
1044

    
1045
					/* add new filter rules */
1046
					$filter_configure = true;
1047
					break;
1048
				}
1049
				$i++;
1050
			}
1051
			$config['interfaces'][$ifname]['descr'] = strtoupper($client['if']);
1052
			$config['interfaces'][$ifname]['if'] = $client['if'];
1053
			$config['interfaces'][$ifname]['ipaddr'] = "0.0.0.0";
1054
			$config['interfaces'][$ifname]['subnet'] = "0";
1055
			if (isset($client['bridge'])) {
1056
				$config['interfaces'][$ifname]['bridge'] = $client['bridge'];
1057
				$bridge_configure = true;
1058
			} else if (isset($config['interfaces'][$ifname]['bridge'])) {
1059
				/* bridge config removed */
1060
				unset ($config['interfaces'][$ifname]['bridge']);
1061
				$bridge_configure = true;
1062
			}
1063
			$config['interfaces'][$ifname]['enable'] = isset($client['enable']) ? true : false;
1064
			$config['interfaces'][$ifname]['ovpn'] = "client_{$tun}";
1065
			write_config();
1066
		}
1067
	}
1068

    
1069
	/* do we have to reconfigure filter rules? */
1070
	if (isset($bridge_configure))
1071
		interfaces_optional_configure();
1072
	else if (isset($filter_configure))
1073
		filter_configure();
1074

    
1075
	return "OpenVPN client interfaces defined";
1076
}
1077

    
1078
/* Delete a client interface definition */
1079
function ovpn_client_iface_del($tun) {
1080
	global $config;
1081

    
1082
	for ($i = 1; is_array($config['interfaces']['opt' . $i]); $i++) {
1083
		$ifname = 'opt' . $i;
1084
		if ((isset($config['interfaces'][$ifname]['ovpn']))
1085
		     && ($config['interfaces'][$ifname]['if'] == "$tun")) {
1086
			unset($config['interfaces'][$ifname]);
1087
			break;
1088
		}
1089
	}
1090

    
1091
	/* shift down other OPTn interfaces to get rid of holes */
1092
	$i++;
1093

    
1094
	/* look at the following OPTn ports */
1095
	while (is_array($config['interfaces']['opt' . $i])) {
1096
		$config['interfaces']['opt' . ($i - 1)] =
1097
			$config['interfaces']['opt' . $i];
1098

    
1099
		unset($config['interfaces']['opt' . $i]);
1100
		$i++;
1101
	}
1102

    
1103
	/* reconfigure filter rules */
1104
	interfaces_optional_configure();
1105
}
1106

    
1107
/* append interface to ovpndirty_path */
1108
function ovpn_cli_dirty($tun) {
1109
	global $d_ovpnclidirty_path;
1110
	
1111
	$fd = fopen($d_ovpnclidirty_path, 'a');
1112
	if ($fd) {
1113
		fwrite($fd, $tun . "\n");
1114
		fclose($fd);
1115
	}
1116
}
1117

    
1118

    
1119
/******************/
1120
/* Misc functions */
1121
/******************/
1122

    
1123
/* find the first available device of type $type */
1124
function getnxt_if($type) {
1125
	global $config;
1126

    
1127
	/* initialize variables */
1128
	$iface_list	= array();
1129
	$max		= ($type == 'tun') ? 17 : 4;
1130

    
1131
	/* construct list of valid interfaces */
1132
	for ($i = 0; $i < $max ; $i++)
1133
		array_push($iface_list, $type . $i);
1134
	
1135
	/* delete interface in use from the list */
1136
	if ($a_server = $config['ovpn']['server']['tunnel']) {
1137
		foreach ($a_server as $server) {
1138
			$entry = array();
1139
			array_push($entry, $server['tun_iface']);
1140
			$iface_list = array_diff($iface_list, $entry);
1141
		}
1142
	}
1143

    
1144
	/* same for list of client tunnels  */
1145
	if ($a_client = $config['ovpn']['client']['tunnel']) {
1146
		foreach ($a_client as $client) {
1147
			$entry = array();
1148
			array_push($entry, $client['if']);
1149
			$iface_list = array_diff($iface_list, $entry);
1150
		}
1151
	}
1152
			
1153
	/* return first element of list, if list of interfaces isn't empty */
1154
	if (count($iface_list))
1155
		return array_shift($iface_list);
1156
	else
1157
		return false;
1158
}
1159

    
1160
/* find the next best available port */
1161
function getnxt_port() {
1162

    
1163
	/* construct list of valid ports */
1164
	$port_list = free_port_list();
1165

    
1166
        /* return first element of list, if list of ports isn't empty */
1167
        if (count($port_list))
1168
                return array_shift($port_list);
1169
        else
1170
                return false;
1171
}
1172

    
1173
/* construct list of free ports */
1174
function free_port_list() {
1175
	global $config;
1176

    
1177
	/* initialize variables */
1178
	$port_list	= array();
1179
	$first_port 	= 1194;
1180
	$max		= $first_port + 21;
1181

    
1182
	for ($i = $first_port; $i < $max; $i++)
1183
		array_push($port_list, $i);
1184
        
1185
        /* delete port in use from the list */
1186
        if ($a_server = $config['ovpn']['server']['tunnel']) {
1187
                foreach ($a_server as $server) {
1188
                        $entry = array();
1189
                        array_push($entry, $server['port']);
1190
                        $port_list = array_diff($port_list, $entry);
1191
                }
1192
        }
1193

    
1194
        /* same for list of client tunnels  */
1195
        if ($a_client = $config['ovpn']['client']['tunnel']) {
1196
                foreach ($a_client as $client) {
1197
                        $entry = array();
1198
                        array_push($entry, $client['cport']);
1199
                        $port_list = array_diff($port_list, $entry);
1200
                }
1201
        }
1202

    
1203
	return $port_list;
1204
}
1205

    
1206
/* construct list of used ports */
1207
function used_port_list() {
1208
	global $config;
1209

    
1210
	/* initialize variables */
1211
	$port_list	= array();
1212

    
1213
        /* add used ports to the list */
1214
        if ($a_server = $config['ovpn']['server']['tunnel']) {
1215
                foreach ($a_server as $server) {
1216
                        if (isset($server['enable']))
1217
				array_push($port_list, $server['port']);
1218
                }
1219
        }
1220

    
1221
        /* same for list of client tunnels  */
1222
        if ($a_client = $config['ovpn']['client']['tunnel']) {
1223
                foreach ($a_client as $client) {
1224
                        if (isset($client['enable']))
1225
                        	array_push($port_list, $client['cport']);
1226
                }
1227
        }
1228

    
1229
	return $port_list;
1230
}
1231

    
1232
/* construct list of bindings used for a specified port */
1233
function used_bind_list($port) {
1234
	global $config;
1235

    
1236
	/* initialize variables */
1237
	$bind_list	= array();
1238

    
1239
        /* add used bindings to the list */
1240
        if ($a_server = $config['ovpn']['server']['tunnel']) {
1241
                foreach ($a_server as $server) {
1242
                        if (isset($server['enable']) && $server['port'] == $port)
1243
				array_push($bind_list, $server['bind_iface']);
1244
                }
1245
        }
1246

    
1247
	/* client daemon always binds to 0.0.0.0 */
1248
	if ($a_client = $config['ovpn']['client']['tunnel']) {
1249
		foreach ($a_client as $client) {
1250
			if (isset($client['enable']) && $client['cport'] == $port)
1251
				array_push($bind_list, "all");
1252
		}
1253
	}
1254

    
1255
	/* return list of bindings */
1256
	return $bind_list;
1257
}
1258

    
1259
/* Calculate the last address in a range given the start and /prefix */
1260
function ovpn_calc_end($start, $prefix){
1261
	$first = ip2long($start);
1262
	$last = pow(2,(32 - $prefix)) - 1 + $first;
1263
	return long2ip($last);
1264
}
1265

    
1266
/* Calculate a mask given a /prefix */
1267
function ovpn_calc_mask($prefix){
1268
	return long2ip(ip2long("255.255.255.255") - (pow( 2, (32 - $prefix)) - 1));
1269
}
1270

    
1271
/* Port in use */
1272
function ovpn_port_inuse_server($port){
1273
	global $config;
1274
	if ($a_server = $config['ovpn']['server']['tunnel']) {
1275
		foreach ($a_server as $server) {
1276
			if ($server['port'] == $port) {
1277
				return true;
1278
			}
1279
		}
1280
	}
1281
	return false;
1282
}
1283

    
1284
/* Read in a file from the $_FILES array */
1285
function ovpn_get_file($file){
1286
	global $g;
1287
	
1288
	if (!is_uploaded_file($_FILES[$file]['tmp_name'])){
1289
		trigger_error("Bad file upload".$_FILES[$file]['error'], E_USER_NOTICE);
1290
		return NULL;
1291
	}
1292
	$contents = file_get_contents($_FILES[$file]['tmp_name']);
1293
	return $contents;
1294
}
1295

    
1296

    
1297
/* Get the IP address of a specified interface */
1298
function ovpn_get_ip($iface){
1299
	global $config;
1300
	
1301
	if ($iface == 'wan')
1302
		return get_current_wan_address();
1303
		
1304
	if ($config['interfaces'][$iface]['bridge'])
1305
		/* No bridging (yet) */
1306
		return false;
1307
	return $config['interfaces'][$iface]['ipaddr'];
1308
}
1309
	
1310
	
1311
/* Get a list of the cipher options supported by OpenVPN */
1312
function ovpn_get_cipher_list(){
1313
	
1314
/*	exec("/usr/local/sbin/openvpn --show-ciphers", $raw);
1315
	print_r ($raw);
1316
	
1317
	$ciphers = preg_grep('/ bit default key /', $raw);
1318
	
1319
	for($i = 0; $i <count($ciphers); $i++){
1320
		$tmp = explode(' ',$ciphers[$i]);
1321
		$cipher_list["$tmp[0]"] = "{$tmp[0]} ({$tmp[1]} {$tmp[2]})";
1322
	}
1323
*/
1324
	$cipher_list = array('DES-CBC' => 'DES-CBC (64 bit)',
1325
			     'RC2-CBC' => 'RC2-CBC (128 bit)',
1326
			     'DES-EDE-CBC' => 'DES-EDE-CBC (128 bit)',
1327
			     'DES-EDE3-CBC' => 'DES-EDE3-CBC (192 bit)',
1328
			     'DESX-CBC' => 'DESX-CBC (192 bit)',
1329
			     'BF-CBC' => 'BF-CBC (128 bit)',
1330
			     'RC2-40-CBC' => 'RC2-40-CBC (40 bit)',
1331
			     'CAST5-CBC' => 'CAST5-CBC (128 bit)',
1332
			     'RC5-CBC' => 'RC5-CBC (128 bit)',
1333
			     'RC2-64-CBC' => 'RC2-64-CBC (64 bit)',
1334
			     'AES-128-CBC' => 'AES-128-CBC (128 bit)',
1335
			     'AES-192-CBC' => 'AES-192-CBC (192 bit)',
1336
			     'AES-256-CBC' => 'AES-256-CBC (256 bit)');
1337
	return $cipher_list;
1338
}
1339
		
1340
	
1341
/* Get optional interface */
1342
/* needs tunneling interface (tun0, tun1, tap0, ...) */
1343
/* returns optional interface name (opt2, opt3, ...) */
1344
function ovpn_get_opt_interface($tun){
1345
	global $config;
1346

    
1347
	for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
1348
		$ifname = 'opt' . $i;
1349

    
1350
		if (isset($config['interfaces']['opt' . $i]['ovpn']))
1351
			if ($config['interfaces'][$ifname]['if'] == "$tun")
1352
				 return $ifname;
1353
	}
1354
	/* not found? */
1355
	return false;
1356
}
1357

    
1358
/* Build a list of the current real interfaces */
1359
function ovpn_real_interface_list(){
1360
	global $config;
1361
	
1362
	$interfaces = array('all' => 'ALL',
1363
			    'lan' => 'LAN',
1364
			    'wan' => 'WAN');
1365
	for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
1366
		if (isset($config['interfaces']['opt' . $i]['ovpn']))
1367
			/* Hide our own interface */
1368
			break;
1369
		if (isset($config['interfaces']['opt' . $i]['enable']))
1370
			$interfaces['opt' . $i] = $config['interfaces']['opt' . $i]['descr'];
1371
	}
1372
	return $interfaces;
1373
}
1374

    
1375
/* called by interfaces_opt.php */
1376
function ovpn_ccd_sort() {
1377
	global $g, $config;
1378

    
1379
	function ccdcmp($a, $b) {
1380
		return strcmp($a['cn'][0], $b['cn'][0]);
1381
	}
1382

    
1383
	usort($config['ovpn']['server']['ccd'], "ccdcmp");
1384

    
1385
}
1386

    
1387
/* called by interfaces_opt.php */
1388
function ovpn_config_post() {
1389
	global $_POST, $optcfg, $pconfig;
1390
	
1391
	unset($input_errors);
1392

    
1393
	/* bridge check */
1394
	if ($_POST['bridge'] && strstr($optcfg['if'], "tun"))
1395
		$input_errors[] = "Bridging a tun interface isn't possible.";
1396

    
1397
	if (($_POST['enable'] && !isset($optcfg['enable'])) || (!$_POST['enable'] && isset($optcfg['enable'])))
1398
		$input_errors[] = "Enabling or disabling a tunneling interface isn't supported on this page.";
1399

    
1400
	if ($_POST['ipaddr'] != $optcfg['ipaddr']) 
1401
		$input_errors[] = "Changing the IP address of a tunneling interfaces isn't supported on this page.";
1402

    
1403
	if ($_POST['subnet'] != $optcfg['subnet']) 
1404
		$input_errors[] = "Changing the subnet mask of a tunneling interfaces isn't supported on this page.";
1405

    
1406
	if ($input_errors) {
1407
		$pconfig['ipaddr'] = $optcfg['ipaddr'];
1408
		$pconfig['subnet'] = $optcfg['subnet'];
1409
		$pconfig['bridge'] = $optcfg['bridge'];
1410
		$pconfig['enable'] = isset($optcfg['enable']);
1411
	}
1412

    
1413
	return $input_errors;
1414
}
1415

    
1416
function check_bridging($bridge) {
1417
	global $config;
1418
	unset($input_errors);
1419

    
1420
	/* double bridging? */
1421
	for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) { 
1422
		if ($i != $index) {
1423
			if ($config['interfaces']['opt' . $i]['bridge'] == $bridge) {
1424
				$input_errors = "Optional interface {$i} " . 
1425
				  "({$config['interfaces']['opt' . $i]['descr']}) is already bridged to " .
1426
				  "the specified interface.";
1427
			} else if ($config['interfaces']['opt' . $i]['bridge'] == "opt{$index}") {
1428
				$input_errors = "Optional interface {$i} " . 
1429
				  "({$config['interfaces']['opt' . $i]['descr']}) is already bridged to " .
1430
				  "this interface.";
1431
			}
1432
		}
1433
	}
1434

    
1435
	if ($config['interfaces'][$bridge]['bridge'])
1436
		$input_errors = "The specified interface is already bridged to another interface.";
1437

    
1438
	return $input_errors;
1439
}
1440

    
1441
/*
1442
function is_specialnet($net) {
1443
	$specialsrcdst = explode(" ", "lan");
1444
	        
1445
	if (in_array($net, $specialsrcdst))
1446
		return true;
1447
	else
1448
		return false;
1449
}
1450
*/
1451

    
1452
	
1453
/* lock openvpn information, decide that the lock file is stale after
1454
   10 seconds */
1455
function ovpn_lock() {
1456
	
1457
	global $g;
1458
	
1459
	$lockfile = "{$g['varrun_path']}/ovpn.lock";
1460
	
1461
	$n = 0;
1462
	while ($n < 10) {
1463
		/* open the lock file in append mode to avoid race condition */
1464
		if ($fd = fopen($lockfile, "x")) {
1465
			/* succeeded */
1466
			fclose($fd);
1467
			return;
1468
		} else {
1469
			/* file locked, wait and try again */
1470
			sleep(1);
1471
			$n++;
1472
		}
1473
	}
1474
}
1475

    
1476
/* unlock configuration file */
1477
function ovpn_unlock() {
1478
	
1479
	global $g;
1480
	
1481
	$lockfile = "{$g['varrun_path']}/ovpn.lock";
1482
	
1483
	if (file_exists($lockfile))
1484
		unlink($lockfile);
1485
}
1486

    
1487
?>
(13-13/26)