1d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey/* 2d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey * Copyright (C) 2012 The Android Open Source Project 3d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey * 4d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License"); 5d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey * you may not use this file except in compliance with the License. 6d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey * You may obtain a copy of the License at 7d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey * 8d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey * http://www.apache.org/licenses/LICENSE-2.0 9d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey * 10d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey * Unless required by applicable law or agreed to in writing, software 11d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS, 12d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey * See the License for the specific language governing permissions and 14d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey * limitations under the License. 15d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey */ 16d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey 17d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey#include <errno.h> 18d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey#include <stdio.h> 19d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey#include <stdlib.h> 20d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey#include <string.h> 21d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey 22d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey#define LOG_TAG "FirewallController" 23d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey#define LOG_NDEBUG 0 24d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey 25d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey#include <cutils/log.h> 26d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey 27d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey#include "NetdConstants.h" 28d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey#include "FirewallController.h" 29d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey 30d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkeyconst char* FirewallController::LOCAL_INPUT = "fw_INPUT"; 31d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkeyconst char* FirewallController::LOCAL_OUTPUT = "fw_OUTPUT"; 32d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkeyconst char* FirewallController::LOCAL_FORWARD = "fw_FORWARD"; 33d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey 34d8c64026aaae5a9987151b719bd840ec7d68747aJeff SharkeyFirewallController::FirewallController(void) { 35d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey} 36d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey 37d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkeyint FirewallController::setupIptablesHooks(void) { 38d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey return 0; 39d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey} 40d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey 41d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkeyint FirewallController::enableFirewall(void) { 42d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey int res = 0; 43d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey 44d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey // flush any existing rules 45d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey disableFirewall(); 46d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey 47d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey // create default rule to drop all traffic 48d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey res |= execIptables(V4V6, "-A", LOCAL_INPUT, "-j", "DROP", NULL); 49d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey res |= execIptables(V4V6, "-A", LOCAL_OUTPUT, "-j", "REJECT", NULL); 50d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey res |= execIptables(V4V6, "-A", LOCAL_FORWARD, "-j", "REJECT", NULL); 51d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey 52d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey return res; 53d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey} 54d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey 55d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkeyint FirewallController::disableFirewall(void) { 56d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey int res = 0; 57d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey 58d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey // flush any existing rules 59d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey res |= execIptables(V4V6, "-F", LOCAL_INPUT, NULL); 60d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey res |= execIptables(V4V6, "-F", LOCAL_OUTPUT, NULL); 61d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey res |= execIptables(V4V6, "-F", LOCAL_FORWARD, NULL); 62d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey 63d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey return res; 64d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey} 65d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey 66d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkeyint FirewallController::isFirewallEnabled(void) { 67d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey // TODO: verify that rules are still in place near top 68d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey return -1; 69d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey} 70d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey 71d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkeyint FirewallController::setInterfaceRule(const char* iface, FirewallRule rule) { 72d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey const char* op; 73d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey if (rule == ALLOW) { 74d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey op = "-I"; 75d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey } else { 76d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey op = "-D"; 77d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey } 78d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey 79d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey int res = 0; 80d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey res |= execIptables(V4V6, op, LOCAL_INPUT, "-i", iface, "-j", "RETURN", NULL); 81d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey res |= execIptables(V4V6, op, LOCAL_OUTPUT, "-o", iface, "-j", "RETURN", NULL); 82d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey return res; 83d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey} 84d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey 85d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkeyint FirewallController::setEgressSourceRule(const char* addr, FirewallRule rule) { 86d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey IptablesTarget target = V4; 87d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey if (strchr(addr, ':')) { 88d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey target = V6; 89d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey } 90d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey 91d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey const char* op; 92d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey if (rule == ALLOW) { 93d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey op = "-I"; 94d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey } else { 95d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey op = "-D"; 96d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey } 97d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey 98d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey int res = 0; 99d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey res |= execIptables(target, op, LOCAL_INPUT, "-d", addr, "-j", "RETURN", NULL); 100d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey res |= execIptables(target, op, LOCAL_OUTPUT, "-s", addr, "-j", "RETURN", NULL); 101d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey return res; 102d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey} 103d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey 104d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkeyint FirewallController::setEgressDestRule(const char* addr, int protocol, int port, 105d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey FirewallRule rule) { 106d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey IptablesTarget target = V4; 107d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey if (strchr(addr, ':')) { 108d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey target = V6; 109d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey } 110d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey 111d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey char protocolStr[16]; 112d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey sprintf(protocolStr, "%d", protocol); 113d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey 114d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey char portStr[16]; 115d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey sprintf(portStr, "%d", port); 116d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey 117d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey const char* op; 118d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey if (rule == ALLOW) { 119d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey op = "-I"; 120d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey } else { 121d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey op = "-D"; 122d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey } 123d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey 124d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey int res = 0; 125d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey res |= execIptables(target, op, LOCAL_INPUT, "-s", addr, "-p", protocolStr, 126d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey "--sport", portStr, "-j", "RETURN", NULL); 127d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey res |= execIptables(target, op, LOCAL_OUTPUT, "-d", addr, "-p", protocolStr, 128d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey "--dport", portStr, "-j", "RETURN", NULL); 129d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey return res; 130d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey} 131d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey 132d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkeyint FirewallController::setUidRule(int uid, FirewallRule rule) { 133d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey char uidStr[16]; 134d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey sprintf(uidStr, "%d", uid); 135d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey 136d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey const char* op; 137d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey if (rule == ALLOW) { 138d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey op = "-I"; 139d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey } else { 140d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey op = "-D"; 141d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey } 142d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey 143d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey int res = 0; 144d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey res |= execIptables(V4V6, op, LOCAL_INPUT, "-m", "owner", "--uid-owner", uidStr, 145d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey "-j", "RETURN", NULL); 146d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey res |= execIptables(V4V6, op, LOCAL_OUTPUT, "-m", "owner", "--uid-owner", uidStr, 147d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey "-j", "RETURN", NULL); 148d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey return res; 149d8c64026aaae5a9987151b719bd840ec7d68747aJeff Sharkey} 150