/*******************************************************************************
* Copyright (c) 2016 Eurotech and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Eurotech - initial API and implementation
*******************************************************************************/
package org.eclipse.kura.net.admin;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.kura.KuraErrorCode;
import org.eclipse.kura.KuraException;
import org.eclipse.kura.configuration.ComponentConfiguration;
import org.eclipse.kura.configuration.SelfConfiguringComponent;
import org.eclipse.kura.core.configuration.ComponentConfigurationImpl;
import org.eclipse.kura.core.configuration.metatype.ObjectFactory;
import org.eclipse.kura.core.configuration.metatype.Tad;
import org.eclipse.kura.core.configuration.metatype.Tocd;
import org.eclipse.kura.core.configuration.metatype.Tscalar;
import org.eclipse.kura.core.net.FirewallConfiguration;
import org.eclipse.kura.linux.net.iptables.LinuxFirewall;
import org.eclipse.kura.linux.net.iptables.LocalRule;
import org.eclipse.kura.linux.net.iptables.NATRule;
import org.eclipse.kura.linux.net.iptables.PortForwardRule;
import org.eclipse.kura.net.IP4Address;
import org.eclipse.kura.net.IPAddress;
import org.eclipse.kura.net.NetProtocol;
import org.eclipse.kura.net.NetworkPair;
import org.eclipse.kura.net.admin.event.FirewallConfigurationChangeEvent;
import org.eclipse.kura.net.firewall.FirewallAutoNatConfig;
import org.eclipse.kura.net.firewall.FirewallNatConfig;
import org.eclipse.kura.net.firewall.FirewallOpenPortConfigIP;
import org.eclipse.kura.net.firewall.FirewallOpenPortConfigIP4;
import org.eclipse.kura.net.firewall.FirewallPortForwardConfigIP;
import org.eclipse.kura.net.firewall.FirewallPortForwardConfigIP4;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.event.EventAdmin;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FirewallConfigurationServiceImpl implements FirewallConfigurationService, SelfConfiguringComponent {
private static final Logger s_logger = LoggerFactory.getLogger(FirewallConfigurationServiceImpl.class);
private EventAdmin m_eventAdmin;
public void setEventAdmin(EventAdmin eventAdmin) {
this.m_eventAdmin = eventAdmin;
}
public void unsetEventAdmin(EventAdmin eventAdmin) {
this.m_eventAdmin = null;
}
protected void activate(ComponentContext componentContext, Map<String, Object> properties) {
s_logger.debug("activate()");
// we are intentionally ignoring the properties from ConfigAdmin at startup
if (properties == null) {
s_logger.debug("activate() :: Got null properties...");
} else {
for (String key : properties.keySet()) {
s_logger.debug("activate() :: Props... {}={}", key, properties.get(key));
}
}
}
protected void deactivate(ComponentContext componentContext) {
s_logger.debug("deactivate()");
}
public synchronized void updated(Map<String, Object> properties) {
s_logger.debug("updated()");
for (String key : properties.keySet()) {
s_logger.debug("updated() :: Props... {}={}", key, properties.get(key));
}
FirewallConfiguration firewallConfiguration = new FirewallConfiguration(properties);
try {
setFirewallOpenPortConfiguration(firewallConfiguration.getOpenPortConfigs());
} catch (KuraException e) {
s_logger.error("Failed to set Firewall OPen Ports Configuration - {}", e);
}
try {
setFirewallPortForwardingConfiguration(firewallConfiguration.getPortForwardConfigs());
} catch (KuraException e) {
s_logger.error("Failed to set Firewall Port Forwarding Configuration - {}", e);
}
try {
setFirewallNatConfiguration(firewallConfiguration.getNatConfigs());
} catch (KuraException e) {
s_logger.error("Failed to set Firewall NAT Configuration - {}", e);
}
// raise the event because there was a change
this.m_eventAdmin.postEvent(new FirewallConfigurationChangeEvent(properties));
}
@Override
public FirewallConfiguration getFirewallConfiguration() throws KuraException {
s_logger.debug("getting the firewall configuration");
FirewallConfiguration firewallConfiguration = new FirewallConfiguration();
LinuxFirewall firewall = LinuxFirewall.getInstance();
Iterator<LocalRule> localRules = firewall.getLocalRules().iterator();
while (localRules.hasNext()) {
LocalRule localRule = localRules.next();
if (localRule.getPortRange() != null) {
s_logger.debug("getFirewallConfiguration() :: Adding local rule for {}", localRule.getPortRange());
firewallConfiguration.addConfig(new FirewallOpenPortConfigIP4(localRule.getPortRange(),
NetProtocol.valueOf(localRule.getProtocol()), localRule.getPermittedNetwork(),
localRule.getPermittedInterfaceName(), localRule.getUnpermittedInterfaceName(),
localRule.getPermittedMAC(), localRule.getSourcePortRange()));
} else {
s_logger.debug("getFirewallConfiguration() :: Adding local rule for {}", localRule.getPort());
firewallConfiguration.addConfig(new FirewallOpenPortConfigIP4(localRule.getPort(),
NetProtocol.valueOf(localRule.getProtocol()), localRule.getPermittedNetwork(),
localRule.getPermittedInterfaceName(), localRule.getUnpermittedInterfaceName(),
localRule.getPermittedMAC(), localRule.getSourcePortRange()));
}
}
Iterator<PortForwardRule> portForwardRules = firewall.getPortForwardRules().iterator();
while (portForwardRules.hasNext()) {
PortForwardRule portForwardRule = portForwardRules.next();
try {
s_logger.debug("getFirewallConfiguration() :: Adding port forwarding - inbound iface is {}",
portForwardRule.getInboundIface());
firewallConfiguration
.addConfig(
new FirewallPortForwardConfigIP4(portForwardRule.getInboundIface(),
portForwardRule.getOutboundIface(),
(IP4Address) IPAddress.parseHostAddress(portForwardRule.getAddress()),
NetProtocol.valueOf(portForwardRule.getProtocol()), portForwardRule.getInPort(),
portForwardRule.getOutPort(), portForwardRule.isMasquerade(),
new NetworkPair<IP4Address>(
(IP4Address) IPAddress
.parseHostAddress(portForwardRule.getPermittedNetwork()),
(short) portForwardRule.getPermittedNetworkMask()),
portForwardRule.getPermittedMAC(), portForwardRule.getSourcePortRange()));
} catch (UnknownHostException e) {
e.printStackTrace();
throw new KuraException(KuraErrorCode.INTERNAL_ERROR, e);
}
}
Iterator<NATRule> autoNatRules = firewall.getAutoNatRules().iterator();
while (autoNatRules.hasNext()) {
NATRule autoNatRule = autoNatRules.next();
s_logger.debug("getFirewallConfiguration() :: Adding auto NAT rules {}", autoNatRule.getSourceInterface());
firewallConfiguration.addConfig(new FirewallAutoNatConfig(autoNatRule.getSourceInterface(),
autoNatRule.getDestinationInterface(), autoNatRule.isMasquerade()));
}
Iterator<NATRule> natRules = firewall.getNatRules().iterator();
while (natRules.hasNext()) {
NATRule natRule = natRules.next();
s_logger.debug("getFirewallConfiguration() :: Adding NAT rules {}", natRule.getSourceInterface());
firewallConfiguration.addConfig(new FirewallNatConfig(natRule.getSourceInterface(),
natRule.getDestinationInterface(), natRule.getProtocol(), natRule.getSource(),
natRule.getDestination(), natRule.isMasquerade()));
}
return firewallConfiguration;
}
@Override
public ComponentConfiguration getConfiguration() throws KuraException {
s_logger.debug("getConfiguration()");
try {
FirewallConfiguration firewallConfiguration = getFirewallConfiguration();
return new ComponentConfigurationImpl(PID, getDefinition(),
firewallConfiguration.getConfigurationProperties());
} catch (Exception e) {
e.printStackTrace();
throw new KuraException(KuraErrorCode.INTERNAL_ERROR, e);
}
}
@Override
public void setFirewallOpenPortConfiguration(
List<FirewallOpenPortConfigIP<? extends IPAddress>> firewallConfiguration) throws KuraException {
s_logger.debug("setFirewallOpenPortConfiguration() :: Deleting local rules");
LinuxFirewall firewall = LinuxFirewall.getInstance();
firewall.deleteAllLocalRules();
ArrayList<LocalRule> localRules = new ArrayList<LocalRule>();
for (FirewallOpenPortConfigIP<? extends IPAddress> openPortEntry : firewallConfiguration) {
if (openPortEntry.getPermittedNetwork() == null
|| openPortEntry.getPermittedNetwork().getIpAddress() == null) {
try {
openPortEntry
.setPermittedNetwork(new NetworkPair(IPAddress.parseHostAddress("0.0.0.0"), (short) 0));
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
try {
LocalRule localRule = null;
if (openPortEntry.getPortRange() != null) {
s_logger.debug("setFirewallOpenPortConfiguration() :: Adding local rule for: {}",
openPortEntry.getPortRange());
localRule = new LocalRule(openPortEntry.getPortRange(), openPortEntry.getProtocol().name(),
new NetworkPair(
IPAddress.parseHostAddress(
openPortEntry.getPermittedNetwork().getIpAddress().getHostAddress()),
openPortEntry.getPermittedNetwork().getPrefix()),
openPortEntry.getPermittedInterfaceName(), openPortEntry.getUnpermittedInterfaceName(),
openPortEntry.getPermittedMac(), openPortEntry.getSourcePortRange());
} else {
s_logger.debug("setFirewallOpenPortConfiguration() :: Adding local rule for: {}",
openPortEntry.getPort());
localRule = new LocalRule(openPortEntry.getPort(), openPortEntry.getProtocol().name(),
new NetworkPair(
IPAddress.parseHostAddress(
openPortEntry.getPermittedNetwork().getIpAddress().getHostAddress()),
openPortEntry.getPermittedNetwork().getPrefix()),
openPortEntry.getPermittedInterfaceName(), openPortEntry.getUnpermittedInterfaceName(),
openPortEntry.getPermittedMac(), openPortEntry.getSourcePortRange());
}
localRules.add(localRule);
} catch (Exception e) {
s_logger.error("setFirewallOpenPortConfiguration() :: Failed to add local rule for: {} - {}",
openPortEntry.getPort(), e);
}
}
firewall.addLocalRules(localRules);
}
@Override
public void setFirewallPortForwardingConfiguration(
List<FirewallPortForwardConfigIP<? extends IPAddress>> firewallConfiguration) throws KuraException {
s_logger.debug("setFirewallPortForwardingConfiguration() :: Deleting port forward rules");
LinuxFirewall firewall = LinuxFirewall.getInstance();
firewall.deleteAllPortForwardRules();
ArrayList<PortForwardRule> portForwardRules = new ArrayList<PortForwardRule>();
for (FirewallPortForwardConfigIP<? extends IPAddress> portForwardEntry : firewallConfiguration) {
s_logger.debug("setFirewallPortForwardingConfiguration() :: Adding port forward rule for: {}",
portForwardEntry.getInPort());
if (portForwardEntry.getPermittedNetwork() == null
|| portForwardEntry.getPermittedNetwork().getIpAddress() == null) {
try {
portForwardEntry
.setPermittedNetwork(new NetworkPair(IPAddress.parseHostAddress("0.0.0.0"), (short) 0));
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
PortForwardRule portForwardRule = new PortForwardRule(portForwardEntry.getInboundInterface(),
portForwardEntry.getOutboundInterface(), portForwardEntry.getAddress().getHostAddress(),
portForwardEntry.getProtocol().name(), portForwardEntry.getInPort(), portForwardEntry.getOutPort(),
portForwardEntry.isMasquerade(),
portForwardEntry.getPermittedNetwork().getIpAddress().getHostAddress(),
portForwardEntry.getPermittedNetwork().getPrefix(), portForwardEntry.getPermittedMac(),
portForwardEntry.getSourcePortRange());
portForwardRules.add(portForwardRule);
}
firewall.addPortForwardRules(portForwardRules);
}
@Override
public void setFirewallNatConfiguration(List<FirewallNatConfig> natConfigs) throws KuraException {
LinuxFirewall firewall = LinuxFirewall.getInstance();
firewall.deleteAllNatRules();
ArrayList<NATRule> natRules = new ArrayList<NATRule>();
for (FirewallNatConfig natConfig : natConfigs) {
NATRule natRule = new NATRule(natConfig.getSourceInterface(), natConfig.getDestinationInterface(),
natConfig.getProtocol(), natConfig.getSource(), natConfig.getDestination(),
natConfig.isMasquerade());
natRules.add(natRule);
}
firewall.addNatRules(natRules);
}
private Tocd getDefinition() throws KuraException {
ObjectFactory objectFactory = new ObjectFactory();
Tocd tocd = objectFactory.createTocd();
tocd.setName("FirewallConfigurationService");
tocd.setId("org.eclipse.kura.net.admin.FirewallConfigurationService");
tocd.setDescription("Firewall Configuration Service");
Tad tad = objectFactory.createTad();
tad.setId(FirewallConfiguration.OPEN_PORTS_PROP_NAME);
tad.setName(FirewallConfiguration.OPEN_PORTS_PROP_NAME);
tad.setType(Tscalar.STRING);
tad.setCardinality(10000);
tad.setRequired(true);
tad.setDefault(FirewallConfiguration.DFLT_OPEN_PORTS_VALUE);
tad.setDescription(NetworkAdminConfigurationMessages.getMessage(NetworkAdminConfiguration.PLATFORM_INTERFACES));
tocd.addAD(tad);
tad = objectFactory.createTad();
tad.setId(FirewallConfiguration.PORT_FORWARDING_PROP_NAME);
tad.setName(FirewallConfiguration.PORT_FORWARDING_PROP_NAME);
tad.setType(Tscalar.STRING);
tad.setCardinality(10000);
tad.setRequired(true);
tad.setDefault(FirewallConfiguration.DFLT_PORT_FORWARDING_VALUE);
tad.setDescription(NetworkAdminConfigurationMessages.getMessage(NetworkAdminConfiguration.PLATFORM_INTERFACES));
tocd.addAD(tad);
tad = objectFactory.createTad();
tad.setId(FirewallConfiguration.NAT_PROP_NAME);
tad.setName(FirewallConfiguration.NAT_PROP_NAME);
tad.setType(Tscalar.STRING);
tad.setCardinality(10000);
tad.setRequired(true);
tad.setDefault(FirewallConfiguration.DFLT_NAT_VALUE);
tad.setDescription(NetworkAdminConfigurationMessages.getMessage(NetworkAdminConfiguration.PLATFORM_INTERFACES));
tocd.addAD(tad);
return tocd;
}
}