From 37c6b2a7c9caea90cdb9cb7a8f663a3ed5dece7e Mon Sep 17 00:00:00 2001 From: Luke De Mouy Date: Wed, 6 Jan 2016 12:59:00 -0700 Subject: [PATCH 1/7] Adds in the LookUpPort function call that returns a struct containing information about a port including it's description and keyword. SSH and the web port are current placeholders for the recommended ports list --- src/library/portlookup.cpp | 73 ++++++++++++++++++++++++++++++++++++++ src/library/portlookup.h | 37 +++++++++++++++++++ 2 files changed, 110 insertions(+) create mode 100644 src/library/portlookup.cpp create mode 100644 src/library/portlookup.h diff --git a/src/library/portlookup.cpp b/src/library/portlookup.cpp new file mode 100644 index 0000000..aac5d84 --- /dev/null +++ b/src/library/portlookup.cpp @@ -0,0 +1,73 @@ +#include "portlookup.h" +#include +using namespace sysadm; +PortLookUp::PortInfo PortLookUp::LookUpPort(int portNumber) +{ + //Make sure that the port is valid + if (portNumber < 0 || portNumber > 65535) + { + PortInfo returnValue; + returnValue.Port = -1; + returnValue.Description = "Port out of bounds"; + return returnValue; + } + + PortInfo returnValue; + //the port number is valid so set it + returnValue.Port = portNumber; + + for(int i = 0; i < recommendedPortListSize; i++) + { + if (portNumber == recommendedPorts[i]) + { + returnValue.Recommended = true; + } + } + + + // /etc/services contains a file that lists the various port numbers + // and their descriptions + QFile* services = new QFile("/etc/services"); + services->open(QFile::ReadOnly); + while(!services->atEnd()) + { + QString line = services->readLine(); + + //jump down past the comments + if(line[0] == '#') + continue; + + //remove all of the extraneous whitespace in the line + line = line.simplified(); + //Split across spaces since it's now whitespace delimited + QStringList lineList = line.split(' '); + + //Ports are stored in the file as number/type so take the left hand side + int port = lineList.at(1).split('/').at(0).toInt(); + + //obviously if it's not the port we want, go to the next line + if (port != portNumber) + continue; + + //the keyword associated with the port is the first element in a line + returnValue.Keyword = lineList.at(0); + + //if the size of the list is less than 3 then there is no description + if(lineList.size() > 2) + { + QString description = lineList.at(2); + //String the description back together from the end of the list + for(int i = 3; i < lineList.size(); i++) + { + description += " " + lineList.at(i); + } + returnValue.Description = description; + } + } + services->close(); + + + return returnValue; + +} + diff --git a/src/library/portlookup.h b/src/library/portlookup.h new file mode 100644 index 0000000..4022146 --- /dev/null +++ b/src/library/portlookup.h @@ -0,0 +1,37 @@ +//=========================================== +// 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 + +#ifndef PORTLOOKUP_H +#define PORTLOOKUP_H +#include +namespace sysadm +{ +namespace PortLookUp +{ + static int recommendedPorts[] = {5,22}; + const int recommendedPortListSize = 2; + + struct PortInfo{ + int Port; + QString Keyword; + QString Description; + bool Recommended; + }; + + /** + * @description Returns a structure containing information about the port + * including its port type, keyword, description, and whether it's a + * recommended port + * + * @parameter portNumber a port number between 1 and 2^16 + * + * @ErrorConditions Port Number is set to -1 and a description of the error is stored in the description variable + */ + static PortInfo LookUpPort(int portNumber); +} +} +#endif // PORTLOOKUP_H + From 19c072bc8135f0599b18e140759c725d05743a7c Mon Sep 17 00:00:00 2001 From: Luke De Mouy Date: Wed, 6 Jan 2016 18:04:47 -0700 Subject: [PATCH 2/7] update library.pro to build the portlookup class Refactor portlookup from a function that reads a file each time it is called to a class that reads the file into a QStringList the first time that it is called and reuses it afterwards. --- src/library/library.pro | 7 +-- src/library/portlookup.cpp | 101 ++++++++++++++++++++++--------------- src/library/portlookup.h | 21 ++++---- 3 files changed, 76 insertions(+), 53 deletions(-) diff --git a/src/library/library.pro b/src/library/library.pro index 114c2b2..31547dc 100644 --- a/src/library/library.pro +++ b/src/library/library.pro @@ -13,13 +13,14 @@ VERSION = 1.0.0 HEADERS += sysadm-global.h \ sysadm-general.h \ sysadm-lifepreserver.h \ - sysadm-network.h - + sysadm-network.h \ + portlookup.h SOURCES += sysadm-general.cpp \ sysadm-lifepreserver.cpp \ sysadm-network.cpp \ - NetDevice.cpp + NetDevice.cpp \ + portlookup.cpp include.path=/usr/local/include/ include.files=sysadm-*.h diff --git a/src/library/portlookup.cpp b/src/library/portlookup.cpp index aac5d84..6365b96 100644 --- a/src/library/portlookup.cpp +++ b/src/library/portlookup.cpp @@ -1,5 +1,6 @@ #include "portlookup.h" #include +#include using namespace sysadm; PortLookUp::PortInfo PortLookUp::LookUpPort(int portNumber) { @@ -12,62 +13,80 @@ PortLookUp::PortInfo PortLookUp::LookUpPort(int portNumber) return returnValue; } + //Check to see if things have been initialized + if(portStrings == NULL) + readServicesFile(); + + PortInfo returnValue; //the port number is valid so set it returnValue.Port = portNumber; - - for(int i = 0; i < recommendedPortListSize; i++) + + //Check to see if it's a recommended port + returnValue.Recommended = false; + for(int i = 0; i < recommendedPortsSize; i++) { - if (portNumber == recommendedPorts[i]) - { - returnValue.Recommended = true; - } + if (portNumber == recommendedPorts[i]) + { + returnValue.Recommended = true; + } } + + //Check to see if the port number is listed. The format in the file + // is portname/portType. ex.: 22/tcp + + QStringList port = portStrings->filter(QRegExp("/\\b("+QString::number(portNumber)+"\\/)/g")); + + if(port.size() > 0) + { + //grab the first one since any duplicates are just other port + //types for the same port, usually associated with the same + //application and we're not tracking that + QString line = port.at(0); + + //Split across spaces since it's whitespace delimited + QStringList lineList = line.split(' '); + + //the keyword associated with the port is the first element in a line + returnValue.Keyword = lineList.at(0); + + //if the size of the list is less than 3 then there is no description + if(lineList.size() > 2) + { + QString description = lineList.at(2); + //String the description back together from the end of the list + for(int i = 3; i < lineList.size(); i++) + { + description += " " + lineList.at(i); + } + returnValue.Description = description; + } + } - + return returnValue; + +} + +void PortLookUp::readServicesFile() +{ + portStrings = new QStringList(); + // /etc/services contains a file that lists the various port numbers // and their descriptions QFile* services = new QFile("/etc/services"); services->open(QFile::ReadOnly); while(!services->atEnd()) { - QString line = services->readLine(); + QString line = services->readLine(); + //jump down past the comments + if(line[0] == '#') + continue; - //jump down past the comments - if(line[0] == '#') - continue; + //remove all of the extraneous whitespace in the line + line = line.simplified(); - //remove all of the extraneous whitespace in the line - line = line.simplified(); - //Split across spaces since it's now whitespace delimited - QStringList lineList = line.split(' '); - - //Ports are stored in the file as number/type so take the left hand side - int port = lineList.at(1).split('/').at(0).toInt(); - - //obviously if it's not the port we want, go to the next line - if (port != portNumber) - continue; - - //the keyword associated with the port is the first element in a line - returnValue.Keyword = lineList.at(0); - - //if the size of the list is less than 3 then there is no description - if(lineList.size() > 2) - { - QString description = lineList.at(2); - //String the description back together from the end of the list - for(int i = 3; i < lineList.size(); i++) - { - description += " " + lineList.at(i); - } - returnValue.Description = description; - } + portStrings->append(line); } services->close(); - - - return returnValue; - } diff --git a/src/library/portlookup.h b/src/library/portlookup.h index 4022146..9638ba1 100644 --- a/src/library/portlookup.h +++ b/src/library/portlookup.h @@ -6,32 +6,35 @@ #ifndef PORTLOOKUP_H #define PORTLOOKUP_H -#include +#include namespace sysadm { -namespace PortLookUp +const static int recommendedPorts[] = {22, 80}; +const static int recommendedPortsSize = 2; +class PortLookUp { - static int recommendedPorts[] = {5,22}; - const int recommendedPortListSize = 2; - struct PortInfo{ int Port; QString Keyword; QString Description; bool Recommended; }; - +public: /** * @description Returns a structure containing information about the port * including its port type, keyword, description, and whether it's a * recommended port * - * @parameter portNumber a port number between 1 and 2^16 + * @parameter portNumber a port number between 0 and 2^16 - 1 * * @ErrorConditions Port Number is set to -1 and a description of the error is stored in the description variable */ - static PortInfo LookUpPort(int portNumber); -} + PortInfo LookUpPort(int portNumber); + +private: + void readServicesFile(); + QStringList* portStrings; +}; } #endif // PORTLOOKUP_H From bdac469ed33a4b36507b48bd5d01ec8e1a98d576 Mon Sep 17 00:00:00 2001 From: Luke De Mouy Date: Thu, 7 Jan 2016 03:39:50 -0700 Subject: [PATCH 3/7] remove unnecessary include, delete the QFile once we're done with it. Add in a constructor that initializes the port cache, and add in a destructor to delete the cache if portlookup is deleted. --- src/library/portlookup.cpp | 13 ++++++++++++- src/library/portlookup.h | 1 + 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/library/portlookup.cpp b/src/library/portlookup.cpp index 6365b96..dfd12e4 100644 --- a/src/library/portlookup.cpp +++ b/src/library/portlookup.cpp @@ -1,6 +1,6 @@ #include "portlookup.h" #include -#include + using namespace sysadm; PortLookUp::PortInfo PortLookUp::LookUpPort(int portNumber) { @@ -67,6 +67,16 @@ PortLookUp::PortInfo PortLookUp::LookUpPort(int portNumber) } +PortLookUp::PortLookUp() +{ + readServiceFile(); +} + +PortLookUp::~PortLookUp() +{ + delete portStrings; +} + void PortLookUp::readServicesFile() { portStrings = new QStringList(); @@ -88,5 +98,6 @@ void PortLookUp::readServicesFile() portStrings->append(line); } services->close(); + delete services; } diff --git a/src/library/portlookup.h b/src/library/portlookup.h index 9638ba1..4ac4c9b 100644 --- a/src/library/portlookup.h +++ b/src/library/portlookup.h @@ -30,6 +30,7 @@ public: * @ErrorConditions Port Number is set to -1 and a description of the error is stored in the description variable */ PortInfo LookUpPort(int portNumber); + ~PortLookUp(); private: void readServicesFile(); From 26f51d6822e21f7e1396e0909a9270ae4211c95e Mon Sep 17 00:00:00 2001 From: Luke De Mouy Date: Thu, 7 Jan 2016 16:42:11 -0700 Subject: [PATCH 4/7] Make portlookup take the port type into consideration when checking the port --- src/library/portlookup.cpp | 11 +++++------ src/library/portlookup.h | 3 ++- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/library/portlookup.cpp b/src/library/portlookup.cpp index dfd12e4..ecc2b37 100644 --- a/src/library/portlookup.cpp +++ b/src/library/portlookup.cpp @@ -2,7 +2,7 @@ #include using namespace sysadm; -PortLookUp::PortInfo PortLookUp::LookUpPort(int portNumber) +PortLookUp::PortInfo PortLookUp::LookUpPort(int portNumber, QString portType) { //Make sure that the port is valid if (portNumber < 0 || portNumber > 65535) @@ -35,13 +35,12 @@ PortLookUp::PortInfo PortLookUp::LookUpPort(int portNumber) //Check to see if the port number is listed. The format in the file // is portname/portType. ex.: 22/tcp - QStringList port = portStrings->filter(QRegExp("/\\b("+QString::number(portNumber)+"\\/)/g")); + QStringList port = portStrings->filter(QRegExp("/\\b("+QString::number(portNumber)+"\\/"+portType.toLower()+")/g")); if(port.size() > 0) { - //grab the first one since any duplicates are just other port - //types for the same port, usually associated with the same - //application and we're not tracking that + //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); //Split across spaces since it's whitespace delimited @@ -69,7 +68,7 @@ PortLookUp::PortInfo PortLookUp::LookUpPort(int portNumber) PortLookUp::PortLookUp() { - readServiceFile(); + readServicesFile(); } PortLookUp::~PortLookUp() diff --git a/src/library/portlookup.h b/src/library/portlookup.h index 4ac4c9b..91b5d31 100644 --- a/src/library/portlookup.h +++ b/src/library/portlookup.h @@ -29,7 +29,8 @@ public: * * @ErrorConditions Port Number is set to -1 and a description of the error is stored in the description variable */ - PortInfo LookUpPort(int portNumber); + PortInfo LookUpPort(int portNumber, QString portType); + PortLookUp(); ~PortLookUp(); private: From 5cc11be9e678db693c0e084d105b44277da88d6e Mon Sep 17 00:00:00 2001 From: Luke De Mouy Date: Thu, 7 Jan 2016 16:55:04 -0700 Subject: [PATCH 5/7] add the port type to the PortInfo struct --- src/library/portlookup.cpp | 8 +++++++- src/library/portlookup.h | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/library/portlookup.cpp b/src/library/portlookup.cpp index ecc2b37..b091e65 100644 --- a/src/library/portlookup.cpp +++ b/src/library/portlookup.cpp @@ -22,6 +22,12 @@ PortLookUp::PortInfo PortLookUp::LookUpPort(int portNumber, QString portType) //the port number is valid so set it returnValue.Port = portNumber; + //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; + //Check to see if it's a recommended port returnValue.Recommended = false; for(int i = 0; i < recommendedPortsSize; i++) @@ -35,7 +41,7 @@ PortLookUp::PortInfo PortLookUp::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(QRegExp("/\\b("+QString::number(portNumber)+"\\/"+portType.toLower()+")/g")); + QStringList port = portStrings->filter(QRegExp("/\\b("+QString::number(portNumber)+"\\/"+portType+")/g")); if(port.size() > 0) { diff --git a/src/library/portlookup.h b/src/library/portlookup.h index 91b5d31..b3ebdab 100644 --- a/src/library/portlookup.h +++ b/src/library/portlookup.h @@ -15,6 +15,7 @@ class PortLookUp { struct PortInfo{ int Port; + QString PortType; QString Keyword; QString Description; bool Recommended; From fb508a83520da9be5ecd2c36bbff6c06eb26f6ca Mon Sep 17 00:00:00 2001 From: Luke De Mouy Date: Sat, 9 Jan 2016 13:00:23 -0700 Subject: [PATCH 6/7] Move PortInfo struct out of PortLookUp class, and fiddled with the regex to make it actually work based on testing. The filter operation now will pickup things like 522/tcp in the QStringList if you're searching for 22/tcp, but testing seems to indicate that just taking the first one in the list works for getting what we want. --- src/library/portlookup.cpp | 6 ++---- src/library/portlookup.h | 16 +++++++++------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/library/portlookup.cpp b/src/library/portlookup.cpp index b091e65..52756b9 100644 --- a/src/library/portlookup.cpp +++ b/src/library/portlookup.cpp @@ -1,8 +1,7 @@ #include "portlookup.h" #include - using namespace sysadm; -PortLookUp::PortInfo PortLookUp::LookUpPort(int portNumber, QString portType) +PortInfo PortLookUp::LookUpPort(int portNumber, QString portType) { //Make sure that the port is valid if (portNumber < 0 || portNumber > 65535) @@ -41,8 +40,7 @@ PortLookUp::PortInfo PortLookUp::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(QRegExp("/\\b("+QString::number(portNumber)+"\\/"+portType+")/g")); - + QStringList port = portStrings->filter(QString::number(portNumber) + "/" + portType); if(port.size() > 0) { //grab the first one, there may be duplicates due to colliding ports in the /etc/services file diff --git a/src/library/portlookup.h b/src/library/portlookup.h index b3ebdab..6ccb58d 100644 --- a/src/library/portlookup.h +++ b/src/library/portlookup.h @@ -9,17 +9,19 @@ #include namespace sysadm { +struct PortInfo{ + int Port; + QString PortType; + QString Keyword; + QString Description; + bool Recommended; +}; + const static int recommendedPorts[] = {22, 80}; const static int recommendedPortsSize = 2; class PortLookUp { - struct PortInfo{ - int Port; - QString PortType; - QString Keyword; - QString Description; - bool Recommended; - }; + public: /** * @description Returns a structure containing information about the port From a326c3f8112649e63481030faadc05428686c05c Mon Sep 17 00:00:00 2001 From: Luke De Mouy Date: Mon, 11 Jan 2016 12:22:54 -0700 Subject: [PATCH 7/7] renamed PortLookUp to firewall, and the files to sysadm-firewall --- src/library/library.pro | 4 ++-- src/library/{portlookup.cpp => sysadm-firewall.cpp} | 10 +++++----- src/library/{portlookup.h => sysadm-firewall.h} | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) rename src/library/{portlookup.cpp => sysadm-firewall.cpp} (94%) rename src/library/{portlookup.h => sysadm-firewall.h} (95%) diff --git a/src/library/library.pro b/src/library/library.pro index 31547dc..e599734 100644 --- a/src/library/library.pro +++ b/src/library/library.pro @@ -14,13 +14,13 @@ HEADERS += sysadm-global.h \ sysadm-general.h \ sysadm-lifepreserver.h \ sysadm-network.h \ - portlookup.h + sysadm-firewall.h SOURCES += sysadm-general.cpp \ sysadm-lifepreserver.cpp \ sysadm-network.cpp \ NetDevice.cpp \ - portlookup.cpp + sysadm-firewall.cpp include.path=/usr/local/include/ include.files=sysadm-*.h diff --git a/src/library/portlookup.cpp b/src/library/sysadm-firewall.cpp similarity index 94% rename from src/library/portlookup.cpp rename to src/library/sysadm-firewall.cpp index 52756b9..3efd387 100644 --- a/src/library/portlookup.cpp +++ b/src/library/sysadm-firewall.cpp @@ -1,7 +1,7 @@ -#include "portlookup.h" +#include "sysadm-firewall.h" #include using namespace sysadm; -PortInfo PortLookUp::LookUpPort(int portNumber, QString portType) +PortInfo Firewall::LookUpPort(int portNumber, QString portType) { //Make sure that the port is valid if (portNumber < 0 || portNumber > 65535) @@ -70,17 +70,17 @@ PortInfo PortLookUp::LookUpPort(int portNumber, QString portType) } -PortLookUp::PortLookUp() +Firewall::Firewall() { readServicesFile(); } -PortLookUp::~PortLookUp() +Firewall::~Firewall() { delete portStrings; } -void PortLookUp::readServicesFile() +void Firewall::readServicesFile() { portStrings = new QStringList(); diff --git a/src/library/portlookup.h b/src/library/sysadm-firewall.h similarity index 95% rename from src/library/portlookup.h rename to src/library/sysadm-firewall.h index 6ccb58d..dbdccae 100644 --- a/src/library/portlookup.h +++ b/src/library/sysadm-firewall.h @@ -19,7 +19,7 @@ struct PortInfo{ const static int recommendedPorts[] = {22, 80}; const static int recommendedPortsSize = 2; -class PortLookUp +class Firewall { public: @@ -33,8 +33,8 @@ public: * @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); - PortLookUp(); - ~PortLookUp(); + Firewall(); + ~Firewall(); private: void readServicesFile();