diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl index 20d3ec31500dc..2cac9f625bbb3 100644 --- a/core/java/android/os/INetworkManagementService.aidl +++ b/core/java/android/os/INetworkManagementService.aidl @@ -362,4 +362,11 @@ interface INetworkManagementService * Flush the DNS cache associated with the specified interface. */ void flushInterfaceDnsCache(String iface); + + void setFirewallEnabled(boolean enabled); + boolean isFirewallEnabled(); + void setInterfaceFirewallRule(String iface, boolean allow); + void setEgressSourceFirewallRule(String addr, boolean allow); + void setEgressDestFirewallRule(String addr, int port, boolean allow); + void setUidFirewallRule(int uid, boolean allow); } diff --git a/core/java/com/android/internal/util/Preconditions.java b/core/java/com/android/internal/util/Preconditions.java index a53a9c0c6eb69..a327adc7a431e 100644 --- a/core/java/com/android/internal/util/Preconditions.java +++ b/core/java/com/android/internal/util/Preconditions.java @@ -54,4 +54,16 @@ public class Preconditions { return reference; } + /** + * Ensures the truth of an expression involving the state of the calling + * instance, but not involving any parameters to the calling method. + * + * @param expression a boolean expression + * @throws IllegalStateException if {@code expression} is false + */ + public static void checkState(boolean expression) { + if (!expression) { + throw new IllegalStateException(); + } + } } diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java index 39e518671d9fd..722e1e03d1566 100644 --- a/services/java/com/android/server/NetworkManagementService.java +++ b/services/java/com/android/server/NetworkManagementService.java @@ -35,6 +35,7 @@ import static com.android.server.NetworkManagementService.NetdResponseCode.Tethe import static com.android.server.NetworkManagementService.NetdResponseCode.TtyListResult; import static com.android.server.NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED; +import android.bluetooth.BluetoothTetheringDataTracker; import android.content.Context; import android.net.INetworkManagementEventObserver; import android.net.InterfaceConfiguration; @@ -55,6 +56,7 @@ import android.util.Slog; import android.util.SparseBooleanArray; import com.android.internal.net.NetworkStatsFactory; +import com.android.internal.util.Preconditions; import com.android.server.NativeDaemonConnector.Command; import com.google.android.collect.Maps; @@ -78,7 +80,6 @@ import java.util.Map; import java.util.NoSuchElementException; import java.util.StringTokenizer; import java.util.concurrent.CountDownLatch; -import android.bluetooth.BluetoothTetheringDataTracker; /** * @hide @@ -92,6 +93,9 @@ public class NetworkManagementService extends INetworkManagementService.Stub private static final String ADD = "add"; private static final String REMOVE = "remove"; + private static final String ALLOW = "allow"; + private static final String DENY = "deny"; + private static final String DEFAULT = "default"; private static final String SECONDARY = "secondary"; @@ -169,6 +173,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub private HashMap mActiveIdleTimers = Maps.newHashMap(); private volatile boolean mBandwidthControlEnabled; + private volatile boolean mFirewallEnabled; /** * Constructs a new NetworkManagementService instance @@ -363,6 +368,9 @@ public class NetworkManagementService extends INetworkManagementService.Stub } } } + + // TODO: Push any existing firewall state + setFirewallEnabled(mFirewallEnabled); } // @@ -1425,7 +1433,72 @@ public class NetworkManagementService extends INetworkManagementService.Stub } } - /** {@inheritDoc} */ + @Override + public void setFirewallEnabled(boolean enabled) { + mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); + try { + mConnector.execute("firewall", enabled ? "enable" : "disable"); + mFirewallEnabled = enabled; + } catch (NativeDaemonConnectorException e) { + throw e.rethrowAsParcelableException(); + } + } + + @Override + public boolean isFirewallEnabled() { + mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); + return mFirewallEnabled; + } + + @Override + public void setInterfaceFirewallRule(String iface, boolean allow) { + mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); + Preconditions.checkState(mFirewallEnabled); + final String rule = allow ? ALLOW : DENY; + try { + mConnector.execute("firewall", "set_interface_rule", iface, rule); + } catch (NativeDaemonConnectorException e) { + throw e.rethrowAsParcelableException(); + } + } + + @Override + public void setEgressSourceFirewallRule(String addr, boolean allow) { + mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); + Preconditions.checkState(mFirewallEnabled); + final String rule = allow ? ALLOW : DENY; + try { + mConnector.execute("firewall", "set_egress_source_rule", addr, rule); + } catch (NativeDaemonConnectorException e) { + throw e.rethrowAsParcelableException(); + } + } + + @Override + public void setEgressDestFirewallRule(String addr, int port, boolean allow) { + mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); + Preconditions.checkState(mFirewallEnabled); + final String rule = allow ? ALLOW : DENY; + try { + mConnector.execute("firewall", "set_egress_dest_rule", addr, port, rule); + } catch (NativeDaemonConnectorException e) { + throw e.rethrowAsParcelableException(); + } + } + + @Override + public void setUidFirewallRule(int uid, boolean allow) { + mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); + Preconditions.checkState(mFirewallEnabled); + final String rule = allow ? ALLOW : DENY; + try { + mConnector.execute("firewall", "set_uid_rule", uid, rule); + } catch (NativeDaemonConnectorException e) { + throw e.rethrowAsParcelableException(); + } + } + + @Override public void monitor() { if (mConnector != null) { mConnector.monitor(); @@ -1456,5 +1529,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub } pw.println("]"); } + + pw.print("Firewall enabled: "); pw.println(mFirewallEnabled); } }