FAQ10820]针对某个APK,需要做到wifi/gprs分别做到允许/禁止两种策略

如何禁止某个应用联网

DESCRIPTION]
JB5开始已经default有这部分代码,只需要参照该FAQ后面的使用说明和方法调用即可。
JB5之前的版本,可以按照下面完整的solution进行操作
[SOLUTION]
1.NetworkManagementService.java
    public void setFirewallUidChainRule(int uid, int networkType, boolean allow) {
        //enforceSystemUid();
        final String MOBILE = "mobile";
        final String WIFI = "wifi";

        final String rule = allow ? ALLOW : DENY;
        final String chain = (networkType == 1) ? WIFI : MOBILE;
        
        try {
            mConnector.execute("firewall", "set_uid_fw_rule", uid, chain, rule);
        } catch (NativeDaemonConnectorException e) {
            throw e.rethrowAsParcelableException();
        }
    }
    
    /**
     * @internal Configure firewall rule by uid and chain
     * @hide
     */
    public void clearFirewallChain(String chain) {
        //enforceSystemUid();
        try {
            mConnector.execute("firewall", "clear_fw_chain", chain);
        } catch (NativeDaemonConnectorException e) {
            throw e.rethrowAsParcelableException();
        }
    }    
}
2.CommandListener.cpp中
1)最后一个类FirewallCmd的runCommand方法的
    cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown command", false);
    return 0;
之前加上
    if (!strcmp(argv[1], "set_uid_fw_rule")) {
        if (argc != 5) {
            cli->sendMsg(ResponseCode::CommandSyntaxError,
                         "Usage: firewall set_uid_fw_rule <uid> <mobile|wifi> <allow|deny>",
                         false);
            return 0;
        }

        int uid = atoi(argv[2]);
        FirewallChinaRule chain = parseChain(argv[3]);
        FirewallRule rule = parseRule(argv[4]);

        int res = sFirewallCtrl->setUidFwRule(uid, chain, rule);
        return sendGenericOkFail(cli, res);
    }

    if (!strcmp(argv[1], "clear_fw_chain")) {
        if (argc != 3) {
            cli->sendMsg(ResponseCode::CommandSyntaxError,
                         "Usage: firewall clear_fw_chain <chain>",
                         false);
            return 0;
        }

        const char* chain = argv[2];
        
        int res = sFirewallCtrl->clearFwChain(chain);
        return sendGenericOkFail(cli, res);
    }   
2)以下两个数组改成如下;
static const char* FILTER_INPUT[] = {
        // Bandwidth should always be early in input chain, to make sure we
        // correctly count incoming traffic against data plan.
        BandwidthController::LOCAL_INPUT,
// mtk03594: Support enhanced firewall @{
        FirewallController::FIREWALL,
///@}
        FirewallController::LOCAL_INPUT,
        NULL,
};
static const char* FILTER_OUTPUT[] = {
        OEM_IPTABLES_FILTER_OUTPUT,
// mtk03594: Support enhanced firewall @{
        FirewallController::FIREWALL,
///@}
        FirewallController::LOCAL_OUTPUT,
        BandwidthController::LOCAL_OUTPUT,
        NULL,
};
3) 添加下面这个数组
static const char* FILTER_FIREWALL[] = {
        FirewallController::FIREWALL_MOBILE,
        FirewallController::FIREWALL_WIFI,
        NULL,
};

4) CommandListener.cpp的构造函数CommandListener::CommandListener() :的
    createChildChains(V4, "nat", "PREROUTING", NAT_PREROUTING);
    createChildChains(V4, "nat", "POSTROUTING", NAT_POSTROUTING);

    // Let each module setup their child chains
    setupOemIptablesHook();
后添加
createChildChains(V4V6, "filter", "firewall", FILTER_FIREWALL);


3.FirewallController.cpp里
1)加上以下两个函数
int FirewallController::setUidFwRule(int uid, FirewallChinaRule chain, FirewallRule rule) {
    char uidStr[16];
    char cmdStr[128];
    int res = 0;
    const char* op;
    const char* fwChain;

    sprintf(uidStr, "%d", uid);

    if (rule == ALLOW) {
        op = "-I";
    } else {
        op = "-D";
    }

    if(chain == MOBILE) {
        fwChain = "mobile";
    }else{
        fwChain = "wifi";
    }

    res |= execIptables(V4, op, fwChain, "-m", "owner", "--uid-owner", uidStr,
            "-j", "REJECT", "--reject-with", "icmp-net-prohibited", NULL);
    res |= execIptables(V6, op, fwChain, "-m", "owner", "--uid-owner", uidStr,
            "-j", "REJECT", "--reject-with", "icmp6-adm-prohibited", NULL);

    return res;    
}

int FirewallController::clearFwChain(const char* chain) {
    int res = 0;

    if(chain != NULL){
        if(strlen(chain) > 0){
            res |= execIptables(V4V6, "-F", chain, NULL);
        }else{
            ALOGD("Clear all chain");
            res |= execIptables(V4V6, "-F", NULL);
        }
    }else{
        ALOGE("Chain is NULL");
    }

    return res;
}
2).FirewallController.cpp文件里面添加
const char* FirewallController::FIREWALL = "firewall";
3).FirewallController.cpp文件下面这个方法改成如下;
int FirewallController::setupIptablesHooks(void) {

    // mtk03594: Support enhanced firewall @{
    int res = 0;
    res |= execIptables(V4V6, "-F", FIREWALL, NULL);
    res |= execIptables(V4V6, "-A", FIREWALL, "-o", "ppp+", "-j", FIREWALL_MOBILE, NULL);
    res |= execIptables(V4V6, "-A", FIREWALL, "-o", "ccmni+", "-j", FIREWALL_MOBILE, NULL);
    res |= execIptables(V4V6, "-A", FIREWALL, "-o", "ccemni+", "-j", FIREWALL_MOBILE, NULL);
    res |= execIptables(V4V6, "-A", FIREWALL, "-o", "usb+", "-j", FIREWALL_MOBILE, NULL);
    res |= execIptables(V4V6, "-A", FIREWALL, "-o", "cc2mni+", "-j", FIREWALL_MOBILE, NULL);
    res |= execIptables(V4V6, "-A", FIREWALL, "-o", "wlan+", "-j", FIREWALL_WIFI, NULL);
    //@}
    
    return 0;
}

4.FirewallController.h里
加上以下两个函数定义
    int setUidFwRule(int, FirewallChinaRule, FirewallRule);
    int clearFwChain(const char* chain);
JB5开始的版本可以从此开始进行修改:
完成以上代码添加后,可以在相应的APK里采用以下步骤使用添加的这些接口:
1.在相关的文件里import并且定义及获得NetworkManagementService
    import android.os.INetworkManagementService;
    private INetworkManagementService mNetworkService;
        mNetworkService = INetworkManagementService.Stub.asInterface(
                ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE));

2.调用mNetworkService.setFirewallUidChainRule or mNetworkService.clearFirewallChain设置和清空相应的APP的限制即可.

PS:1.每次重新开机,其Iptable都会被清空,如果下次重新开机时,需要重新下一遍command
     2.setFirewallUidChainRule这个方法,针对同一个AP其allow和deny要成对出现
     如果是要禁止掉某个APP访问网络的话,应该是要下allow,而不是下deny,deny是不禁止,allow是允许禁止
     clearFirewallChain是重置规则,一般在APK reset的时候使用,它里面传的参数可以为wifi 或者mobile
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值