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

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

openswan fix

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