softwarecontainer  0.18.0-739e8d7 2017-05-04
iptableentry.cpp
1 /*
2  * Copyright (C) 2016-2017 Pelagicore AB
3  *
4  * Permission to use, copy, modify, and/or distribute this software for
5  * any purpose with or without fee is hereby granted, provided that the
6  * above copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
9  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
10  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
11  * BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
12  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
13  * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
14  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
15  * SOFTWARE.
16  *
17  * For further information see LICENSE
18  */
19 
20 #include "iptableentry.h"
21 #include "gateway/gateway.h"
22 #include <iostream>
23 
24 namespace softwarecontainer {
25 
27 {
28  for (auto rule : m_rules) {
29  if (rule.protocols.size()) {
30 
31  for (auto proto : rule.protocols) {
32  if (!insertCommand(interpretRuleWithProtocol(rule, proto))) {
33  std::cerr << "Couldn't apply the rule " << rule.target << std::endl;
34  return false;
35  }
36  }
37 
38  } else if (!insertCommand(interpretRule(rule))) {
39  std::cerr << "Couldn't apply the rule " << rule.target << std::endl;
40  return false;
41  }
42  }
43 
44  if (!insertCommand(interpretPolicy())) {
45  std::cerr << "Unable to set policy " << convertTarget(m_defaultTarget)
46  << " for " << m_type << std::endl;
47  return false;
48  }
49 
50  return true;
51 }
52 
53 std::string IPTableEntry::convertTarget (Target& t)
54 {
55  switch(t)
56  {
57  case Target::ACCEPT:
58  return "ACCEPT";
59  case Target::DROP:
60  return "DROP";
61  case Target::REJECT:
62  return "REJECT";
63  case Target::INVALID_TARGET:
64  return "INVALID";
65  }
66  return "INVALID";
67 }
68 
69 std::string IPTableEntry::interpretRuleWithProtocol(Rule rule, const std::string &protocol)
70 {
71  std::string iptableCommand = "iptables -A " + m_type;
72 
73  if (!rule.host.empty()) {
74  if (rule.host != "*") {
75  if ("INPUT" == m_type) {
76  iptableCommand = iptableCommand + " -s ";
77  } else {
78  iptableCommand = iptableCommand + " -d ";
79  }
80  iptableCommand = iptableCommand + rule.host ;
81  }
82  }
83 
84  if (rule.ports.any) {
85  if (rule.ports.multiport) {
86  iptableCommand = iptableCommand + " -p " + protocol + " --match multiport ";
87 
88  if ("INPUT" == m_type) {
89  iptableCommand = iptableCommand + "--sports " + rule.ports.ports;
90  } else {
91  iptableCommand = iptableCommand + "--dports " + rule.ports.ports;
92  }
93  } else {
94  iptableCommand = iptableCommand + " -p " + protocol + " ";
95  if ("INPUT" == m_type) {
96  iptableCommand = iptableCommand + "--sport " + rule.ports.ports;
97  } else {
98  iptableCommand = iptableCommand + "--dport " + rule.ports.ports;
99  }
100  }
101  } else {
102  iptableCommand = iptableCommand + " -p " + protocol;
103  }
104 
105  iptableCommand = iptableCommand + " -j " + convertTarget(rule.target);
106 
107  return iptableCommand;
108 }
109 
111 {
112  std::string iptableCommand = "iptables -A " + m_type;
113 
114  if (!rule.host.empty()) {
115  if (rule.host != "*") {
116  if ("INPUT" == m_type) {
117  iptableCommand = iptableCommand + " -s ";
118  } else {
119  iptableCommand = iptableCommand + " -d ";
120  }
121  iptableCommand = iptableCommand + rule.host ;
122  }
123  }
124 
125  if (rule.ports.any) {
126  if (rule.ports.multiport) {
127  iptableCommand = iptableCommand + " -p all --match multiport ";
128 
129  if ("INPUT" == m_type) {
130  iptableCommand = iptableCommand + "--sports " + rule.ports.ports;
131  } else {
132  iptableCommand = iptableCommand + "--dports " + rule.ports.ports;
133  }
134  } else {
135  iptableCommand = iptableCommand + " -p tcp ";
136  if ("INPUT" == m_type) {
137  iptableCommand = iptableCommand + "--sport " + rule.ports.ports;
138  } else {
139  iptableCommand = iptableCommand + "--dport " + rule.ports.ports;
140  }
141  }
142  }
143 
144  iptableCommand = iptableCommand + " -j " + convertTarget(rule.target);
145 
146  return iptableCommand;
147 }
148 
150 {
151  if (m_defaultTarget != Target::ACCEPT && m_defaultTarget != Target::DROP) {
152  std::cerr << "Wrong default target : " << convertTarget(m_defaultTarget) << std::endl;
153  return "";
154  }
155  std::string iptableCommand = "iptables -P " + m_type + " " + convertTarget(m_defaultTarget);
156 
157  return iptableCommand;
158 }
159 
160 
161 bool IPTableEntry::insertCommand(std::string command)
162 {
163  std::cout << "Add network rule : " << command << std::endl;
164 
165  try {
166  Glib::spawn_command_line_sync(command);
167 
168  } catch (Glib::SpawnError e) {
169  std::cerr << "Failed to spawn " << command << ": code " << e.code()
170  << " msg: " << e.what() << std::endl;
171 
172  return false;
173  } catch (Glib::ShellError e) {
174  std::cerr << "Failed to call " << command << ": code " << e.code()
175  << " msg: " << e.what() << std::endl;
176  return false;
177  }
178 
179  return true;
180 }
181 
183 {
184  return "IPTableEntry type: " + m_type;
185 }
186 
187 } // namespace softwarecontainer
Definition of a &#39;Rule&#39; used to handle network traffic.
Definition: iptableentry.h:62
Target
Targets for Rules.
Definition: iptableentry.h:51
std::string interpretRuleWithProtocol(Rule rule, const std::string &protocol)
Interprets a rule with protocol information to iptables applicable string.
std::string interpretRule(Rule rule)
Interprets a rule to iptables applicable string.
bool applyRules()
Applies all rules to iptables.
std::string interpretPolicy(void)
This function Interprets defaultTarget rule to iptables applicable policy string. ...
std::string toString()
Creates a string with information about the entry.
Developers guide to adding a config item: