softwarecontainer  0.18.0-739e8d7 2017-05-04
networkgatewayparser.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 #include "networkgatewayparser.h"
20 
21 namespace softwarecontainer {
22 
24  IPTableEntry &e)
25 {
26  std::string chain;
27  if (!JSONParser::read(element, "direction", chain)) {
28  log_error() << "No type specified in network config.";
29  return false;
30  }
31 
32  e.m_defaultTarget = IPTableEntry::Target::DROP;
33 
34  if ("INCOMING" == chain) {
35  e.m_type = "INPUT";
36  } else if ("OUTGOING" == chain) {
37  e.m_type = "OUTPUT";
38  } else {
39  log_error() << e.m_type << " is not a valid type ('INCOMING' or 'OUTGOING')";
40  return false;
41  }
42 
43  const json_t *rules = json_object_get(element, "allow");
44 
45  if (rules == nullptr) {
46  log_error() << "No rules specified";
47  return false;
48  }
49 
50  if (!json_is_array(rules)) {
51  log_error() << "Rules not specified as an array";
52  return false;
53  }
54 
55  size_t ix;
56  json_t *val;
57  json_array_foreach(rules, ix, val) {
58  if (json_is_object(val)) {
59  if (!parseRule(val, e.m_rules)) {
60  log_error() << "Could not parse rule config";
61  return false;
62  }
63  } else {
64  log_error() << "formatting of rules array is incorrect.";
65  return false;
66  }
67  }
68 
69  return true;
70 }
71 
72 
73 bool NetworkGatewayParser::parseRule(const json_t *element,
74  std::vector<IPTableEntry::Rule> &rules)
75 {
77 
78  r.target = IPTableEntry::Target::ACCEPT;
79 
80  if (!JSONParser::read(element, "host", r.host)) {
81  log_error() << "Host not specified in the network config.";
82  return false;
83  }
84 
85  // Parsing port formats
86  json_t *ports = json_object_get(element, "ports");
87  if (ports != nullptr) {
88  parsePort(ports, r.ports);
89  }
90 
91  // Parsing protocols
92  json_t *protocols = json_object_get(element, "protocols");
93  if (protocols != nullptr) {
94  parseProtocol(protocols, r.protocols);
95  }
96 
97  rules.push_back(r);
98  return true;
99 }
100 
101 bool NetworkGatewayParser::parsePort(const json_t *element, IPTableEntry::portFilter &ports)
102 {
103  // Port formatted as single integer means there is only one port
104  if (json_is_integer(element)) {
105  auto port = json_integer_value(element);
106  ports.any = true;
107  ports.multiport = false;
108  ports.ports = std::to_string(port);
109  // Port formatted as a string representing a range
110  } else if (json_is_string(element)) {
111  auto portRange = json_string_value(element);
112  ports.any = true;
113  ports.multiport = true;
114  ports.ports = portRange;
115  // Port formatted as a list of integers
116  } else if (json_is_array(element)) {
117  size_t ix;
118  json_t *val;
119  std::string portList = "";
120 
121  json_array_foreach(element, ix, val) {
122  if (!json_is_integer(val)) {
123  log_error() << "Entry in port array is not an integer.";
124  return false;
125  }
126 
127  int port = json_integer_value(val);
128  portList = portList + std::to_string(port) + ",";
129  }
130  portList.pop_back();
131  ports.any = true;
132  ports.multiport = true;
133  ports.ports = portList;
134  } else {
135  log_error() << "Rules specified in an invalid format";
136  return false;
137  }
138  return true;
139 }
140 
141 bool NetworkGatewayParser::isProtocolValid(std::string protocol) {
142  if ((protocol == "tcp") || (protocol == "udp") || (protocol == "icmp")) {
143  return true;
144  } else {
145  log_error() << protocol
146  << " is not valid value. Only tcp, udp and icmp protocols are allowed";
147  return false;
148  }
149 }
150 
151 bool NetworkGatewayParser::parseProtocol(const json_t *element,
152  std::vector<std::string> &proto)
153 {
154  // Single Protocol
155  if (json_is_string(element)) {
156  std::string protocol = json_string_value(element);
157  if (!isProtocolValid(protocol)) {
158  return false;
159  }
160  proto.push_back(protocol);
161  // Multiple protocols
162  } else if (json_is_array(element)) {
163  size_t ix;
164  json_t *val;
165 
166  json_array_foreach(element, ix, val) {
167  if (!json_is_string(val)) {
168  log_error() << "Listed protocol is not valid";
169  return false;
170  }
171 
172  std::string protocol = json_string_value(val);
173 
174  if (!isProtocolValid(protocol)) {
175  return false;
176  }
177 
178  proto.push_back(protocol);
179  }
180  } else {
181  log_error() << "Protocols specified in an invalid format";
182  return false;
183  }
184  return true;
185 }
186 
187 } // namespace softwarecontainer
Definition of a &#39;Rule&#39; used to handle network traffic.
Definition: iptableentry.h:62
bool parseNetworkGatewayConfiguration(const json_t *element, IPTableEntry &e)
Parses NetworkGateway configuration into IPTableEntry.
container for port filtering options.
Definition: iptableentry.h:37
Developers guide to adding a config item:
static bool read(const json_t *element, const char *key, std::string &result)
Reads a string from a JSON Object.
Definition: jsonparser.cpp:51
A rules entry for the treatment of packets.
Definition: iptableentry.h:29