diff --git a/doc/ChangeLog b/doc/ChangeLog index b9fc2f82b..5e9b6a675 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,5 +1,17 @@ 2011-01-19 Vadim Kurland + * NamedObject.cpp (sanitizeObjectName): see #1953 "ASA NAT - two + host objects in the same rule result in incorrect config". We now + register and keep track of all named objects to make sure their + names are unique. + + * newHostDialog.cpp (finishClicked): see #1953 "ASA NAT - two host + objects in the same rule result in incorrect config". Objects that + represent addresses of interfaces of a host object created using + template will be automatically renamed to follow standard naming + convention "host_name:interface_name:ip" to avoid creating + duplicate names. + * PolicyCompiler_pix_writers.cpp: see #1960 add support for CustomService for PIX policy rules. Note that CustomService objects are only supported in Policy rules since nat commands in diff --git a/src/cisco_lib/BaseObjectGroup.cpp b/src/cisco_lib/BaseObjectGroup.cpp index efcab13a7..e716a3234 100644 --- a/src/cisco_lib/BaseObjectGroup.cpp +++ b/src/cisco_lib/BaseObjectGroup.cpp @@ -46,32 +46,33 @@ using namespace fwcompiler; using namespace std; -map BaseObjectGroup::name_disambiguation; +map BaseObjectGroup::name_disambiguation; const char *BaseObjectGroup::TYPENAME={"BaseObjectGroup"}; -string BaseObjectGroup::registerGroupName(const std::string &prefix, +string BaseObjectGroup::registerGroupName(const string &prefix, object_group_type gt) { - ostringstream str; - str << prefix; + QStringList str; + str << QString::fromUtf8(prefix.c_str()); switch (gt) { - case UNKNOWN: str << ".unknown"; break; - case NETWORK: str << ".net"; break; - case PROTO: str << ".proto"; break; - case ICMP_TYPE: str << ".icmp"; break; - case TCP_SERVICE: str << ".tcp"; break; - case UDP_SERVICE: str << ".udp"; break; - case TCP_UDP_SERVICE: str << ".tcpudp"; break; - case MIXED_SERVICE: str << ".mixed"; break; + case UNKNOWN: str << "unknown"; break; + case NETWORK: str << "net"; break; + case PROTO: str << "proto"; break; + case ICMP_TYPE: str << "icmp"; break; + case TCP_SERVICE: str << "tcp"; break; + case UDP_SERVICE: str << "udp"; break; + case TCP_UDP_SERVICE: str << "tcpudp"; break; + case MIXED_SERVICE: str << "mixed"; break; } - int n = name_disambiguation[str.str()]; - name_disambiguation[str.str()] = n + 1; - str << "." << n; - return str.str(); + QString name_prefix = str.join("."); + int n = name_disambiguation[name_prefix]; + name_disambiguation[name_prefix] = n + 1; + str << QString().setNum(n); + return str.join(".").toUtf8().constData(); } BaseObjectGroup::object_group_type BaseObjectGroup::getObjectGroupTypeFromFWObject( diff --git a/src/cisco_lib/BaseObjectGroup.h b/src/cisco_lib/BaseObjectGroup.h index ed527def9..a7026b5d5 100644 --- a/src/cisco_lib/BaseObjectGroup.h +++ b/src/cisco_lib/BaseObjectGroup.h @@ -33,6 +33,9 @@ #include "fwbuilder/ServiceGroup.h" #include "fwbuilder/FWException.h" +#include + + namespace fwcompiler { class NamedObjectManager; @@ -54,7 +57,7 @@ private: public: - static std::map name_disambiguation; + static std::map name_disambiguation; static std::string registerGroupName(const std::string &prefix, object_group_type gt); diff --git a/src/cisco_lib/NamedObject.cpp b/src/cisco_lib/NamedObject.cpp index 0297375d2..4a292ce5b 100644 --- a/src/cisco_lib/NamedObject.cpp +++ b/src/cisco_lib/NamedObject.cpp @@ -211,12 +211,12 @@ const char* rw[] = { }; QSet NamedObject::reserved_words; +map NamedObject::name_disambiguation; NamedObject::NamedObject(const FWObject *_obj) { obj = _obj; - name = sanitizeObjectName(obj->getName().c_str()); if (reserved_words.empty()) { const char** cptr = rw; @@ -226,6 +226,7 @@ NamedObject::NamedObject(const FWObject *_obj) cptr++; } } + name = sanitizeObjectName(QString::fromUtf8(obj->getName().c_str())); } QString NamedObject::getCommandWord() @@ -251,6 +252,11 @@ QString NamedObject::sanitizeObjectName(const QString &name) { qs = qs + "_obj"; } + + int n = name_disambiguation[qs]; + name_disambiguation[qs] = n + 1; + qs = QString("%1.%2").arg(qs).arg(n); + return qs; } diff --git a/src/cisco_lib/NamedObject.h b/src/cisco_lib/NamedObject.h index e41199427..d6a216927 100644 --- a/src/cisco_lib/NamedObject.h +++ b/src/cisco_lib/NamedObject.h @@ -38,7 +38,7 @@ namespace fwcompiler { const libfwbuilder::FWObject *obj; QString name; static QSet reserved_words; - + QString printPorts(int port_range_start, int port_range_end); protected: @@ -50,6 +50,8 @@ protected: public: + static std::map name_disambiguation; + NamedObject(const libfwbuilder::FWObject *obj); virtual QString getCommand(const libfwbuilder::Firewall *fw); virtual QString getCommandWhenObjectGroupMember( diff --git a/src/cisco_lib/NamedObjectsAndGroupsSupport.cpp b/src/cisco_lib/NamedObjectsAndGroupsSupport.cpp index 916156b1f..a4555ed51 100644 --- a/src/cisco_lib/NamedObjectsAndGroupsSupport.cpp +++ b/src/cisco_lib/NamedObjectsAndGroupsSupport.cpp @@ -26,6 +26,7 @@ #include "config.h" #include "NamedObjectsAndGroupsSupport.h" +#include "NamedObject.h" #include "ObjectGroupFactory.h" #include "fwbuilder/FWObjectDatabase.h" @@ -92,7 +93,7 @@ string NamedObjectManager::addNamedObject(const FWObject *obj) if (named_objects[obj->getId()] == NULL) { NamedObject *asa8obj = new NamedObject(obj); - res = asa8obj->getCommand(fw).toStdString(); + res = asa8obj->getCommand(fw).toUtf8().constData(); named_objects[obj->getId()] = asa8obj; } return res; @@ -110,6 +111,7 @@ void CreateObjectGroups::init(FWObjectDatabase *db) object_groups = new Group(); db->add( object_groups ); BaseObjectGroup::name_disambiguation.clear(); + NamedObject::name_disambiguation.clear(); //if (named_objects.size() > 0) clearNamedObjectsRegistry(); } @@ -175,15 +177,16 @@ bool CreateObjectGroups::processNext() obj_group->setObjectGroupTypeFromMembers(named_objects_manager); - QStringList gn; + QStringList group_name_prefix; if (!rule_iface->getLabel().empty()) - gn.push_back(rule_iface->getLabel().c_str()); + group_name_prefix.push_back(rule_iface->getLabel().c_str()); - gn.push_back(rule->getUniqueId().c_str()); - gn.push_back(name_suffix.c_str()); + group_name_prefix.push_back(rule->getUniqueId().c_str()); + group_name_prefix.push_back(name_suffix.c_str()); string group_name = BaseObjectGroup::registerGroupName( - gn.join(".").toStdString(), obj_group->getObjectGroupType()); + group_name_prefix.join(".").toStdString(), + obj_group->getObjectGroupType()); obj_group->setName(group_name); } else diff --git a/src/libgui/ObjectManipulator.h b/src/libgui/ObjectManipulator.h index 0ad69449b..4c2587434 100644 --- a/src/libgui/ObjectManipulator.h +++ b/src/libgui/ObjectManipulator.h @@ -142,7 +142,6 @@ class ObjectManipulator : public QWidget libfwbuilder::FWObject *copyFrom=NULL, QUndoCommand* macro = 0); - void autorename(libfwbuilder::FWObject *obj); void extractFirewallsFromGroup(libfwbuilder::ObjectGroup *gr, std::set &fo); @@ -286,6 +285,7 @@ public: QString makeNameUnique(libfwbuilder::FWObject* parent, const QString &obj_name, const QString &obj_type); + void autorename(libfwbuilder::FWObject *obj); void autorename(std::list &obj_list, const std::string &objtype, const std::string &namesuffix); diff --git a/src/libgui/newHostDialog.cpp b/src/libgui/newHostDialog.cpp index c9973cb86..5ccef751d 100644 --- a/src/libgui/newHostDialog.cpp +++ b/src/libgui/newHostDialog.cpp @@ -578,11 +578,8 @@ void newHostDialog::finishClicked() no->duplicate(o, true); no->setName(m_dialog->obj_name->text().toUtf8().constData()); - if (no==NULL) - { - QDialog::accept(); - return; - } + mw->activeProject()->m_panel->om->autorename(no); + nhst = Host::cast(no); } else { @@ -624,7 +621,8 @@ void newHostDialog::finishClicked() { QString addrname=QString("%1:%2:mac") .arg(m_dialog->obj_name->text()).arg(name); - physAddress* pa = physAddress::cast(db->create(physAddress::TYPENAME)); + physAddress* pa = physAddress::cast( + db->create(physAddress::TYPENAME)); pa->setName(addrname.toUtf8().constData()); oi->add(pa); pa->setPhysAddress(physaddr.toLatin1().constData()); @@ -636,11 +634,14 @@ void newHostDialog::finishClicked() if (address.address == "0.0.0.0") continue; if (address.ipv4) { - string addrname = string( QString("%1:%2:ip").arg(m_dialog->obj_name->text()).arg(name).toUtf8() ); + string addrname = string( + QString("%1:%2:ip") + .arg(m_dialog->obj_name->text()).arg(name).toUtf8()); IPv4 *oa = IPv4::cast(db->create(IPv4::TYPENAME)); oi->add(oa); oa->setName(addrname); - oa->setAddress( InetAddr(address.address.toLatin1().constData()) ); + oa->setAddress( + InetAddr(address.address.toLatin1().constData()) ); bool ok = false ; int inetmask = address.netmask.toInt(&ok); if (ok) @@ -649,16 +650,21 @@ void newHostDialog::finishClicked() } else { - oa->setNetmask( InetAddr(address.netmask.toLatin1().constData()) ); + oa->setNetmask( + InetAddr(address.netmask.toLatin1().constData()) ); } } else { - string addrname = string( QString("%1:%2:ip6").arg(m_dialog->obj_name->text()).arg(name).toUtf8() ); + string addrname = string( + QString("%1:%2:ip6") + .arg(m_dialog->obj_name->text()).arg(name).toUtf8() ); IPv6 *oa = IPv6::cast(db->create(IPv6::TYPENAME)); oi->add(oa); oa->setName(addrname); - oa->setAddress(InetAddr(AF_INET6, address.address.toLatin1().constData()) ); + oa->setAddress( + InetAddr(AF_INET6, + address.address.toLatin1().constData()) ); bool ok = false ; int inetmask = address.netmask.toInt(&ok); if (ok) @@ -667,7 +673,9 @@ void newHostDialog::finishClicked() } else { - oa->setNetmask(InetAddr(AF_INET6, address.netmask.toLatin1().constData())); + oa->setNetmask( + InetAddr(AF_INET6, + address.netmask.toLatin1().constData())); } } }