. */ require_once("../common.php"); require_once("../network/network.php"); require_once("../proc.php"); IncludeLang(__FILE__); $VPN_IPSEC_DIR="/etc/ipsec.d"; $VPN_PUB="$VPN_IPSEC_DIR/ipsec.pub"; $VPN_TUNNEL_DIR="$VPN_IPSEC_DIR/tunnels"; $VPN_LOG="/var/log/secure"; $VPN_STARTERRORS="$VPN_IPSEC_DIR/starterrors"; function vpn_Stop() { if (SvcIsUp("ipsec")) { SvcDown("ipsec"); } } //RET: false als het werk, anders error text. function vpn_Restart() { //only works on internet server if (!ModuleMatch("I")) return false; //return ok-code // global $VPN_STARTERRORS; vpn_Stop(); // LogInfo(_LogVPNStarting()); SvcUp("ipsec"); // FileWriteRaw("/etc/sysconfig/pluto_updown", "DEFAULTSOURCE=".GetFirstLanIp()."\n"); // Cmd("pgrphack closefd /usr/sbin/ipsec setup start |grep 'FATAL:' 1>&2",'',$out,$err); // if ($err) // { // FileWrite($VPN_STARTERRORS,$err); // LogError(_LogVPNstartErrors(implode(" ",$err))); // return ($err); // } // else // { // FileWrite($VPN_STARTERRORS,''); // sleep(2); //wacht zodat VPN subsysteem up is // //kijk of er tunnels up moeten // $tunnels=vpn_ReadTunnels(); // foreach ($tunnels as $name=>$conf) // { // //hij moet up zijn, EN hij is reeds getest // if ((!vpn_TunnelIsDownOnBoot($name)) && vpn_TunnelIsTested($name)) // vpn_TunnelUp($name); // } // return false; // } } function vpn_StartErrors() { global $VPN_STARTERRORS; if (is_file($VPN_STARTERRORS)) { $raw=FileReadRaw($VPN_STARTERRORS); } return ($raw); } /*function vpn_Failed() { global $VPN_IPSEC_DIR; return (is_file("$VPN_IPSEC_DIR/failed")); } function vpn_Tested() { global $VPN_IPSEC_DIR; return (is_file("$VPN_IPSEC_DIR/tested")); } */ //force vpn monitoring check. ( this is also done every minute with a crontab) function vpn_MonUpdate($name) { Progress("Checking tunnel status $name..."); SafeExec("syn3-ipseccheck '$name'"); Progress(""); } function vpn_TunnelUp($name) { $err=Cmd(" ( ipsec auto --down '$name' 2>/dev/null; ipsec auto --rereadsecrets; ipsec auto --replace '$name' && ipsec auto --asynchronous --up '$name' ) 2>&1 ",'',$out,$errout); if ($err!=0) { $out[]="Exit code $err"; LogError(_LogTunnelUpError($name,implode(" ",$out))); return false; } else { LogInfo(_LogTunnelUp($name)); return true; } } function vpn_TunnelDown($name) { vpn_TunnelSetDownOnBoot($name,1); $err=Cmd("ipsec auto --delete '$name' 2>&1",'',$out,$errout); vpn_MonUpdate($name); if ($err!=0) { LogError(_TunnelDownError($name,implode(" ",$out))); return false; } else { LogInfo(_LogTunnelDown($name)); return true; } } function vpn_TunnelIsTested($name) { global $VPN_TUNNEL_DIR; return (!is_file("$VPN_TUNNEL_DIR/$name.untested")); } function vpn_TunnelSetTested($name,$tested) { global $VPN_TUNNEL_DIR; if ($tested) FileDelete("$VPN_TUNNEL_DIR/$name.untested"); else FileWriteRaw("$VPN_TUNNEL_DIR/$name.untested",""); } function vpn_TunnelIsDownOnBoot($name) { $tunnel=vpn_ReadTunnel($name); return ($tunnel["auto"]=="up"); } function vpn_TunnelSetDownOnBoot($name,$down) { $tunnel=vpn_ReadTunnel($name); if ($down) $tunnel["auto"]="ignore"; else $tunnel["auto"]="up"; vpn_WriteTunnel($name, $tunnel, false); } //gooi tunnel up, maar run backup script voor het geval er netwerk //conflict is. in dit geval gaat tunnel weer down function vpn_TunnelTestStart($name) { //test loopt nog? if ($_SESSION[testtunnel] && posix_kill($_SESSION[testtunnel][pid],0)) Error(_TestAlreadyRunning()); //start het backup script en onthoudt PID $_SESSION[testtunnel][pid]=BgExec("exec testtunnel.sh '$name'"); $_SESSION[testtunnel][name]=$name; vpn_TunnelSetTested($name,1); //het backup script zet hem weer op 0 als het misgaat vpn_TunnelUp($name); //niet controleren op errors return true; } //Controleer of er nog een test loopt, en of deze geslaagd is. //Roep deze functie aan NA het refreshen van de pagina, zodat je weet //dat de netwerk settings niet verstoord zijn. function vpn_TunnelTestEnd() { //is there a test running? if ($_SESSION[testtunnel]) { //kill het backup script BOEM posix_kill($_SESSION[testtunnel][pid],9); $name=$_SESSION[testtunnel][name]; //test is klaar nu unset($_SESSION[testtunnel]); //kijk of test gelukt of mislukt is en wijzig config if (!vpn_TunnelIsTested($name)) { LogError(_LogTunnelTestFailed($name)); } else { vpn_TunnelSetDownOnBoot($name, 0); vpn_MonUpdate($name); } } } function vpn_ReadSecret($name) { global $VPN_TUNNEL_DIR; $line=FileReadRaw("$VPN_TUNNEL_DIR/$name.key"); preg_match('/"(.*)"/',$line,$matches); return ($matches[1]); } function vpn_WriteSecret($name,$secret) { global $VPN_TUNNEL_DIR; $tunnel=vpn_ReadTunnel($name); $line="$tunnel[leftid] $tunnel[right]: PSK \"$secret\"\n"; FileWriteRaw("$VPN_TUNNEL_DIR/$name.key",$line); } function vpn_ValidName($name) { return ( (!preg_match("/[^a-z0-9-]/",$name)) && (strlen($name)<25) && (strlen($name)>=3) ); } function vpn_ValidSecret($secret) { return ( (strlen($secret)>=8) ); } function vpn_ValidPubKey($key) { $key=vpn_ReadableToPub($key); return ( (strlen($key)==370) && (substr($key,0,2)=='0s') && (!preg_match("/[^A-Za-z0-9+\/]/",substr($key,2))) ); } function vpn_SameKey($key1,$key2) { $key1=vpn_ReadableToPub($key1); $key2=vpn_ReadableToPub($key2); return ($key1==$key2); } function vpn_ReadPubKey() { global $VPN_PUB; $raw=FileReadMatches($VPN_PUB,"/#pubkey=/"); preg_match("/.*pubkey=(.*)/",$raw[0],$matches); return ($matches[1]); } //make key readable (insert new-lines etc) function vpn_PubToReadable($pubkey) { return(preg_replace("/(.{50})/","\$0\n",$pubkey)); } //filter all the crap from a readable key function vpn_ReadableToPub($pubkey) { return(preg_replace("/[^A-Za-z0-9+\/=]/","",$pubkey)); } //returns corresponding tunnel filename function vpn_GetTunnelFile($name) { global $VPN_TUNNEL_DIR; return ("$VPN_TUNNEL_DIR/$name.conf"); } function vpn_ReadTunnel($name) { $raw=FileRead(vpn_GetTunnelFile($name)); foreach ($raw as $line) { if (preg_match("/^[^a-z]*([a-z]*)=(.*)$/",$line,$matches)) $ret[$matches[1]]=$matches[2]; } return ($ret); } function vpn_ReadTunnels() { global $VPN_TUNNEL_DIR; $dh=opendir($VPN_TUNNEL_DIR); while ($file=readdir($dh)) { if (preg_match("/^(.*).conf$/",$file,$matches)) { if ($matches[1] != "dummy") $ret[$matches[1]]=vpn_ReadTunnel($matches[1]); } } return ($ret); } function vpn_WriteTunnel($name,$data, $needs_testing=true) { global $VPN_IPSEC_DIR; global $VPN_TUNNEL_DIR; $raw[]="conn $name"; foreach ($data as $varname=>$varvalue) { $raw[]="\t$varname=$varvalue"; } //mark configuration as untested if ($needs_testing) FileWriteRaw("$VPN_TUNNEL_DIR/$name.untested"); FileWrite(vpn_GetTunnelFile($name),$raw); LogInfo(_LogVPNSettingsChanged($name)); } function vpn_DelTunnel($name) { global $VPN_TUNNEL_DIR; vpn_TunnelDown($name); FileDelete("$VPN_TUNNEL_DIR/$name.conf"); FileDelete("$VPN_TUNNEL_DIR/$name.mon"); FileDelete("$VPN_TUNNEL_DIR/$name.key"); FileDelete("$VPN_TUNNEL_DIR/$name.down"); FileDelete("$VPN_TUNNEL_DIR/$name.untested"); LogInfo(_LogVPNTunnelDeleted($name)); } $VPN_STATES=array( 'Main'=>"Connecting...", 'STATE_MAIN_I1'=>"Connecting...", 'STATE_MAIN_R1'=>"Connection accepted...", 'STATE_MAIN_I2'=>"Connection complete...", 'STATE_MAIN_I3'=>"Checking keys...", 'STATE_MAIN_R2'=>"Checking keys...", 'STATE_MAIN_I4'=>"Keys accepted...", 'STATE_MAIN_R3'=>"Waiting for tunnel request...", 'Quick'=>"Requesting tunnel...", 'STATE_QUICK_I1'=>"Requesting tunnel...", 'STATE_QUICK_R1'=>"Tunnel request received...", 'STATE_QUICK_I2'=>"Tunnel established", 'STATE_QUICK_R2'=>"Tunnel established", ); $VPN_PRIO=array( 'Main'=>0, 'STATE_MAIN_I1'=>1, 'STATE_MAIN_R1'=>2, 'STATE_MAIN_I2'=>3, 'STATE_MAIN_I3'=>4, 'STATE_MAIN_R2'=>5, 'STATE_MAIN_I4'=>6, 'STATE_MAIN_R3'=>7, 'Quick'=>8, 'STATE_QUICK_I1'=>9, 'STATE_QUICK_R1'=>10, 'STATE_QUICK_I2'=>11, 'STATE_QUICK_R2'=>12, ); //tries to determine state from a logline. //returns false on no state found function vpn_LogToState($logline) { global $VPN_STATES; if (preg_match("/to state (.*)$/",$logline,$matches)) { if (isset($VPN_STATES[$matches[1]])) return ($matches[1]); } elseif (preg_match("/initiating (.*) Mode/",$logline,$matches)) { if (isset($VPN_STATES[$matches[1]])) return ($matches[1]); } else { return false; } } //read logging output of a tunnel //returns: $ret[]=array($state,$line); function vpn_GetLog($name) { global $VPN_LOG; $lines=SafeExec("grep '\]: \"$name\"' '$VPN_LOG'|tail -1000"); foreach ($lines as $line) { preg_match("/\]: \".*?\".(.*)/",$line,$matches); $ret[]=array(vpn_LogToState($matches[1]),$matches[1]); } return $ret; } //gets state of all tunnels //ret[tunnelname][state]=$state //ret[tunnelname][info][]=infolines function vpn_GetStatus() { global $VPN_STATES; global $VPN_PRIO; if (Cmd("ipsec whack --status",'',$output)!=0) { LogError("Error reading ipsec status. Please check if ipsec-service is running"); return (false); } else { $ret=Array(); foreach ($output as $line) { if (preg_match('/^.*#([0-9])*:.*"(.*?)"[:0-9]* ([A-Z0-9_]+) /',$line,$matches)) { $nr=$matches[1]; $name=$matches[2]; $state=$matches[3]; if ( $name && $state && $VPN_PRIO[$state]>=$VPN_PRIO[$ret[$name]['state']] ) { $ret[$name]['state']=$state; $ret[$name]['info'][]=$line; } } elseif (preg_match('/^.*"(.*?)": *(.*)$/',$line,$matches)) { $name=$matches[1]; $info=$matches[2]; if ($name && $info) { $ret[$name]['info'][]=$info; } } } return $ret; } } /* zit nu in network.php if ($_SERVER['argv'][1]=="restart") { vpn_Restart(); } */ ?>