From d4c57ce28b705866c07f05d5e3e0d0e9141e03ee Mon Sep 17 00:00:00 2001 From: allombar Date: Sun, 19 May 2024 16:34:09 +0200 Subject: [PATCH] Implement Nitro Feature for macOS --- .../nitro/os/NitroOsFunctionsFactory.java | 8 +- .../proxy/nitro/os/macos/NitroMacOS.java | 97 +++++++++++++++++++ 2 files changed, 103 insertions(+), 2 deletions(-) create mode 100644 G-Earth/src/main/java/gearth/protocol/connection/proxy/nitro/os/macos/NitroMacOS.java diff --git a/G-Earth/src/main/java/gearth/protocol/connection/proxy/nitro/os/NitroOsFunctionsFactory.java b/G-Earth/src/main/java/gearth/protocol/connection/proxy/nitro/os/NitroOsFunctionsFactory.java index 18bbf7c..3c46e20 100644 --- a/G-Earth/src/main/java/gearth/protocol/connection/proxy/nitro/os/NitroOsFunctionsFactory.java +++ b/G-Earth/src/main/java/gearth/protocol/connection/proxy/nitro/os/NitroOsFunctionsFactory.java @@ -1,6 +1,7 @@ package gearth.protocol.connection.proxy.nitro.os; import gearth.misc.OSValidator; +import gearth.protocol.connection.proxy.nitro.os.macos.NitroMacOS; import gearth.protocol.connection.proxy.nitro.os.windows.NitroWindows; import org.apache.commons.lang3.NotImplementedException; @@ -15,7 +16,10 @@ public final class NitroOsFunctionsFactory { throw new NotImplementedException("unix nitro is not implemented yet"); } - throw new NotImplementedException("macOS nitro is not implemented yet"); - } + if (OSValidator.isMac()) { + return new NitroMacOS(); + } + throw new NotImplementedException("unsupported operating system"); + } } diff --git a/G-Earth/src/main/java/gearth/protocol/connection/proxy/nitro/os/macos/NitroMacOS.java b/G-Earth/src/main/java/gearth/protocol/connection/proxy/nitro/os/macos/NitroMacOS.java new file mode 100644 index 0000000..fd094a3 --- /dev/null +++ b/G-Earth/src/main/java/gearth/protocol/connection/proxy/nitro/os/macos/NitroMacOS.java @@ -0,0 +1,97 @@ +package gearth.protocol.connection.proxy.nitro.os.macos; + +import gearth.misc.RuntimeUtil; +import gearth.protocol.connection.proxy.nitro.os.NitroOsFunctions; + +import java.io.File; +import java.io.IOException; + +public class NitroMacOS implements NitroOsFunctions { + + /** + * Semicolon separated hosts to ignore for proxying. + */ + private static final String PROXY_IGNORE = "discord.com;discordapp.com;github.com;"; + + /** + * Checks if the certificate is trusted by the local machine. + * @param certificate Absolute path to the certificate. + * @return true if trusted + */ + @Override + public boolean isRootCertificateTrusted(File certificate) { + try { + final String output = RuntimeUtil.getCommandOutput(new String[] {"sh", "-c", "security verify-cert -c \"" + certificate.getAbsolutePath() + "\""}); + + return !output.contains("CSSMERR_TP_NOT_TRUSTED"); + } catch (IOException e) { + e.printStackTrace(); + } + + return false; + } + + @Override + public boolean installRootCertificate(File certificate) { + final String certificatePath = certificate.getAbsolutePath(); + + try { + // Install the certificate + Process process = new ProcessBuilder("sh", "-c", "sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain \"" + certificatePath + "\"") + .inheritIO() + .start(); + + // Wait for the process to complete + int exitCode = process.waitFor(); + if (exitCode != 0) { + System.out.printf("security add-trusted-cert command exited with exit code %d%n", exitCode); + return false; + } + + return true; + } catch (IOException | InterruptedException e) { + e.printStackTrace(); + } + + return false; + } + + @Override + public boolean registerSystemProxy(String host, int port) { + try { + final String proxy = String.format("%s:%d", host, port); + final String[] ignoreHosts = PROXY_IGNORE.split(";"); + + // Enable proxy + Runtime.getRuntime().exec("networksetup -setwebproxy Wi-Fi " + host + " " + port); + Runtime.getRuntime().exec("networksetup -setsecurewebproxy Wi-Fi " + host + " " + port); + + // Set proxy bypass domains + for (String ignoreHost : ignoreHosts) { + Runtime.getRuntime().exec("networksetup -setproxybypassdomains Wi-Fi " + ignoreHost); + } + + return true; + } catch (IOException e) { + e.printStackTrace(); + } + + return false; + } + + @Override + public boolean unregisterSystemProxy() { + try { + // Disable proxy + Runtime.getRuntime().exec("networksetup -setwebproxystate Wi-Fi off"); + Runtime.getRuntime().exec("networksetup -setsecurewebproxystate Wi-Fi off"); + + return true; + } catch (IOException e) { + e.printStackTrace(); + } + + return false; + } + +} \ No newline at end of file