. */ require_once("../common.php"); require_once("../network/network.php"); require_once("../proc.php"); IncludeLang(__FILE__); $VPN_IPSEC_DIR="/etc/ipsec.d"; $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 vpn_Stop(); SvcUp("ipsec"); } 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) && //varieert nu? (substr($key,0,2)=='0s') && (!preg_match("/[^A-Za-z0-9+\/=]/",$key)) ); } function vpn_SameKey($key1,$key2) { $key1=vpn_ReadableToPub($key1); $key2=vpn_ReadableToPub($key2); return ($key1==$key2); } function vpn_ReadPubKey() { return(safeExec("syn3-ipsecpubkey")[0]); } //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-0-9]*([a-z0-9]*)=(.*)$/",$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_1=array( //ike v1 'STATE_MAIN_I1'=>"Connecting...", 'STATE_MAIN_R1'=>"Connecting...", 'STATE_MAIN_I2'=>"Connecting...", 'STATE_MAIN_I3'=>"Checking keys...", 'STATE_MAIN_R2'=>"Checking keys...", 'STATE_MAIN_I4'=>"OK", 'STATE_MAIN_R3'=>"OK", //ike v2 'STATE_PARENT_I1'=>"Negotiating...", 'STATE_PARENT_I2'=>"Negotiating...", 'STATE_PARENT_I3'=>"OK", 'STATE_PARENT_R2'=>"OK", ); $VPN_STATES_2=array( //ike v1 'STATE_QUICK_I1'=>"Negotiating tunnel...", 'STATE_QUICK_R1'=>"Negotiating tunnel...", 'STATE_QUICK_I2'=>"OK", 'STATE_QUICK_R2'=>"OK", //ike v2 'STATE_V2_IPSEC_I'=>"OK", 'STATE_V2_IPSEC_R'=>"OK", ); // // // $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, // ); //determines phase1 and phase2 state from logline function vpn_LogToState($logline) { global $VPN_STATES_1; global $VPN_STATES_2; $ret=[]; if (preg_match("/(STATE_[0-9_A-Z]*)/",$logline,$matches)) { $state=$matches[1]; if ($VPN_STATES_1[$state]) $ret['phase1']=$VPN_STATES_1[$state]; if ($VPN_STATES_2[$state]) $ret['phase2']=$VPN_STATES_2[$state]; } return($ret); } //read logging output of a tunnel //returns: $ret[]=array($state,$line); function vpn_GetLog($name) { global $VPN_LOG; $lines=SafeExec("grep 'pluto.*\"$name\"' '$VPN_LOG'|tail -1000"); foreach ($lines as $line) { // preg_match("/\]: \".*?\".(.*)/",$line,$matches); $ret[]=array(vpn_LogToState($line),$line); } return $ret; } //gets state of all tunnels //ret[tunnelname][state]=$state //ret[tunnelname][info][]=infolines function vpn_GetStatus() { global $VPN_STATES_1; global $VPN_STATES_2; // 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('/\"(.*)\"/',$line,$matches)) { $name=$matches[1]; $ret[$name]['info'][]=$line; $state=vpn_LogToState($line); if ($state['phase1'] && !$ret[$name]['phase1_newest']) { $ret[$name]['phase1']=$state['phase1']; if (preg_match('/ newest /', $line)) $ret[$name]['phase1_newest']=true; } if ($state['phase2'] && !$ret[$name]['phase2_newest']) { $ret[$name]['phase2']=$state['phase2']; if (preg_match('/ newest /', $line)) $ret[$name]['phase2_newest']=true; } } // //state + info // if (preg_match('/^.*#([0-9])*:.*"(.*?)"[:0-9]* ([A-Z0-9_]+) /',$line,$matches)) // { // $nr=$matches[1]; // $name=$matches[2]; // $state=$matches[3]; // if ( // $name && // $state // ) // { // if ($VPN_STATES_1[$state]) // $ret[$name]['phase1']=$VPN_STATES_1[$state]; // if ($VPN_STATES_2[$state]) // $ret[$name]['phase2']=$VPN_STATES_2[$state]; // // $ret[$name]['info'][]=$line; // } // } // //info only // 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(); } */ ?>