1
0
mirror of https://github.com/OpenNebula/one.git synced 2024-12-23 17:33:56 +03:00

feature #3175: Check security group consistency

This commit is contained in:
Ruben S. Montero 2014-11-13 16:00:03 +01:00
parent 8a22a6d885
commit 3f2ad72cb0
2 changed files with 175 additions and 0 deletions

View File

@ -119,6 +119,21 @@ private:
~SecurityGroup();
/**
* Check that a rule is valid
* @param rule as a VectorAttribute
* @param error describing the problem if any
* @return true if the rule is valid
*/
bool isValidRule(const VectorAttribute * rule, string& error) const;
/**
* Checks the new rules
* @param error string describing the error if any
* @return 0 on success
*/
int post_update_template(string& error);
// *************************************************************************
// DataBase implementation (Private)
// *************************************************************************

View File

@ -15,6 +15,8 @@
/* ------------------------------------------------------------------------ */
#include "SecurityGroup.h"
#include "NebulaUtil.h"
#include <arpa/inet.h>
/* ------------------------------------------------------------------------ */
@ -65,6 +67,9 @@ SecurityGroup::~SecurityGroup()
int SecurityGroup::insert(SqlDB *db, string& error_str)
{
vector<const Attribute*>::const_iterator it;
vector<const Attribute*> rules;
erase_template_attribute("NAME",name);
if (name.empty())
@ -72,6 +77,23 @@ int SecurityGroup::insert(SqlDB *db, string& error_str)
goto error_name;
}
get_template_attribute("RULE", rules);
for ( it = rules.begin(); it != rules.end(); it++ )
{
const VectorAttribute* rule = dynamic_cast<const VectorAttribute*>(*it);
if (rule == 0)
{
goto error_format;
}
if (!isValidRule(rule, error_str))
{
goto error_valid;
}
}
if ( insert_replace(db, false, error_str) != 0 )
{
goto error_db;
@ -83,6 +105,11 @@ error_name:
error_str = "No NAME in template for Security Group.";
goto error_common;
error_format:
error_str = "RULE has to be defined as a vector attribute.";
goto error_common;
error_valid:
error_db:
error_common:
return -1;
@ -284,3 +311,136 @@ void SecurityGroup::get_rules(vector<VectorAttribute*>& result) const
result.push_back(new_rule);
}
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
bool SecurityGroup::isValidRule(const VectorAttribute * rule, string& error) const
{
string value, ip, proto;
unsigned int ivalue;
int id;
// -------------------------------------------------------------------------
// Check PROTOCOL and extensions
// - RANGE for TCP and UDP
// - ICMP_TYPE for ICMP
// -------------------------------------------------------------------------
proto = rule->vector_value("PROTOCOL");
one_util::toupper(proto);
if ( proto != "TCP" && proto != "UDP" && proto != "ICMP" && proto != "IPSEC"
&& proto != "ALL")
{
error = "Wrong PROTOCOL in rule. Valid options: TCP, UDP, ICMP, IPSEC,"
" ALL.";
return false;
}
value = rule->vector_value("RANGE");
if (!value.empty() && proto != "TCP" && proto != "UDP")
{
error = "RANGE is supported only for TCP and UDP protocols.";
return false;
}
value = rule->vector_value("ICMP_TYPE");
if (!value.empty())
{
if (proto != "ICMP")
{
error = "ICMP_TYPE is supported only for ICMP protocol.";
return false;
}
if (rule->vector_value("ICMP_TYPE", ivalue) != 0)
{
error = "Wrong ICMP_TYPE, it must be integer";
return false;
}
}
// -------------------------------------------------------------------------
// RULE_TYPE
// -------------------------------------------------------------------------
value = rule->vector_value("RULE_TYPE");
one_util::toupper(value);
if ( value != "INBOUND" && value != "OUTBOUND" )
{
error = "Wrong RULE_TYPE in rule. Valid options: INBOUND, OUTBOUND.";
return false;
}
// -------------------------------------------------------------------------
// Check IP, SIZE and NETWORK_ID
// -------------------------------------------------------------------------
ip = rule->vector_value("IP");
if (!ip.empty()) //Target as IP & SIZE
{
struct in_addr ip_addr;
if (rule->vector_value("SIZE", ivalue) != 0)
{
error = "Wrong or empty SIZE.";
return false;
}
if (inet_pton(AF_INET, ip.c_str(), static_cast<void*>(&ip_addr)) != 1)
{
error = "Wrong format for IP value.";
return false;
}
}
else //Target is ANY or NETWORK_ID
{
value = rule->vector_value("NETWORK_ID");
if (!value.empty() && rule->vector_value("NETWORK_ID", id) != 0)
{
error = "Wrong NETWORK_ID.";
return false;
}
}
return true;
}
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
int SecurityGroup::post_update_template(string& error)
{
vector<const Attribute*>::const_iterator it;
vector<const Attribute*> rules;
get_template_attribute("RULE", rules);
for ( it = rules.begin(); it != rules.end(); it++ )
{
const VectorAttribute* rule = dynamic_cast<const VectorAttribute*>(*it);
if (rule == 0)
{
error = "RULE has to be defined as a vector attribute.";
return -1;
}
if (!isValidRule(rule, error))
{
return -1;
}
}
return 0;
}