package art.servers.controller;
|
|
import art.servers.Shared;
|
import art.servers.configuration.ConfigurationNtpHttp;
|
import com.sun.jna.platform.win32.Advapi32;
|
import com.sun.jna.platform.win32.Kernel32;
|
import com.sun.jna.platform.win32.WinBase;
|
import com.sun.jna.platform.win32.WinDef;
|
import com.sun.jna.platform.win32.WinNT;
|
import com.sun.jna.ptr.IntByReference;
|
import java.io.BufferedReader;
|
import java.io.ByteArrayOutputStream;
|
import java.io.InputStreamReader;
|
import java.net.HttpURLConnection;
|
import java.net.InetSocketAddress;
|
import java.net.Proxy;
|
import java.net.URL;
|
import java.text.SimpleDateFormat;
|
import java.util.Calendar;
|
import java.util.Locale;
|
import java.util.TimeZone;
|
import java.util.Timer;
|
import java.util.TimerTask;
|
|
public class ControllerNtpHttp extends Controller
|
{
|
private ConfigurationNtpHttp configuration = null;
|
private String name = null;
|
|
public ControllerNtpHttp(ConfigurationNtpHttp configuration)
|
{
|
this.name = Shared.getMessage("NTP HTTP");
|
this.configuration = configuration;
|
|
Timer timer = new Timer();
|
|
timer.schedule(new TimerTask()
|
{
|
public void run()
|
{
|
update();
|
}
|
}, 0, configuration.polling * 1000);
|
}
|
|
|
|
private void update()
|
{
|
try
|
{
|
long t0 = System.currentTimeMillis();
|
|
String date = getDate(configuration.URL, configuration.timeout, configuration.timeout);
|
SimpleDateFormat dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
|
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
|
|
long t1 = System.currentTimeMillis();
|
|
long delay = t1 - t0;
|
long timestamp = dateFormat.parse(date).getTime() + delay;
|
long difference = Math.abs(System.currentTimeMillis() - timestamp);
|
|
if (difference > configuration.maximumAllowedDelay)
|
{
|
SetLocalTime(timestamp, null);
|
}
|
|
Shared.println(name, Shared.getMessage("Time difference") + " = " + difference + " " + Shared.getMessage("ms"));
|
|
}
|
catch (Exception exception)
|
{
|
Shared.printerr(name, exception.getMessage());
|
}
|
}
|
|
|
|
private String getDate(String url, int connectionTimeout, int readTimeout) throws Exception
|
{
|
HttpURLConnection connection = null;
|
ByteArrayOutputStream outputStreamBody = null;
|
|
try
|
{
|
// Connect to the web server endpoint
|
|
URL httpurl = new URL(url);
|
|
if ((configuration.proxyAddress != null) && (configuration.proxyPort > 0))
|
{
|
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(configuration.proxyAddress, configuration.proxyPort));
|
connection = (HttpURLConnection)httpurl.openConnection(proxy);
|
}
|
else
|
{
|
connection = (HttpURLConnection)httpurl.openConnection();
|
}
|
|
connection.setConnectTimeout(connectionTimeout);
|
connection.setReadTimeout(readTimeout);
|
|
// Write header
|
|
connection.setRequestMethod("GET");
|
connection.addRequestProperty("User-Agent", "ALUVISA");
|
connection.addRequestProperty("Content-Type", "application/octet-stream");
|
connection.setDoOutput(true);
|
|
// Read answer
|
|
int responseCode = connection.getResponseCode();
|
|
if (responseCode == 200)
|
{
|
return connection.getHeaderField("Date");
|
}
|
else
|
{
|
throw new Exception("Response code, " + responseCode);
|
}
|
|
}
|
catch (Exception exception)
|
{
|
throw exception;
|
}
|
finally
|
{
|
|
// Disconnect
|
|
try { outputStreamBody.close(); } catch (Exception e) {};
|
try { connection.disconnect(); } catch (Exception e) {};
|
}
|
|
|
}
|
|
|
|
|
private static boolean SetLocalTime(long timestamp, String password) throws Exception
|
{
|
String os = System.getProperty("os.name").toLowerCase();
|
|
if (os.contains("win"))
|
{
|
// Operating system is based on Windows
|
|
WinNT.TOKEN_PRIVILEGES tp = new WinNT.TOKEN_PRIVILEGES(1);
|
WinNT.TOKEN_PRIVILEGES oldtp = new WinNT.TOKEN_PRIVILEGES(1);
|
WinNT.LUID luid = new WinNT.LUID();
|
WinNT.HANDLEByReference hTokenRef = new WinNT.HANDLEByReference();
|
if (!Advapi32.INSTANCE.OpenProcessToken(Kernel32.INSTANCE.GetCurrentProcess(), WinNT.TOKEN_ADJUST_PRIVILEGES | WinNT.TOKEN_QUERY, hTokenRef))
|
{
|
throw new Exception("HTTP clock. Error. OpenProcessToken");
|
}
|
|
WinNT.HANDLE hToken = hTokenRef.getValue();
|
if (!Advapi32.INSTANCE.LookupPrivilegeValue(null, WinNT.SE_SYSTEMTIME_NAME, luid))
|
{
|
Kernel32.INSTANCE.CloseHandle(hToken);
|
throw new Exception("HTTP clock. Error. LookupPrivilegeValue");
|
}
|
|
tp.PrivilegeCount = new WinDef.DWORD(1);
|
tp.Privileges = new WinNT.LUID_AND_ATTRIBUTES[1];
|
tp.Privileges[0] = new WinNT.LUID_AND_ATTRIBUTES(luid, new WinDef.DWORD(WinNT.SE_PRIVILEGE_ENABLED));
|
IntByReference retSize = new IntByReference(0);
|
if (!Advapi32.INSTANCE.AdjustTokenPrivileges(hToken, false, tp, tp.size(), oldtp, retSize))
|
{
|
Kernel32.INSTANCE.CloseHandle(hToken);
|
throw new Exception("HTTP clock. Error. AdjustTokenPrivileges");
|
}
|
|
Calendar calendar = Calendar.getInstance();
|
calendar.setTimeInMillis(timestamp);
|
WinBase.SYSTEMTIME st = new WinBase.SYSTEMTIME();
|
st.wYear = (short)calendar.get(Calendar.YEAR);
|
st.wMonth = (short)(calendar.get(Calendar.MONTH) + 1);
|
st.wDay = (short)calendar.get(Calendar.DAY_OF_MONTH);
|
st.wHour = (short)calendar.get(Calendar.HOUR_OF_DAY);
|
st.wMinute = (short)calendar.get(Calendar.MINUTE);
|
st.wSecond = (short)calendar.get(Calendar.SECOND);
|
st.wMilliseconds = (short)calendar.get(Calendar.MILLISECOND);
|
st.wDayOfWeek = (short)calendar.get(Calendar.DAY_OF_WEEK);
|
|
boolean result = Kernel32.INSTANCE.SetLocalTime(st);
|
int error = Kernel32.INSTANCE.GetLastError();
|
Kernel32.INSTANCE.CloseHandle(hToken);
|
|
return result;
|
}
|
else if (os.contains("osx"))
|
{
|
// Operating system is Apple OSX based
|
}
|
else if (os.contains("nix") || os.contains("aix") || os.contains("nux"))
|
{
|
// Operating system is based on Linux/Unix/*AIX
|
|
SimpleDateFormat formato1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
|
|
String[] command = {"/bin/bash", "-c", "echo " + password + " | sudo -S date --set='" + formato1.format(timestamp) + "'"};
|
//String[] cmd = {"echo " + password + " | sudo -S date --set='" + formato1.format(timestamp) + "'"};
|
Process process = Runtime.getRuntime().exec(command);
|
int exitValue = process.waitFor();
|
if (exitValue != 0)
|
{
|
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
|
String result = new String();
|
String line = null;
|
while ((line = reader.readLine()) != null) result = result + line + "\r\n";
|
throw new Exception(result);
|
}
|
else
|
{
|
return true;
|
}
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
}
|