|
|
@@ -13,6 +13,8 @@ import com.wireguard.android.util.ToolsInstaller; |
|
|
|
import com.wireguard.config.Config; |
|
|
|
|
|
|
|
import java.io.File; |
|
|
|
import java.io.FileOutputStream; |
|
|
|
import java.nio.charset.StandardCharsets; |
|
|
|
import java.util.ArrayList; |
|
|
|
import java.util.Collections; |
|
|
|
import java.util.List; |
|
|
@@ -29,23 +31,45 @@ public final class WgQuickBackend implements Backend { |
|
|
|
private static final String TAG = "WireGuard/" + WgQuickBackend.class.getSimpleName(); |
|
|
|
|
|
|
|
private final Context context; |
|
|
|
private final File localTemporaryDir; |
|
|
|
private final RootShell rootShell; |
|
|
|
private final ToolsInstaller toolsInstaller; |
|
|
|
|
|
|
|
public WgQuickBackend(final Context context, final RootShell rootShell, |
|
|
|
final ToolsInstaller toolsInstaller) { |
|
|
|
this.context = context; |
|
|
|
localTemporaryDir = new File(context.getCacheDir(), "tmp"); |
|
|
|
this.rootShell = rootShell; |
|
|
|
this.toolsInstaller = toolsInstaller; |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
public Config applyConfig(final Tunnel tunnel, final Config config) { |
|
|
|
if (tunnel.getState() == State.UP) |
|
|
|
throw new UnsupportedOperationException("Not implemented"); |
|
|
|
public Config applyConfig(final Tunnel tunnel, final Config config) throws Exception { |
|
|
|
if (tunnel.getState() == State.UP) { |
|
|
|
// Restart the tunnel to apply the new config. |
|
|
|
setState(tunnel, State.DOWN); |
|
|
|
try { |
|
|
|
bringUpTunnel(tunnel, config); |
|
|
|
} catch (final Exception e) { |
|
|
|
// The new configuration didn't work, so try to go back to the old one. |
|
|
|
bringUpTunnel(tunnel, tunnel.getConfig()); |
|
|
|
throw e; |
|
|
|
} |
|
|
|
} |
|
|
|
return config; |
|
|
|
} |
|
|
|
|
|
|
|
private int bringUpTunnel(final Tunnel tunnel, final Config config) throws Exception { |
|
|
|
final File tempFile = new File(localTemporaryDir, tunnel.getName() + ".conf"); |
|
|
|
try (FileOutputStream stream = new FileOutputStream(tempFile, false)) { |
|
|
|
stream.write(config.toString().getBytes(StandardCharsets.UTF_8)); |
|
|
|
} |
|
|
|
final int result = rootShell.run(null, "wg-quick up '" + tempFile.getAbsolutePath() + '\''); |
|
|
|
if (!tempFile.delete()) |
|
|
|
Log.w(TAG, "Couldn't delete temporary file after bringing up " + tunnel.getName()); |
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
public Set<String> enumerate() { |
|
|
|
final List<String> output = new ArrayList<>(); |
|
|
@@ -85,11 +109,9 @@ public final class WgQuickBackend implements Backend { |
|
|
|
if (state == State.UP) { |
|
|
|
if (!new File("/sys/module/wireguard").exists()) |
|
|
|
throw new ErrnoException("WireGuard module not loaded", OsConstants.ENODEV); |
|
|
|
// FIXME: Assumes file layout from FileConfigStore. Use a temporary file. |
|
|
|
final File file = new File(context.getFilesDir(), tunnel.getName() + ".conf"); |
|
|
|
result = rootShell.run(null, String.format("wg-quick up '%s'", file.getAbsolutePath())); |
|
|
|
result = bringUpTunnel(tunnel, tunnel.getConfig()); |
|
|
|
} else { |
|
|
|
result = rootShell.run(null, String.format("wg-quick down '%s'", tunnel.getName())); |
|
|
|
result = rootShell.run(null, "wg-quick down '" + tunnel.getName() + '\''); |
|
|
|
} |
|
|
|
if (result != 0) |
|
|
|
throw new Exception("wg-quick failed"); |
|
|
|