From 38ff401f11addce463ddc4035f7a9305edd3adc0 Mon Sep 17 00:00:00 2001 From: Luke De Mouy Date: Mon, 11 Jan 2016 14:17:02 -0700 Subject: [PATCH 1/8] Copy the functionality from the original utility into the Firewall class, in particular adds in the following functionality: Start, Stop, and Restart the firewall, and see if it's running Open or Close a port, and get a list of the ports that are currently open. UI code was removed, and functions were modified as appropriate. --- src/library/sysadm-firewall.cpp | 94 ++++++++++++++++++++++++++++++++- src/library/sysadm-firewall.h | 54 ++++++++++++++++++- 2 files changed, 146 insertions(+), 2 deletions(-) diff --git a/src/library/sysadm-firewall.cpp b/src/library/sysadm-firewall.cpp index 3efd387..ce33cb6 100644 --- a/src/library/sysadm-firewall.cpp +++ b/src/library/sysadm-firewall.cpp @@ -70,9 +70,63 @@ PortInfo Firewall::LookUpPort(int portNumber, QString portType) } -Firewall::Firewall() +void Firewall::OpenPort(int port, QString type) { + openports << QString::number(port)+"::::"+type; + SaveOpenPorts(); +} + +void Firewall::ClosePort(int port, QString type) +{ + openports.removeAll( QString::number(port)+"::::"+type); + SaveOpenPorts(); +} + +QVector Firewall::OpenPorts() +{ + QVector returnValue = QVector(openports.length()); + + for(int i=0; iclose(); delete services; } + +void Firewall::LoadOpenPorts() +{ + openports.clear(); + QFile file("/etc/ipfw.openports"); + if( file.open(QIODevice::ReadOnly) ){ + QTextStream in(&file); + while( !in.atEnd() ){ + QString line = in.readLine(); + if(line.startsWith("#") || line.simplified().isEmpty()){ continue; } + //File format: " " (nice and simple) + openports << line.section(" ",1,1)+"::::"+line.section(" ",0,0); + } + file.close(); + } + openports.sort(); //order them in ascending port order +} + +void Firewall::SaveOpenPorts() +{ + //Convert to file format + openports.sort(); //make sure they are still sorted by port + QStringList fileout; + for(int i=0; i OpenPorts(); + + ///#endsection + + ///#section: firewall commands + /** + * @brief Checks to see if the firewall is running + * @return true if the firewall is running, false if not + */ + bool IsRunning(); + /** + * @brief Starts the firewall + */ + void Start(); + /** + * @brief Stops the firewall + */ + void Stop(); + /** + * @brief Restarts the firewall + */ + void Restart(); + ///#endsection + + ///#section: ctors dtors Firewall(); ~Firewall(); + ///#endsection private: void readServicesFile(); QStringList* portStrings; + + QStringList openports; + + void LoadOpenPorts(); + void SaveOpenPorts(); }; } #endif // PORTLOOKUP_H From 21f5cf6265e058831eb69dee3471e42d25d1b9b1 Mon Sep 17 00:00:00 2001 From: Luke De Mouy Date: Mon, 11 Jan 2016 14:29:42 -0700 Subject: [PATCH 2/8] Add license header on firewall cpp file --- src/library/sysadm-firewall.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/library/sysadm-firewall.cpp b/src/library/sysadm-firewall.cpp index ce33cb6..f5de9c0 100644 --- a/src/library/sysadm-firewall.cpp +++ b/src/library/sysadm-firewall.cpp @@ -1,3 +1,9 @@ +//=========================================== +// PC-BSD source code +// Copyright (c) 2015, PC-BSD Software/iXsystems +// Available under the 3-clause BSD license +// See the LICENSE file for full details + #include "sysadm-firewall.h" #include using namespace sysadm; From 17d2c131b518dff2b6df63238dd7cdcc4e80ecbb Mon Sep 17 00:00:00 2001 From: Luke De Mouy Date: Mon, 11 Jan 2016 15:02:07 -0700 Subject: [PATCH 3/8] Add in the option to restore the default configuration --- src/library/sysadm-firewall.cpp | 9 +++++++++ src/library/sysadm-firewall.h | 6 +++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/library/sysadm-firewall.cpp b/src/library/sysadm-firewall.cpp index f5de9c0..faa20ce 100644 --- a/src/library/sysadm-firewall.cpp +++ b/src/library/sysadm-firewall.cpp @@ -129,6 +129,15 @@ void Firewall::Restart() system("/etc/rc.d/ipfw restart"); } +void Firewall::RestoreDefaults() +{ + //move the files out of the way + system("mv /etc/ipfw.rules /etc/ipfw.rules.previous"); + system("mv /etc/ipfw.openports /etc/ipfw.openports.previous"); + //refresh/restart the rules files + system("sh /usr/local/share/pcbsd/scripts/reset-firewall"); +} + Firewall::Firewall() { readServicesFile(); diff --git a/src/library/sysadm-firewall.h b/src/library/sysadm-firewall.h index 62d1bcd..c6aa321 100644 --- a/src/library/sysadm-firewall.h +++ b/src/library/sysadm-firewall.h @@ -55,7 +55,6 @@ public: * @return a QVector of the open ports */ QVector OpenPorts(); - ///#endsection ///#section: firewall commands @@ -76,6 +75,11 @@ public: * @brief Restarts the firewall */ void Restart(); + + /** + * @brief Restores the Default Configuration + */ + void RestoreDefaults(); ///#endsection ///#section: ctors dtors From 20ee1eaf62394437b3b32fbf4effbcff1afeb155 Mon Sep 17 00:00:00 2001 From: Luke De Mouy Date: Mon, 11 Jan 2016 19:28:02 -0700 Subject: [PATCH 4/8] Switch openports from being a nonintuitive string to using our PortInfo struct and add comments to the /etc/ipfw.openports file when we write to it. Enable C++11 in the library.pro file as it's required for std::sort and std::tie, since qSort is deprecated as of Qt 5.3 --- src/library/library.pro | 2 +- src/library/sysadm-firewall.cpp | 26 +++++++++++++------------- src/library/sysadm-firewall.h | 13 ++++++++++++- 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/library/library.pro b/src/library/library.pro index e599734..769fca9 100644 --- a/src/library/library.pro +++ b/src/library/library.pro @@ -1,4 +1,4 @@ - +CONFIG += c++11 QT += core network TARGET=sysadm diff --git a/src/library/sysadm-firewall.cpp b/src/library/sysadm-firewall.cpp index faa20ce..e1a2213 100644 --- a/src/library/sysadm-firewall.cpp +++ b/src/library/sysadm-firewall.cpp @@ -6,6 +6,9 @@ #include "sysadm-firewall.h" #include +#include +#include + using namespace sysadm; PortInfo Firewall::LookUpPort(int portNumber, QString portType) { @@ -78,24 +81,19 @@ PortInfo Firewall::LookUpPort(int portNumber, QString portType) void Firewall::OpenPort(int port, QString type) { - openports << QString::number(port)+"::::"+type; + openports.append(LookUpPort(port,type)); SaveOpenPorts(); } void Firewall::ClosePort(int port, QString type) { - openports.removeAll( QString::number(port)+"::::"+type); + openports.removeAll(LookUpPort(port,type)); SaveOpenPorts(); } QVector Firewall::OpenPorts() { - QVector returnValue = QVector(openports.length()); - - for(int i=0; ireadLine(); //jump down past the comments - if(line[0] == '#') + if(line[0] == '#' || line.simplified().isEmpty()) continue; //remove all of the extraneous whitespace in the line @@ -183,20 +181,22 @@ void Firewall::LoadOpenPorts() QString line = in.readLine(); if(line.startsWith("#") || line.simplified().isEmpty()){ continue; } //File format: " " (nice and simple) - openports << line.section(" ",1,1)+"::::"+line.section(" ",0,0); + openports.append(LookUpPort(line.section(" ",1,1).toInt(),line.section(" ",0,0))); } file.close(); } - openports.sort(); //order them in ascending port order + //order them in ascending order by port then port type + std::sort(openports.begin(),openports.end()); } void Firewall::SaveOpenPorts() { //Convert to file format - openports.sort(); //make sure they are still sorted by port + std::sort(openports.begin(), openports.end()); //make sure they are still sorted by port QStringList fileout; for(int i=0; i(const PortInfo lhs, const PortInfo rhs) + { return rhs < lhs;} + friend bool operator==(const PortInfo lhs, const PortInfo rhs) + { + return lhs.Port == rhs.Port && lhs.PortType == rhs.PortType; + } + friend bool operator !=(const PortInfo lhs, const PortInfo rhs) + { return !(lhs == rhs);} }; const static int recommendedPorts[] = {22, 80}; @@ -91,7 +102,7 @@ private: void readServicesFile(); QStringList* portStrings; - QStringList openports; + QVector openports; void LoadOpenPorts(); void SaveOpenPorts(); From 4645d2fa200841c6834def4dae72bd34fc4567a0 Mon Sep 17 00:00:00 2001 From: Luke De Mouy Date: Mon, 11 Jan 2016 19:38:42 -0700 Subject: [PATCH 5/8] rename PortType to Type, and simply the argument names from functions from portType and portNumber to type and number respectively --- src/library/sysadm-firewall.cpp | 20 ++++++++++---------- src/library/sysadm-firewall.h | 24 ++++++++++++------------ 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/library/sysadm-firewall.cpp b/src/library/sysadm-firewall.cpp index e1a2213..c519193 100644 --- a/src/library/sysadm-firewall.cpp +++ b/src/library/sysadm-firewall.cpp @@ -10,10 +10,10 @@ #include using namespace sysadm; -PortInfo Firewall::LookUpPort(int portNumber, QString portType) +PortInfo Firewall::LookUpPort(int port, QString type) { //Make sure that the port is valid - if (portNumber < 0 || portNumber > 65535) + if (port < 0 || port > 65535) { PortInfo returnValue; returnValue.Port = -1; @@ -28,19 +28,19 @@ PortInfo Firewall::LookUpPort(int portNumber, QString portType) PortInfo returnValue; //the port number is valid so set it - returnValue.Port = portNumber; + returnValue.Port = port; //make sure that the portType is cased in lower to match the service file and //then store it in the returnValue, since there isn't a huge point in checking //the validitiy of the type since /etc/services lists more than udp/tcp - portType = portType.toLower(); - returnValue.PortType = portType; + type = type.toLower(); + returnValue.Type = type; //Check to see if it's a recommended port returnValue.Recommended = false; for(int i = 0; i < recommendedPortsSize; i++) { - if (portNumber == recommendedPorts[i]) + if (port == recommendedPorts[i]) { returnValue.Recommended = true; } @@ -49,12 +49,12 @@ PortInfo Firewall::LookUpPort(int portNumber, QString portType) //Check to see if the port number is listed. The format in the file // is portname/portType. ex.: 22/tcp - QStringList port = portStrings->filter(QString::number(portNumber) + "/" + portType); - if(port.size() > 0) + QStringList portList = portStrings->filter(QString::number(port) + "/" + type); + if(portList.size() > 0) { //grab the first one, there may be duplicates due to colliding ports in the /etc/services file //but those are listed after the declaration for what the port officially should be used for - QString line = port.at(0); + QString line = portList.at(0); //Split across spaces since it's whitespace delimited QStringList lineList = line.split(' '); @@ -196,7 +196,7 @@ void Firewall::SaveOpenPorts() QStringList fileout; for(int i=0; i(const PortInfo lhs, const PortInfo rhs) { return rhs < lhs;} friend bool operator==(const PortInfo lhs, const PortInfo rhs) { - return lhs.Port == rhs.Port && lhs.PortType == rhs.PortType; + return lhs.Port == rhs.Port && lhs.Type == rhs.Type; } friend bool operator !=(const PortInfo lhs, const PortInfo rhs) { return !(lhs == rhs);} @@ -40,25 +40,25 @@ public: * including its port type, keyword, description, and whether it's a * recommended port * - * @param portNumber a port number between 0 and 2^16 - 1 - * @param portType specify whether the port is tdp, udp, etc + * @param number a port number between 0 and 2^16 - 1 + * @param type specify whether the port is tdp, udp, etc * * @ErrorConditions Port Number is set to -1 and a description of the error is stored in the description variable */ - PortInfo LookUpPort(int portNumber, QString portType); + PortInfo LookUpPort(int number, QString type); /** * @brief Opens a port - * @param portNumber a port number between 0 and 2^16 -1 - * @param portType specify whether the port is tdp, udp, etc + * @param number a port number between 0 and 2^16 -1 + * @param type specify whether the port is tdp, udp, etc */ - void OpenPort(int portNumber, QString portType); + void OpenPort(int number, QString type); /** * @brief ClosePort closes a port - * @param portNumber a port number between 0 and 2^16 -1 - * @param portType specify whether the port is tdp, udp, etc + * @param number a port number between 0 and 2^16 -1 + * @param type specify whether the port is tdp, udp, etc */ - void ClosePort(int portNumber, QString portType); + void ClosePort(int number, QString type); /** * @brief finds a list of ports that are open gets the info about them From aec5ce9aeb38b6496c1e27ed79b93f4ac563788d Mon Sep 17 00:00:00 2001 From: Luke De Mouy Date: Tue, 12 Jan 2016 02:26:06 -0700 Subject: [PATCH 6/8] Move the #include to where it should be in the header file as opposed to the cpp --- src/library/sysadm-firewall.cpp | 1 - src/library/sysadm-firewall.h | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/library/sysadm-firewall.cpp b/src/library/sysadm-firewall.cpp index c519193..0c12f11 100644 --- a/src/library/sysadm-firewall.cpp +++ b/src/library/sysadm-firewall.cpp @@ -7,7 +7,6 @@ #include "sysadm-firewall.h" #include #include -#include using namespace sysadm; PortInfo Firewall::LookUpPort(int port, QString type) diff --git a/src/library/sysadm-firewall.h b/src/library/sysadm-firewall.h index ee4633e..36eb8b9 100644 --- a/src/library/sysadm-firewall.h +++ b/src/library/sysadm-firewall.h @@ -7,6 +7,7 @@ #ifndef PORTLOOKUP_H #define PORTLOOKUP_H #include +#include namespace sysadm { struct PortInfo{ From 43a42745659130eec6982275db45c96dddf4ffcc Mon Sep 17 00:00:00 2001 From: Luke De Mouy Date: Tue, 12 Jan 2016 02:37:07 -0700 Subject: [PATCH 7/8] Add in the ability to close or open multiple ports at once, by passing in a QVector to the OpenPort and ClosePort functions, --- src/library/sysadm-firewall.cpp | 18 ++++++++++++++++++ src/library/sysadm-firewall.h | 12 ++++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/library/sysadm-firewall.cpp b/src/library/sysadm-firewall.cpp index 0c12f11..db1799c 100644 --- a/src/library/sysadm-firewall.cpp +++ b/src/library/sysadm-firewall.cpp @@ -84,12 +84,30 @@ void Firewall::OpenPort(int port, QString type) SaveOpenPorts(); } +void Firewall::OpenPort(QVector ports) +{ + for(PortInfo port : ports) + { + openports.append(port); + } + SaveOpenPorts(); +} + void Firewall::ClosePort(int port, QString type) { openports.removeAll(LookUpPort(port,type)); SaveOpenPorts(); } +void Firewall::ClosePort(QVector ports) +{ + for(PortInfo port : ports) + { + openports.removeAll(port); + } + SaveOpenPorts(); +} + QVector Firewall::OpenPorts() { return openports; diff --git a/src/library/sysadm-firewall.h b/src/library/sysadm-firewall.h index 36eb8b9..882eb83 100644 --- a/src/library/sysadm-firewall.h +++ b/src/library/sysadm-firewall.h @@ -54,6 +54,12 @@ public: */ void OpenPort(int number, QString type); + /** + * @brief Opens a set of ports + * @param ports a vector of ports to open + */ + void OpenPort(QVector ports); + /** * @brief ClosePort closes a port * @param number a port number between 0 and 2^16 -1 @@ -61,6 +67,12 @@ public: */ void ClosePort(int number, QString type); + /** + * @brief ClosePort closes a set of ports + * @param ports a vector of ports to close + */ + void ClosePort(QVector ports); + /** * @brief finds a list of ports that are open gets the info about them * and returns them From 58db613ab751d9415564439b686d6e4bb8e7a129 Mon Sep 17 00:00:00 2001 From: Luke De Mouy Date: Tue, 12 Jan 2016 02:58:35 -0700 Subject: [PATCH 8/8] Refactor to use Range Based For Loops since C++11 is enabled, also add in LoadOpenPorts to the function to reset to the default config, so that we have the correct set of open ports. --- src/library/sysadm-firewall.cpp | 12 +++++++----- src/library/sysadm-firewall.h | 3 +-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/library/sysadm-firewall.cpp b/src/library/sysadm-firewall.cpp index db1799c..6ef15bb 100644 --- a/src/library/sysadm-firewall.cpp +++ b/src/library/sysadm-firewall.cpp @@ -37,9 +37,9 @@ PortInfo Firewall::LookUpPort(int port, QString type) //Check to see if it's a recommended port returnValue.Recommended = false; - for(int i = 0; i < recommendedPortsSize; i++) + for(int recommendedPort : recommendedPorts) { - if (port == recommendedPorts[i]) + if (port == recommendedPort) { returnValue.Recommended = true; } @@ -151,6 +151,8 @@ void Firewall::RestoreDefaults() system("mv /etc/ipfw.openports /etc/ipfw.openports.previous"); //refresh/restart the rules files system("sh /usr/local/share/pcbsd/scripts/reset-firewall"); + + LoadOpenPorts(); } Firewall::Firewall() @@ -211,9 +213,9 @@ void Firewall::SaveOpenPorts() //Convert to file format std::sort(openports.begin(), openports.end()); //make sure they are still sorted by port QStringList fileout; - for(int i=0; i recommendedPorts = {22, 80}; class Firewall {