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

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

initial commit, transferred from cleaned syn3 svn tree

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