source: npl/syn3/webint/src/vpn/openswan.php @ 0b780b4

perl-5.22
Last change on this file since 0b780b4 was 0b780b4, checked in by Edwin Eefting <edwin@datux.nl>, 8 years ago

ikev2 status support

  • Property mode set to 100755
File size: 10.5 KB
Line 
1<?
2/*
3(C) 2004-2013 DatuX - info@datux.nl
4
5This program is free software: you can redistribute it and/or modify
6it under the terms of the GNU General Public License as published by
7the Free Software Foundation, either version 3 of the License, or
8(at your option) any later version.
9
10This program is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program.  If not, see <http://www.gnu.org/licenses/>.
17*/
18
19        require_once("../common.php");
20        require_once("../network/network.php");
21        require_once("../proc.php");
22        IncludeLang(__FILE__);
23
24        $VPN_IPSEC_DIR="/etc/ipsec.d";
25        $VPN_PUB="$VPN_IPSEC_DIR/ipsec.pub";
26        $VPN_TUNNEL_DIR="$VPN_IPSEC_DIR/tunnels";
27        $VPN_LOG="/var/log/secure";
28        $VPN_STARTERRORS="$VPN_IPSEC_DIR/starterrors";
29
30        function vpn_Stop()
31        {
32                if (SvcIsUp("ipsec"))
33                {
34                        SvcDown("ipsec");
35                }
36        }
37
38        //RET: false als het werk, anders error text.
39        function vpn_Restart()
40        {
41                //only works on internet server
42                if (!ModuleMatch("I"))
43                        return false; //return ok-code
44
45                vpn_Stop();
46                SvcUp("ipsec");
47        }
48
49        function vpn_StartErrors()
50        {
51                global $VPN_STARTERRORS;
52                if (is_file($VPN_STARTERRORS))
53                {
54                        $raw=FileReadRaw($VPN_STARTERRORS);
55                }
56                return ($raw);
57        }
58
59        /*function vpn_Failed()
60        {
61                global $VPN_IPSEC_DIR;
62                return (is_file("$VPN_IPSEC_DIR/failed"));
63        }
64
65        function vpn_Tested()
66        {
67                global $VPN_IPSEC_DIR;
68                return (is_file("$VPN_IPSEC_DIR/tested"));
69        }
70                */
71
72
73        //force vpn monitoring check. ( this is also done every minute with a crontab)
74        function vpn_MonUpdate($name)
75        {
76                Progress("Checking tunnel status $name...");
77                SafeExec("syn3-ipseccheck '$name'");
78                Progress("");
79        }
80
81        function vpn_TunnelUp($name)
82        {
83
84                $err=Cmd("
85                        (
86                        ipsec auto --down '$name' 2>/dev/null;
87                        ipsec auto --rereadsecrets;
88                        ipsec auto --replace '$name' &&
89                        ipsec auto --asynchronous --up '$name'
90                        ) 2>&1
91                ",'',$out,$errout);
92                if ($err!=0)
93                {
94                        $out[]="Exit code $err";
95                        LogError(_LogTunnelUpError($name,implode(" ",$out)));
96                        return false;
97                }
98                else
99                {
100                        LogInfo(_LogTunnelUp($name));
101                        return true;
102                }
103        }
104
105        function vpn_TunnelDown($name)
106        {
107                vpn_TunnelSetDownOnBoot($name,1);
108
109                $err=Cmd("ipsec auto --delete '$name' 2>&1",'',$out,$errout);
110                vpn_MonUpdate($name);
111                if ($err!=0)
112                {
113                        LogError(_TunnelDownError($name,implode(" ",$out)));
114                        return false;
115                }
116                else
117                {
118                        LogInfo(_LogTunnelDown($name));
119                        return true;
120                }
121        }
122
123        function vpn_TunnelIsTested($name)
124        {
125                global $VPN_TUNNEL_DIR;
126                return (!is_file("$VPN_TUNNEL_DIR/$name.untested"));
127        }
128
129        function vpn_TunnelSetTested($name,$tested)
130        {
131                global $VPN_TUNNEL_DIR;
132
133                if ($tested)
134                        FileDelete("$VPN_TUNNEL_DIR/$name.untested");
135                else
136                        FileWriteRaw("$VPN_TUNNEL_DIR/$name.untested","");
137        }
138
139        function vpn_TunnelIsDownOnBoot($name)
140        {
141                $tunnel=vpn_ReadTunnel($name);
142                return ($tunnel["auto"]=="up");
143        }
144
145        function vpn_TunnelSetDownOnBoot($name,$down)
146        {
147                $tunnel=vpn_ReadTunnel($name);
148                if ($down)
149                        $tunnel["auto"]="ignore";
150                else
151                        $tunnel["auto"]="up";
152                vpn_WriteTunnel($name, $tunnel, false);
153        }
154
155
156        //gooi tunnel up, maar run backup script voor het geval er netwerk
157        //conflict is. in dit geval gaat tunnel weer down
158        function vpn_TunnelTestStart($name)
159        {
160                //test loopt nog?
161                if ($_SESSION[testtunnel] && posix_kill($_SESSION[testtunnel][pid],0))
162                        Error(_TestAlreadyRunning());
163
164                //start het backup script en onthoudt PID
165                $_SESSION[testtunnel][pid]=BgExec("exec testtunnel.sh '$name'");
166                $_SESSION[testtunnel][name]=$name;
167                vpn_TunnelSetTested($name,1); //het backup script zet hem weer op 0 als het misgaat
168                vpn_TunnelUp($name); //niet controleren op errors
169                return true;
170        }
171
172        //Controleer of er nog een test loopt, en of deze geslaagd is.
173        //Roep deze functie aan NA het refreshen van de pagina, zodat je weet
174        //dat de netwerk settings niet verstoord zijn.
175        function vpn_TunnelTestEnd()
176        {
177                //is there a test running?
178                if ($_SESSION[testtunnel])
179                {
180                        //kill het backup script BOEM
181                        posix_kill($_SESSION[testtunnel][pid],9);
182
183                        $name=$_SESSION[testtunnel][name];
184                        //test is klaar nu
185                        unset($_SESSION[testtunnel]);
186
187                        //kijk of test gelukt of mislukt is en wijzig config
188                        if (!vpn_TunnelIsTested($name))
189                        {
190                                LogError(_LogTunnelTestFailed($name));
191                        }
192                        else
193                        {
194                                vpn_TunnelSetDownOnBoot($name, 0);
195                                vpn_MonUpdate($name);
196                        }
197                }
198        }
199
200        function vpn_ReadSecret($name)
201        {
202                global $VPN_TUNNEL_DIR;
203                $line=FileReadRaw("$VPN_TUNNEL_DIR/$name.key");
204                preg_match('/"(.*)"/',$line,$matches);
205                return ($matches[1]);
206        }
207
208        function vpn_WriteSecret($name,$secret)
209        {
210                global $VPN_TUNNEL_DIR;
211                $tunnel=vpn_ReadTunnel($name);
212
213                $line="$tunnel[leftid] $tunnel[right]: PSK \"$secret\"\n";
214                FileWriteRaw("$VPN_TUNNEL_DIR/$name.key",$line);
215        }
216
217        function vpn_ValidName($name)
218        {
219                return (
220                        (!preg_match("/[^a-z0-9-]/",$name)) &&
221                        (strlen($name)<25) &&
222                        (strlen($name)>=3)
223                );
224        }
225
226        function vpn_ValidSecret($secret)
227        {
228                return (
229                        (strlen($secret)>=8)
230                );
231        }
232
233
234        function vpn_ValidPubKey($key)
235        {
236                $key=vpn_ReadableToPub($key);
237                return (
238                        (strlen($key)==370) &&
239                        (substr($key,0,2)=='0s') &&
240                        (!preg_match("/[^A-Za-z0-9+\/]/",substr($key,2)))
241                );
242        }
243
244        function vpn_SameKey($key1,$key2)
245        {
246                $key1=vpn_ReadableToPub($key1);
247                $key2=vpn_ReadableToPub($key2);
248                return ($key1==$key2);
249        }
250
251
252        function vpn_ReadPubKey()
253        {
254                global $VPN_PUB;
255                $raw=FileReadMatches($VPN_PUB,"/#pubkey=/");
256                preg_match("/.*pubkey=(.*)/",$raw[0],$matches);
257                return ($matches[1]);
258        }
259
260        //make key readable (insert new-lines etc)
261        function vpn_PubToReadable($pubkey)
262        {
263                return(preg_replace("/(.{50})/","\$0\n",$pubkey));
264        }
265
266        //filter all the crap from a readable key
267        function vpn_ReadableToPub($pubkey)
268        {
269                return(preg_replace("/[^A-Za-z0-9+\/=]/","",$pubkey));
270        }
271
272        //returns corresponding tunnel filename
273        function vpn_GetTunnelFile($name)
274        {
275                global $VPN_TUNNEL_DIR;
276                return ("$VPN_TUNNEL_DIR/$name.conf");
277        }
278
279        function vpn_ReadTunnel($name)
280        {
281                $raw=FileRead(vpn_GetTunnelFile($name));
282                foreach ($raw as $line)
283                {
284                        if (preg_match("/^[^a-z-0-9]*([a-z0-9]*)=(.*)$/",$line,$matches))
285                                $ret[$matches[1]]=$matches[2];
286                }
287                return ($ret);
288        }
289
290        function vpn_ReadTunnels()
291        {
292                global $VPN_TUNNEL_DIR;
293                $dh=opendir($VPN_TUNNEL_DIR);
294                while ($file=readdir($dh))
295                {
296                        if (preg_match("/^(.*).conf$/",$file,$matches))
297                        {
298                                if ($matches[1] != "dummy")
299                                        $ret[$matches[1]]=vpn_ReadTunnel($matches[1]);
300                        }
301                }
302                return ($ret);
303        }
304
305        function vpn_WriteTunnel($name,$data, $needs_testing=true)
306        {
307                global $VPN_IPSEC_DIR;
308                global $VPN_TUNNEL_DIR;
309                $raw[]="conn $name";
310                foreach ($data as $varname=>$varvalue)
311                {
312                        $raw[]="\t$varname=$varvalue";
313                }
314                //mark configuration as untested
315                if ($needs_testing)
316                        FileWriteRaw("$VPN_TUNNEL_DIR/$name.untested");
317
318                FileWrite(vpn_GetTunnelFile($name),$raw);
319                LogInfo(_LogVPNSettingsChanged($name));
320        }
321
322        function vpn_DelTunnel($name)
323        {
324                global $VPN_TUNNEL_DIR;
325                vpn_TunnelDown($name);
326
327                FileDelete("$VPN_TUNNEL_DIR/$name.conf");
328                FileDelete("$VPN_TUNNEL_DIR/$name.mon");
329                FileDelete("$VPN_TUNNEL_DIR/$name.key");
330                FileDelete("$VPN_TUNNEL_DIR/$name.down");
331                FileDelete("$VPN_TUNNEL_DIR/$name.untested");
332                LogInfo(_LogVPNTunnelDeleted($name));
333        }
334
335
336        $VPN_STATES_1=array(
337                //ike v1
338                'STATE_MAIN_I1'=>"Connecting...",
339                'STATE_MAIN_R1'=>"Connecting...",
340                'STATE_MAIN_I2'=>"Connecting...",
341
342                'STATE_MAIN_I3'=>"Checking keys...",
343                'STATE_MAIN_R2'=>"Checking keys...",
344
345                'STATE_MAIN_I4'=>"OK",
346                'STATE_MAIN_R3'=>"OK",
347
348
349                //ike v2
350                'STATE_PARENT_I2'=>"Negotiating...",
351
352                'STATE_PARENT_I3'=>"OK",
353                'STATE_PARENT_R2'=>"OK",
354
355        );
356
357        $VPN_STATES_2=array(
358                //ike v1
359                'STATE_QUICK_I1'=>"Negotiating tunnel...",
360                'STATE_QUICK_R1'=>"Negotiating tunnel...",
361
362                'STATE_QUICK_I2'=>"OK",
363                'STATE_QUICK_R2'=>"OK",
364
365
366                //ike v2
367                'STATE_V2_IPSEC_I'=>"OK",
368                'STATE_V2_IPSEC_R'=>"OK",
369
370        );
371
372        //
373        //
374        // $VPN_PRIO=array(
375        //              'Main'=>0,
376        //      'STATE_MAIN_I1'=>1,
377        //              'STATE_MAIN_R1'=>2,
378        //      'STATE_MAIN_I2'=>3,
379        //      'STATE_MAIN_I3'=>4,
380        //              'STATE_MAIN_R2'=>5,
381        //      'STATE_MAIN_I4'=>6,
382        //              'STATE_MAIN_R3'=>7,
383        //      'Quick'=>8,
384        //      'STATE_QUICK_I1'=>9,
385        //              'STATE_QUICK_R1'=>10,
386        //      'STATE_QUICK_I2'=>11,
387        //              'STATE_QUICK_R2'=>12,
388        // );
389
390        //determines phase1 and phase2 state from logline
391        function vpn_LogToState($logline)
392        {
393                global $VPN_STATES_1;
394                global $VPN_STATES_2;
395
396                $ret=[];
397                if (preg_match("/(STATE_[0-9_A-Z]*)/",$logline,$matches))
398                {
399                        $state=$matches[1];
400                        if ($VPN_STATES_1[$state])
401                                $ret['phase1']=$VPN_STATES_1[$state];
402                        if ($VPN_STATES_2[$state])
403                                $ret['phase2']=$VPN_STATES_2[$state];
404                }
405                return($ret);
406        }
407        //read logging output of a tunnel
408        //returns: $ret[]=array($state,$line);
409        function vpn_GetLog($name)
410        {
411                global $VPN_LOG;
412                $lines=SafeExec("grep 'pluto.*\"$name\"' '$VPN_LOG'|tail -1000");
413                foreach ($lines as $line)
414                {
415                        // preg_match("/\]: \".*?\".(.*)/",$line,$matches);
416                        $ret[]=array(vpn_LogToState($line),$line);
417                }
418                return $ret;
419        }
420
421        //gets state of all tunnels
422        //ret[tunnelname][state]=$state
423        //ret[tunnelname][info][]=infolines
424        function vpn_GetStatus()
425        {
426                global $VPN_STATES_1;
427                global $VPN_STATES_2;
428                // global $VPN_PRIO;
429
430                if (Cmd("ipsec whack --status",'',$output)<0)
431                {
432                        LogError("Error reading ipsec status. Please check if ipsec-service is running");
433                        return (false);
434                }
435                else {
436                        $ret=Array();
437                        foreach ($output as $line)
438                        {
439                                if (preg_match('/\"(.*)\"/',$line,$matches))
440                                {
441                                        $name=$matches[1];
442                                        $ret[$name]['info'][]=$line;
443                                        $state=vpn_LogToState($line);
444                                        if ($state['phase1'])
445                                                $ret[$name]['phase1']=$state['phase1'];
446                                        if ($state['phase2'])
447                                                $ret[$name]['phase2']=$state['phase2'];
448
449                                }
450
451                                // //state + info
452                        //      if (preg_match('/^.*#([0-9])*:.*"(.*?)"[:0-9]* ([A-Z0-9_]+) /',$line,$matches))
453                                // {
454                                //      $nr=$matches[1];
455                                //      $name=$matches[2];
456                                //      $state=$matches[3];
457                                //      if (
458                                //              $name &&
459                                //              $state
460                                //      )
461                                //      {
462                                //              if ($VPN_STATES_1[$state])
463                                //                      $ret[$name]['phase1']=$VPN_STATES_1[$state];
464                                //              if ($VPN_STATES_2[$state])
465                                //                      $ret[$name]['phase2']=$VPN_STATES_2[$state];
466                                //
467                                //              $ret[$name]['info'][]=$line;
468                                //      }
469                                // }
470                                // //info only
471                                // elseif (preg_match('/^.*"(.*?)": *(.*)$/',$line,$matches))
472                                // {
473                                //      $name=$matches[1];
474                                //      $info=$matches[2];
475                                //      if ($name && $info)
476                                //      {
477                                //              $ret[$name]['info'][]=$info;
478                                //      }
479                                // }
480                        }
481
482                        return $ret;
483                }
484        }
485
486        /* zit nu in network.php
487        if ($_SERVER['argv'][1]=="restart")
488        {
489                vpn_Restart();
490        }
491*/
492
493
494?>
Note: See TracBrowser for help on using the repository browser.