/* * Copyright 2010 NCHOVY * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.krakenapps.iptables.msgbus; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.felix.ipojo.annotations.Component; import org.apache.felix.ipojo.annotations.Provides; import org.apache.felix.ipojo.annotations.Requires; import org.krakenapps.iptables.Chain; import org.krakenapps.iptables.Iptables; import org.krakenapps.iptables.Rule; import org.krakenapps.msgbus.Request; import org.krakenapps.msgbus.Response; import org.krakenapps.msgbus.handler.MsgbusMethod; import org.krakenapps.msgbus.handler.MsgbusPlugin; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @Component(name = "iptables-plugin") @Provides @MsgbusPlugin public class IptablesPlugin { private final Logger logger = LoggerFactory.getLogger(IptablesPlugin.class); @Requires private Iptables iptables; @MsgbusMethod public void getChainNames(Request req, Response resp) { try { resp.put("chain_names", iptables.getChainNames()); } catch (IOException e) { logger.error("kraken-iptabls: failed to get chain names.", e); } } @MsgbusMethod public void getRules(Request req, Response resp) { try { List<Rule> rules = null; if (req.has("chain_type")) rules = iptables.getRules(Chain.valueOf(req.getString("chain_type"))); else if (req.has("chain_name")) rules = iptables.getRules(req.getString("chain_name")); if (rules != null) { List<Object> r = new ArrayList<Object>(); for (Rule rule : rules) r.add(marshal(rule)); resp.put("rules", r); } } catch (IOException e) { logger.error("kraken-iptabls: failed to get rules.", e); } } private Map<String, Object> marshal(Rule rule) { Map<String, Object> m = new HashMap<String, Object>(); m.put("in", rule.getIn()); m.put("out", rule.getOut()); m.put("source", rule.getSource().getNetworkAddress().getHostAddress()); m.put("destination", rule.getDestination().getNetworkAddress().getHostAddress()); m.put("protocol", rule.getProtocol()); m.put("target", rule.getTarget()); m.put("match_options", rule.getMatchOptions()); m.put("target_options", rule.getTargetOptions()); return m; } @MsgbusMethod public void addRule(Request req, Response resp) { Integer index = req.getInteger("index"); Rule rule = convertRule(req.get("rule")); if (req.has("chain_type")) { Chain chain = Chain.valueOf(req.getString("chain_type")); if (index == null) iptables.addRule(chain, rule); else iptables.addRule(chain, index, rule); } else if (req.has("chain_name")) { String chainName = req.getString("chain_name"); if (index == null) iptables.addRule(chainName, rule); else iptables.addRule(chainName, index, rule); } } private Rule convertRule(Object obj) { return null; } @MsgbusMethod public void removeRule(Request req, Response resp) { int index = req.getInteger("index"); try { if (req.has("chain_type")) iptables.removeRule(Chain.valueOf(req.getString("chain_type")), index); else if (req.has("chain_name")) iptables.removeRule(req.getString("chain_name"), index); } catch (IOException e) { logger.error("kraken-iptabls: failed to remove rule.", e); } } @SuppressWarnings("unchecked") @MsgbusMethod public void removeRules(Request req, Response resp) { List<Object> objs = (List<Object>) req.get("rules"); List<IptablesPlugin.RuleInfo> rules = new ArrayList<IptablesPlugin.RuleInfo>(); for (Object obj : objs) { Map<String, Object> m = (Map<String, Object>) obj; if (m.containsKey("chain_type")) rules.add(new RuleInfo((Integer) m.get("index"), (String) m.get("chain_type"), false)); else if (m.containsKey("chain_name")) rules.add(new RuleInfo((Integer) m.get("index"), (String) m.get("chain_name"), true)); } Collections.sort(rules, new Comparator<RuleInfo>() { @Override public int compare(RuleInfo o1, RuleInfo o2) { return (o2.index - o1.index); } }); for (RuleInfo info : rules) info.removeRule(); } private class RuleInfo { public int index; public String chain; public boolean isName; public RuleInfo(int index, String chain, boolean isName) { this.index = index; this.chain = chain; this.isName = isName; } public void removeRule() { try { if (isName) iptables.removeRule(chain, index); else iptables.removeRule(Chain.valueOf(chain), index); } catch (IOException e) { logger.error("kraken-iptabls: failed to remove rule.", e); } } } }