Project

General

Profile

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

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

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

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

    
81
/*****************************/	
82
/*  Server related functions */
83
/*****************************/
84

    
85
function getnxt_server_if($type) {
86
	/* find the first available device of type $type */
87
	global $config;
88
	$a_server = $config['ovpn']['server']['tunnel'];
89
	$max = ($type == 'tun') ? 9 : 4;
90
	for ($i = 0; $i < $max ; $i++) {
91
		$hit = false;
92
		foreach ($a_server as $server) {
93
			if ($server['tun_iface'] == $type . $i) {
94
				$hit = true;
95
				break;
96
			}
97
		}
98
		if (!$hit)
99
			return $type . $i;
100
	}
101
	return false;
102
}
103

    
104
function getnxt_server_port() {
105
	/* Get first unused port */
106
	global $config;
107
	$a_server = $config['ovpn']['server']['tunnel'];
108
	$port = 1194;
109
	while (true) {
110
		$hit = false;
111
		foreach ($a_server as $server) {
112
			if ($server['port'] == $port) {
113
				$hit = true;
114
				break;
115
			}
116
		}
117
		if (!$hit)
118
			if (!ovpn_port_inuse_client($port))
119
				return $port;
120
		$port++;
121
	}
122
	return false; /* should never get here */
123
}
124

    
125
/* Configure the server */
126
function ovpn_config_server($reconfigure) {
127
	global $config, $g;
128

    
129
	foreach ($config['ovpn']['server']['tunnel'] as $id => $server) {
130
		/* get tunnel interface */
131
		$tun = $server['tun_iface'];
132
			
133
		/* kill any running openvpn daemon */
134
		killbypid($g['varrun_path']."/ovpn_srv_{$tun}.pid");
135

    
136
		if (isset($server['enable'])) {
137

    
138
			if ($g['booting'])
139
				echo "Starting OpenVPN server $id... ";
140

    
141
			/* send SIGUSR1 to running openvpn daemon */
142
			if ( $reconfigure == "true" && isset($server['dynip'])) {
143
				sigkillbypid($g['varrun_path']."/ovpn_srv_{$tun}.pid", "SIGUSR1");
144
				continue;
145
			}
146

    
147
			/* Remove old certs & keys */
148
			unlink_if_exists("{$g['vardb_path']}/ovpn_ca_cert_{$tun}.pem");
149
			unlink_if_exists("{$g['vardb_path']}/ovpn_srv_cert_{$tun}.pem");
150
			unlink_if_exists("{$g['vardb_path']}/ovpn_srv_key_{$tun}.pem");
151
			unlink_if_exists("{$g['vardb_path']}/ovpn_dh_{$tun}.pem");
152

    
153
			/* Copy the TLS-Server certs & keys to disk */
154
			$fd = fopen("{$g['vardb_path']}/ovpn_ca_cert_{$tun}.pem", "w");
155
			if ($fd) {
156
				fwrite($fd, base64_decode($server['ca_cert'])."\n");
157
				fclose($fd);	
158
			}
159
			$fd = fopen("{$g['vardb_path']}/ovpn_srv_cert_{$tun}.pem", "w");
160
			if ($fd) {
161
				fwrite($fd, base64_decode($server['srv_cert'])."\n");
162
				fclose($fd);	
163
			}
164
			touch ("{$g['vardb_path']}/ovpn_srv_key_{$tun}.pem");
165
			chmod ("{$g['vardb_path']}/ovpn_srv_key_{$tun}.pem", 0600);
166
			$fd = fopen("{$g['vardb_path']}/ovpn_srv_key_{$tun}.pem", "w");
167
			if ($fd) {
168
				fwrite($fd, base64_decode($server['srv_key'])."\n");
169
				fclose($fd);	
170
			}
171
			$fd = fopen("{$g['vardb_path']}/ovpn_dh_{$tun}.pem", "w");
172
			if ($fd) {
173
				fwrite($fd, base64_decode($server['dh_param'])."\n");
174
				fclose($fd);	
175
			}
176

    
177
			/* Start the openvpn daemon */
178
			mwexec("/usr/local/sbin/openvpn " . ovpn_srv_config_generate($id));
179

    
180
			if ($g['booting'])
181
				/* Send the boot message */
182
				echo "done\n";
183
		}
184
		else {
185
			if (!$g['booting']){
186
				/* stop any processes, unload the tap module */
187
				/* Remove old certs & keys */
188
				ovpn_server_kill($tun);
189

    
190
				if ($server['type'] == "tap")
191
					ovpn_unlink_tap();
192
			}
193
		}
194
	}
195
	return 0;
196
}
197

    
198
/* Kill off a running server process */
199
function ovpn_server_kill($tun) {
200
	global $g;
201
	
202
	killbypid("{$g['varrun_path']}/ovpn_srv_{$tun}.pid");
203

    
204
	/* Remove old certs & keys */
205
	unlink_if_exists("{$g['vardb_path']}/ovpn_ca_cert_{$tun}.pem");
206
	unlink_if_exists("{$g['vardb_path']}/ovpn_srv_cert_{$tun}.pem");
207
	unlink_if_exists("{$g['vardb_path']}/ovpn_srv_key_{$tun}.pem");
208
	unlink_if_exists("{$g['vardb_path']}/ovpn_dh_{$tun}.pem");
209

    
210
	return 0;
211
}
212

    
213
/* Generate the config for a OpenVPN server */
214
function ovpn_srv_config_generate($id) {
215
	global $config, $g;
216
	$server = $config['ovpn']['server']['tunnel'][$id];
217

    
218
	/* get tunnel interface */
219
	$tun = $server['tun_iface'];
220

    
221
	/* First the generic stuff:
222
		- We are a server
223
		- We are a TLS Server (for authentication)
224
		- We will run without privilege
225
	*/
226
	$ovpn_config = "--daemon --user nobody --group nobody --verb {$server['verb']} --persist-tun --persist-key ";
227
	
228
	/* pid file */
229
	$ovpn_config .= "--writepid {$g['varrun_path']}/ovpn_srv_{$tun}.pid ";
230
	
231
	/* interface */
232
	$ovpn_config .= "--dev {$server['tun_iface']} ";
233
	
234
	/* port */
235
	$ovpn_config .= "--port {$server['port']} ";
236

    
237
	/* Set protocol being used (p = udp (default), tcp-server)
238
	if ($server['proto'] == 'tcp') {
239
		$ovpn_config .= "--proto tcp-server";
240
	}
241
	
242
	/* Interface binding - 1 or all */
243
	if ($server['bind_iface'] != 'all') {
244
		if ($ipaddr = ovpn_get_ip($server['bind_iface']))
245
			$ovpn_config .= "--local $ipaddr ";
246
		else
247
			return "Interface bridged";
248
	}
249

    
250
	/* are we using dynamic ip addresses? */
251
	if (isset($server['dynip']))
252
		$ovpn_config .= "--persist-remote-ip ";
253
	
254
	/* Client to client routing (off by default) */
255
	if (isset($server['cli2cli']))
256
		$ovpn_config .= "--client-to-client ";
257
	
258
	/* Set maximum simultaneous clients */
259
	$ovpn_config .= "--max-clients {$server['maxcli']} ";
260
	 
261
	/* New --server macro simplifies config */
262
	$mask = ovpn_calc_mask($server['prefix']);
263
	$ovpn_config .= "--server {$server['ipblock']} {$mask} ";
264
	
265
	/* TLS-Server params */
266
	$ovpn_config .= "--ca {$g['vardb_path']}/ovpn_ca_cert_{$tun}.pem ";
267
	$ovpn_config .= "--cert {$g['vardb_path']}/ovpn_srv_cert_{$tun}.pem ";
268
	$ovpn_config .= "--key {$g['vardb_path']}/ovpn_srv_key_{$tun}.pem ";
269
	$ovpn_config .= "--dh {$g['vardb_path']}/ovpn_dh_{$tun}.pem ";
270
	
271
	/* Data channel encryption cipher*/
272
	$ovpn_config .= "--cipher {$server['crypto']} ";
273
	
274
	/* Duplicate CNs */
275
	if (isset($server['dupcn']))
276
		$ovpn_config .= "--duplicate-cn ";
277
		
278
	/* Client push - redirect gateway */
279
	if (isset($server['psh_options']['redir'])){
280
		if (isset($server['psh_options']['redir_loc']))
281
			$ovpn_config .= "--push \"redirect-gateway local\" ";
282
		else
283
			$ovpn_config .= "--push \"redirect-gateway\" ";
284
	}
285
			
286
	/* Client push - route delay */
287
	if (isset($server['psh_options']['rte_delay']))
288
		$ovpn_config .= "--push \"route-delay {$server['psh_options']['rte_delay']}\" ";
289
		
290
	/* Client push - ping (note we set both server and client) */
291
	if (isset ($server['psh_options']['ping'])){
292
		$ovpn_config .= "--ping {$server['psh_options']['ping']} ";
293
		$ovpn_config .= "--push \"ping {$server['psh_options']['ping']}\" ";
294
	}
295
	
296
	/* Client push - ping-restart (note server uses 2 x client interval) */
297
	if (isset ($server['psh_options']['pingrst'])){
298
		$interval = $server['psh_options']['pingrst'];
299
		$ovpn_config .= "--ping-restart " . ($interval * 2) . " ";
300
		$ovpn_config .= "--push \"ping-restart $interval\" ";
301
	}
302
	
303
	/* Client push - ping-exit (set on client) */
304
	if (isset ($server['psh_options']['pingexit'])){
305
		$ovpn_config .= "--ping-exit {$server['psh_options']['pingexit']} ";
306
		$ovpn_config .= "--push \"ping-exit {$server['psh_options']['pingexit']}\" ";
307
	}
308
	
309
	/* Client push - inactive (set on client) */
310
	if (isset ($server['psh_options']['inact'])){
311
		$ovpn_config .= "--inactive {$server['psh_options']['pingexit']} ";
312
		$ovpn_config .= "--push \"inactive {$server['psh_options']['inact']}\" ";
313
	}
314

    
315
	//trigger_error("OVPN: $ovpn_config", E_USER_NOTICE);
316
	return $ovpn_config;
317
}
318

    
319
/* Define an OVPN Server tunnel interface in the interfaces array and assign a name */
320
function ovpn_server_iface(){
321
	global $config, $g;
322
	
323
	foreach ($config['ovpn']['server']['tunnel'] as $id => $server) {
324
		if (isset($server['enable'])) {
325

    
326
			/* get tunnel interface */
327
			$tun = $server['tun_iface'];
328
			
329
			$i = 1;
330
			while (true) {
331
				$ifname = 'opt' . $i;
332
				if (is_array($config['interfaces'][$ifname])) {
333
					if ((isset($config['interfaces'][$ifname]['ovpn']))
334
					     && ($config['interfaces'][$ifname]['ovpn'] == "server_{$tun}"))
335
						/* Already an interface defined - overwrite */
336
						break;
337
				}
338
				else {
339
					/* No existing entry, this is first unused */
340
					$config['interfaces'][$ifname] = array();
341
					break;
342
				}
343
				$i++;
344
			}
345
			if (isset($server['descr']))
346
				$config['interfaces'][$ifname]['descr'] = $server['descr'];
347
			else
348
				$config['interfaces'][$ifname]['descr'] = "OVPN server-{$tun}";
349
			$config['interfaces'][$ifname]['if'] = $server['tun_iface'];
350
			$config['interfaces'][$ifname]['ipaddr'] = long2ip( ip2long($server['ipblock']) + 1);
351
			$config['interfaces'][$ifname]['subnet'] = $server['prefix'];
352
			$config['interfaces'][$ifname]['enable'] = isset($server['enable']) ? true : false;
353
			$config['interfaces'][$ifname]['ovpn'] = "server_{$tun}";
354

    
355
			write_config();
356
		}
357
	}
358
	return "OpenVPN server interface defined";
359
}
360

    
361
/* Delete a server interface definition */
362
function ovpn_server_iface_del($tun) {
363
	global $config;
364

    
365
	for ($i = 1; is_array($config['interfaces']['opt' . $i]); $i++) {
366
		$ifname = 'opt' . $i;
367
		if ((isset($config['interfaces'][$ifname]['ovpn']))
368
		     && ($config['interfaces'][$ifname]['if'] == "$tun")) {
369
			unset($config['interfaces'][$ifname]);
370
			break;
371
		}
372
	}
373

    
374

    
375
	/* shift down other OPTn interfaces to get rid of holes */
376
	$i++;
377

    
378
	/* look at the following OPTn ports */
379
	while (is_array($config['interfaces']['opt' . $i])) {
380
		$config['interfaces']['opt' . ($i - 1)] =
381
			$config['interfaces']['opt' . $i];
382

    
383
		unset($config['interfaces']['opt' . $i]);
384
		$i++;
385
	}
386
}
387

    
388

    
389
/****************************/
390
/* Client related functions */
391
/****************************/
392

    
393
function getnxt_client_if($type) {
394
	/* find the first available device of type $type */
395
	global $config;
396
	$a_client = $config['ovpn']['client']['tunnel'];
397
	$max = ($type == 'tun') ? 9 : 4;
398
	for ($i = $max; $i < ($max+$max) ; $i++) {
399
		$hit = false;
400
		foreach ($a_client as $client) {
401
			if ($client['if'] == $type . $i) {
402
				$hit = true;
403
				break;
404
			}
405
		}
406
		if (!$hit)
407
			return $type . $i;
408
	}
409
        return false;
410
}
411

    
412
function getnxt_client_port() {
413
        /* Get first unused port */
414
	global $config;
415
	$a_client = $config['ovpn']['client']['tunnel'];
416
	$port = 1194;
417
	while (true) {
418
		$hit = false;
419
		foreach ($a_client as $client) {
420
			if ($client['port'] == $port) {
421
				$hit = true;
422
				break;
423
			}
424
		}
425
		if (!$hit)
426
			if (!ovpn_port_inuse_server($port))
427
				return $port;
428
		$port++;
429
	}
430
	return false; /* should never get here */
431
}
432

    
433
/* Port in use */
434
function ovpn_port_inuse_client($port){
435
	global $config;
436
	$a_client = $config['ovpn']['client']['tunnel'];
437
	foreach ($a_client as $client) {
438
		if ($client['port'] == $port) {
439
			return true;
440
		}
441
	}
442
	return false;
443
}
444

    
445
function ovpn_config_client() {
446
	/* Boot time configuration */
447
	global $config, $g;
448
	
449
	foreach ($config['ovpn']['client']['tunnel'] as $id => $client) {
450

    
451
		/* get tunnel interface */
452
		$tun = $client['if'];
453

    
454
		/* kill any running openvpn daemon */
455
		killbypid($g['varrun_path']."/ovpn_cli_{$tun}.pid");
456

    
457
		if (isset($client['enable'])) {
458
	
459
			if ($g['booting'])
460
				echo "Starting OpenVPN client $id... ";
461
		
462
			/* Remove old certs & keys */
463
			unlink_if_exists("{$g['vardb_path']}/ovpn_cli_ca_cert_{$tun}.pem");
464
			unlink_if_exists("{$g['vardb_path']}/ovpn_cli_cert_{$tun}.pem");
465
			unlink_if_exists("{$g['vardb_path']}/ovpn_cli_key_{$tun}.pem");
466
		
467
			/* Copy the TLS-Client certs & keys to disk */
468
			$fd = fopen("{$g['vardb_path']}/ovpn_cli_ca_cert_{$tun}.pem", "w");
469
			if ($fd) {
470
				fwrite($fd, base64_decode($client['ca_cert'])."\n");
471
				fclose($fd);	
472
			}
473
			else
474
				trigger_error("OVPN: No open for CA", E_USER_NOTICE);
475
			$fd = fopen("{$g['vardb_path']}/ovpn_cli_cert_{$tun}.pem", "w");
476
			if ($fd) {
477
				fwrite($fd, base64_decode($client['cli_cert'])."\n");
478
				fclose($fd);	
479
			}
480
			touch ("{$g['vardb_path']}/ovpn_cli_key_{$tun}.pem");
481
			chmod ("{$g['vardb_path']}/ovpn_cli_key_{$tun}.pem", 0600);
482
			$fd = fopen("{$g['vardb_path']}/ovpn_cli_key_{$tun}.pem", "w");
483
			if ($fd) {
484
				fwrite($fd, base64_decode($client['cli_key'])."\n");
485
				fclose($fd);	
486
			}
487
				
488
			/* Start openvpn for this client */
489
			mwexec("/usr/local/sbin/openvpn " . ovpn_cli_config_generate($id));
490
		
491
			if ($g['booting'])
492
				/* Send the boot message */
493
				echo "done\n";
494
		}
495
		else {
496
			if (!$g['booting']){
497
				/* stop any processes, unload the tap module */
498
				/* Remove old certs & keys */
499
				ovpn_client_kill($tun);
500

    
501
				if ($client['type'] == "tap")
502
					ovpn_unlink_tap();
503
			}
504
		}
505
	}
506
	return 0;
507
	
508
}
509

    
510
/* Kill off a running client process */
511
function ovpn_client_kill($tun) {
512
	global $g;
513
	
514
	killbypid("{$g['varrun_path']}/ovpn_cli_{$tun}.pid");
515
	
516
	/* Remove old certs & keys */
517
	unlink_if_exists("{$g['vardb_path']}/ovpn_cli_ca_cert_{$tun}.pem");
518
	unlink_if_exists("{$g['vardb_path']}/ovpn_cli_cert_{$tun}.pem");
519
	unlink_if_exists("{$g['vardb_path']}/ovpn_cli_key_{$tun}.pem");
520

    
521
	return 0;
522
}
523

    
524
/* Generate the config for a OpenVPN client */
525
function ovpn_cli_config_generate($id) {
526
	/* configure the named client */
527
	global $config, $g;
528
	$client = $config['ovpn']['client']['tunnel'][$id];
529

    
530
	/* get tunnel interface */
531
	$tun = $client['if'];
532
	
533
	/* Client support in 2.0 is very simple */
534
	
535
	$ovpn_config = "--client --daemon --verb 1 ";
536
	
537
	/* pid file */
538
	$ovpn_config .= "--writepid {$g['varrun_path']}/ovpn_cli_{$tun}.pid ";
539
	
540
	/* interface */
541
	$ovpn_config .= "--dev {$client['if']} ";
542
	
543
	/* protocol */
544
	/* Set protocol being used (p = udp (default), tcp-client)
545
	if ($client['proto'] == 'tcp') {
546
		$ovpn_config .= "--proto tcp-client";
547
	}
548
	
549
	/* port */
550
	$ovpn_config .= "--lport {$client['port']} ";
551
	
552
	/* server location */
553
	$ovpn_config .= "--remote {$client['saddr']} {$client['sport']} ";
554
	
555
	/* TLS-Server params */
556
	$ovpn_config .= "--ca {$g['vardb_path']}/ovpn_cli_ca_cert_{$tun}.pem ";
557
	$ovpn_config .= "--cert {$g['vardb_path']}/ovpn_cli_cert_{$tun}.pem ";
558
	$ovpn_config .= "--key {$g['vardb_path']}/ovpn_cli_key_{$tun}.pem ";
559
		
560
	/* Data channel encryption cipher*/
561
	$ovpn_config .= "--cipher {$client['crypto']} ";
562
	
563
	//trigger_error("OVPN: $ovpn_config", E_USER_NOTICE);
564
	return $ovpn_config;
565
}
566

    
567
/* Define an OVPN tunnel interface in the interfaces array for each client */
568
function ovpn_client_iface(){
569
	global $config;
570
		
571
	foreach ($config['ovpn']['client']['tunnel'] as $id => $client) {
572
		if (isset($client['enable'])) {
573

    
574
			/* get tunnel interface */
575
			$tun = $client['if'];
576

    
577
			$i = 1;
578
			while (true) {
579
				$ifname = 'opt' . $i;
580
				if (is_array($config['interfaces'][$ifname])) {
581
					if ((isset($config['interfaces'][$ifname]['ovpn']))
582
			     		     && ($config['interfaces'][$ifname]['ovpn'] == "client_{$tun}"))
583
						/* Already an interface defined - overwrite */
584
						break;
585
				}
586
				else {
587
					/* No existing entry, this is first unused */
588
					$config['interfaces'][$ifname] = array();
589
					break;
590
				}
591
				$i++;
592
			}
593
			if (isset($client['descr']))
594
				$config['interfaces'][$ifname]['descr'] = $client['descr'];
595
			else
596
				$config['interfaces'][$ifname]['descr'] = "OVPN client-{$tun}";
597
			$config['interfaces'][$ifname]['if'] = $client['if'];
598
			$config['interfaces'][$ifname]['ipaddr'] = "0.0.0.0";
599
			$config['interfaces'][$ifname]['subnet'] = "0";
600
			$config['interfaces'][$ifname]['enable'] = isset($client['enable']) ? true : false;
601
			$config['interfaces'][$ifname]['ovpn'] = "client_{$tun}";
602
			write_config();
603
		}
604
	}
605
	return "OpenVPN client interfaces defined";
606
}
607

    
608
/* Delete a client interface definition */
609
function ovpn_client_iface_del($tun) {
610
	global $config;
611

    
612
	for ($i = 1; is_array($config['interfaces']['opt' . $i]); $i++) {
613
		$ifname = 'opt' . $i;
614
		if ((isset($config['interfaces'][$ifname]['ovpn']))
615
		     && ($config['interfaces'][$ifname]['if'] == "$tun")) {
616
			unset($config['interfaces'][$ifname]);
617
			break;
618
		}
619
	}
620

    
621

    
622
	/* shift down other OPTn interfaces to get rid of holes */
623
	$i++;
624

    
625
	/* look at the following OPTn ports */
626
	while (is_array($config['interfaces']['opt' . $i])) {
627
		$config['interfaces']['opt' . ($i - 1)] =
628
			$config['interfaces']['opt' . $i];
629

    
630
		unset($config['interfaces']['opt' . $i]);
631
		$i++;
632
	}
633
}
634

    
635

    
636
/******************/
637
/* Misc functions */
638

    
639
/* Calculate the last address in a range given the start and /prefix */
640
function ovpn_calc_end($start, $prefix){
641

    
642
	$first = ip2long($start);
643
	$last = pow(2,(32 - $prefix)) - 1 + $first;
644
	return long2ip($last);
645
}
646

    
647
/* Calculate a mask given a /prefix */
648
function ovpn_calc_mask($prefix){
649

    
650
	return long2ip(ip2long("255.255.255.255") - (pow( 2, (32 - $prefix)) - 1));
651
}
652

    
653
/* Port in use */
654
function ovpn_port_inuse_server($port){
655
	global $config;
656
	$a_server = $config['ovpn']['server']['tunnel'];
657
	foreach ($a_server as $server) {
658
		if ($server['port'] == $port) {
659
			return true;
660
		}
661
	}
662
	return false;
663
}
664

    
665
/* Read in a file from the $_FILES array */
666
function ovpn_get_file($file){
667
	global $g;
668
	
669
	if (!is_uploaded_file($_FILES[$file]['tmp_name'])){
670
		trigger_error("Bad file upload".$_FILES[$file]['error'], E_USER_NOTICE);
671
		return NULL;
672
	}
673
	$contents = file_get_contents($_FILES[$file]['tmp_name']);
674
	return $contents;
675
}
676

    
677

    
678
/* Get the IP address of a specified interface */
679
function ovpn_get_ip($iface){
680
	global $config;
681
	
682
	if ($iface == 'wan')
683
		return get_current_wan_address();
684
		
685
	if ($config['interfaces'][$iface]['bridge'])
686
		/* No bridging (yet) */
687
		return false;
688
	return $config['interfaces'][$iface]['ipaddr'];
689
}
690
	
691
/* Get a list of the cipher options supported by OpenVPN */
692
function ovpn_get_cipher_list(){
693
	
694
/*	exec("/usr/local/sbin/openvpn --show-ciphers", $raw);
695
	print_r ($raw);
696
	
697
	$ciphers = preg_grep('/ bit default key /', $raw);
698
	
699
	for($i = 0; $i <count($ciphers); $i++){
700
		$tmp = explode(' ',$ciphers[$i]);
701
		$cipher_list["$tmp[0]"] = "{$tmp[0]} ({$tmp[1]} {$tmp[2]})";
702
	}
703
*/
704
	$cipher_list = array('DES-CBC' => 'DES-CBC (64 bit)',
705
			     'RC2-CBC' => 'RC2-CBC (128 bit)',
706
			     'DES-EDE-CBC' => 'DES-EDE-CBC (128 bit)',
707
			     'DES-EDE3-CBC' => 'DES-EDE3-CBC (192 bit)',
708
			     'DESX-CBC' => 'DESX-CBC (192 bit)',
709
			     'BF-CBC' => 'BF-CBC (128 bit)',
710
			     'RC2-40-CBC' => 'RC2-40-CBC (40 bit)',
711
			     'CAST5-CBC' => 'CAST5-CBC (128 bit)',
712
			     'RC5-CBC' => 'RC5-CBC (128 bit)',
713
			     'RC2-64-CBC' => 'RC2-64-CBC (64 bit)',
714
			     'AES-128-CBC' => 'AES-128-CBC (128 bit)',
715
			     'AES-192-CBC' => 'AES-192-CBC (192 bit)',
716
			     'AES-256-CBC' => 'AES-256-CBC (256 bit)');
717
	return $cipher_list;
718
}
719
		
720
	
721
/* Build a list of the current real interfaces */
722
function ovpn_real_interface_list(){
723
	global $config;
724
	
725
	$interfaces = array('all' => 'ALL',
726
			    'lan' => 'LAN',
727
			    'wan' => 'WAN');
728
	for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
729
		if (isset($config['interfaces']['opt' . $i]['ovpn']))
730
			/* Hide our own interface */
731
			break;
732
		if (isset($config['interfaces']['opt' . $i]['enable']))
733
			$interfaces['opt' . $i] = $config['interfaces']['opt' . $i]['descr'];
734
	}
735
	return $interfaces;
736
}
737

    
738
	
739
/* lock openvpn information, decide that the lock file is stale after
740
   10 seconds */
741
function ovpn_lock() {
742
	
743
	global $g;
744
	
745
	$lockfile = "{$g['varrun_path']}/ovpn.lock";
746
	
747
	$n = 0;
748
	while ($n < 10) {
749
		/* open the lock file in append mode to avoid race condition */
750
		if ($fd = fopen($lockfile, "x")) {
751
			/* succeeded */
752
			fclose($fd);
753
			return;
754
		} else {
755
			/* file locked, wait and try again */
756
			sleep(1);
757
			$n++;
758
		}
759
	}
760
}
761

    
762
/* unlock configuration file */
763
function ovpn_unlock() {
764
	
765
	global $g;
766
	
767
	$lockfile = "{$g['varrun_path']}/ovpn.lock";
768
	
769
	if (file_exists($lockfile))
770
		unlink($lockfile);
771
}
772

    
773
?>
(11-11/23)