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; } }