Ver código fonte

Implemented updating of identity file.

Implement unit test of Utility::ReplaceXmlAttribute() in
TestUtility.cpp.


git-svn-id: https://svn.microneil.com/svn/SNFUtility/trunk@17 aa37657e-1934-4a5f-aa6d-2d8eab27ff7c
master
adeniz 12 anos atrás
pai
commit
b15b3d2aa9

+ 146
- 0
Common/Utility.cpp Ver arquivo

@@ -249,6 +249,152 @@ Utility::MkDir(std::string &Dir) {
}
void
Utility::ReplaceXmlAttribute(std::string *Content, std::string ElementName, std::string AttributeName, std::string AttributeValue) {
std::string::size_type ElementContentBegin; // Index of start of the element content.
std::string::size_type ElementContentEnd; // One past the end of the element content.
ElementContentBegin = Content->find("<" + ElementName); // Get indices of element content.
ElementContentEnd = Content->find("</" + ElementName);
if (std::string::npos == ElementContentBegin) {
std::string Temp;
Temp = "Unable to find the start of element '" + ElementName;
Temp += "'.";
throw std::runtime_error(Temp);
}
if (std::string::npos != Content->find("<" + ElementName, ElementContentBegin + 1)) {
std::string Temp;
Temp = "Found two elements named '" + ElementName;
Temp += "'; there must be only one.";
throw std::runtime_error(Temp);
}
if (std::string::npos == ElementContentEnd) {
ElementContentEnd = Content->find("/>", ElementContentBegin);
}
if (std::string::npos == ElementContentEnd){
std::string Temp;
Temp = "Unable to find the end of element '" + ElementName;
Temp += "'.";
throw std::runtime_error(Temp);
}
ElementContentBegin += ElementName.length() + 1; // Skip element name.
std::string::size_type ProvisionalAttributeNameBegin = ElementContentBegin;
std::string::size_type AttributeNameBegin ;
bool FoundAttribute = false;
std::string PrevChar;
while (ProvisionalAttributeNameBegin < ElementContentEnd) { // Find start of attribute name.
ProvisionalAttributeNameBegin = Content->find(AttributeName, ProvisionalAttributeNameBegin);
if ( (ProvisionalAttributeNameBegin == std::string::npos) || (ProvisionalAttributeNameBegin >= ElementContentEnd) ) {
break;
}
PrevChar = Content->at(ProvisionalAttributeNameBegin - 1);
if (std::string::npos == PrevChar.find_first_not_of(" \t\r\n")) { // Check for whitespace before the attribute.
if (FoundAttribute) {
std::string Temp;
Temp = "Found two attributes named '" + AttributeName;
Temp += "' in element '" + ElementName;
Temp += "'; there must be only one.";
throw std::runtime_error(Temp);
}
FoundAttribute = true;
AttributeNameBegin = ProvisionalAttributeNameBegin;
}
ProvisionalAttributeNameBegin = ProvisionalAttributeNameBegin + AttributeName.length(); // Skip.
}
if (!FoundAttribute) {
std::string Temp;
Temp = "Unable to find the attribute '" + AttributeName;
Temp += "' in element '" + ElementName;
Temp += "'.";
throw std::runtime_error(Temp);
}
std::string::size_type EqualIndex; // Index of "=".
std::string::size_type DelimiterIndex; // Index of delimiter of attribute value.
std::string DelimiterValue; // Attribute value delimiter value.
std::string::size_type AttributeValueBegin; // Index of start of attribute value.
std::string::size_type AttributeValueEnd; // One past the end of the attribute value.
EqualIndex = // Get index of first delimiter.
Content->find_first_not_of(" \t\r\n", AttributeNameBegin + AttributeName.length());
if ( (EqualIndex == std::string::npos) || (EqualIndex >= ElementContentEnd) ) {
std::string Temp;
Temp = "Unable to find \"=\" after '" + AttributeName;
Temp += "' in element '" + ElementName;
Temp += "'.";
throw std::runtime_error(Temp);
}
DelimiterIndex = // Get index of first delimiter.
Content->find_first_not_of(" \t\r\n", EqualIndex + 1);
if ( (DelimiterIndex == std::string::npos) || (DelimiterIndex >= ElementContentEnd) ) {
std::string Temp;
Temp = "Unable to find start of value of attribute '" + AttributeName;
Temp += "' in element '" + ElementName;
Temp += "'.";
throw std::runtime_error(Temp);
}
DelimiterValue = Content->at(DelimiterIndex);
AttributeValueBegin = DelimiterIndex + 1;
AttributeValueEnd = Content->find(DelimiterValue, AttributeValueBegin);
if ( (AttributeValueEnd == std::string::npos) || (AttributeValueEnd >= ElementContentEnd) ) {
std::string Temp;
Temp = "Unable to find the end of the value of '" + AttributeName;
Temp += "' in element '" + ElementName;
Temp += "'.";
throw std::runtime_error(Temp);
}
Content->replace(AttributeValueBegin,
AttributeValueEnd - AttributeValueBegin,
"");
Content->insert(AttributeValueBegin, AttributeValue);
}
bool
Utility::CheckForString(std::string Line, std::string SearchString) {

+ 14
- 0
Common/Utility.hpp Ver arquivo

@@ -83,6 +83,20 @@ public:
//
static bool CheckForString(std::string Line, std::string SearchString);
/// Replace an XML attribute.
//
// Replace the specified XML element attribute with the specified value.
//
// \param[in, out] Content is the XML content containing the element.
//
// \param[in] ElementName is the name of the XML element.
//
// \param[in] AttributeName is the name of the XML attribute.
//
// \param[in] AttributeValue is the new value of the XML attribute.
//
static void ReplaceXmlAttribute(std::string *Content, std::string ElementName, std::string AttributeName, std::string AttributeValue);
/// Trim whitespace from a string.
//
// This method removes leading " ", "\t", "\r", and "\n" from the specified string.

+ 232
- 93
Common/UtilityConfig.cpp Ver arquivo

@@ -131,12 +131,16 @@ const string SuccessKey("Success");
const string LicenseSearchString = "LICENSE_ID=";
const string AuthSearchString = "AUTHENTICATION=";
const string IdentityElementName = "identity";
const string LicenseAttributeName = "licenseid";
const string AuthenticationAttributeName = "authentication";
//////////////////////////////////////////////////////////////////////////////////////////////////////////
// End of configuration. /////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////
UtilityConfig::UtilityConfig() :
LicenseIdIsSpecified(false), AuthenticationIsSpecified(false), ConfigFileExists(true)
LicenseIdIsSpecified(false), AuthenticationIsSpecified(false)
{
SetExplain(false);
@@ -176,7 +180,6 @@ UtilityConfig::CheckAndSetConfigFileName(const std::string DefaultFile[], int Nu
if (NumDefaultFiles > 0) {
ProvisionalConfigFile = DefaultFile[0]; // Use the first default file.
ConfigFileExists = false;
} else { // No default config file was specified.
@@ -203,16 +206,8 @@ UtilityConfig::CheckAndSetConfigFileName(const std::string DefaultFile[], int Nu
throw runtime_error(Temp);
} else {
ConfigFileExists = true; // Config file was found.
}
} else {
ConfigFileExists = FileExists(ProvisionalConfigFile);
}
SetConfigFileName(ProvisionalConfigFile);
@@ -224,27 +219,22 @@ UtilityConfig::CreateDefaultConfigFile(std::string SampleConfigFile) {
std::string File = GetConfigFileName();
if (!ConfigFileExists) {
// Create the config file.
Copy(SampleConfigFile, File);
}
}
if (!FileExists(File)) {
void
UtilityConfig::CreateDefaultIdentityFile(std::string SampleIdentityFile) {
if (!Explain()) {
std::string File = GetIdentityFileName();
SaveFile.CreateBackupFile(File);
if (!FileExists(File)) {
}
// Create the config file.
Copy(SampleIdentityFile, File);
Copy(SampleConfigFile, File);
}
SetMode(File, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); // Set permissions.
SetOwnerGroup(File); // Set to sniffer user.
}
void
@@ -421,63 +411,91 @@ UtilityConfig::LoadInfo(){
}
void
UtilityConfig::UpdateIgnoreListFile() {
UtilityConfig::SetupRepairIdentityFile(std::string SampleIdentityFile) {
string IgnoreListFile = GetIgnoreListFileName();
std::string File = GetIdentityFileName();
if (!FileExists(IgnoreListFile)) {
if (!FileExists(File)) {
Copy(SampleIgnoreListFile, IgnoreListFile);
if (!Explain()) {
}
SaveFile.CreateBackupFile(File);
SetMode(IgnoreListFile, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); // Set permissions.
SetOwnerGroup(IgnoreListFile); // Set to sniffer user.
}
// Create the config file.
Copy(SampleIdentityFile, File);
}
}
void
UtilityConfig::UpdateLogDir() {
UtilityConfig::SetupRepairRulebaseScript() {
string LogDir = GetLogPath();
std::string File = GetRulebaseScriptName();
if (!FileExists(LogDir)) {
if (!FileExists(File)) {
MkDir(LogDir);
if (!Explain()) {
SaveFile.CreateBackupFile(File);
}
Copy(SampleRulebaseScriptFile, File); // Copy if !Explain().
}
SetMode(LogDir, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
SetOwnerGroup(LogDir);
SetMode(File, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); // Set permissions.
}
bool
UtilityConfig::UpdateCredentialsSpecified() {
void
UtilityConfig::SetupRepairIgnoreListFile() {
return ( (LicenseId.length() > 0) && (Authentication.length() > 0) );
string IgnoreListFile = GetIgnoreListFileName();
}
if (!FileExists(IgnoreListFile)) {
if (!Explain()) {
SaveFile.CreateBackupFile(File);
}
Copy(SampleIgnoreListFile, IgnoreListFile);
}
SetMode(IgnoreListFile, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); // Set permissions.
SetOwnerGroup(IgnoreListFile); // Set to sniffer user.
}
void
UtilityConfig::CreateUpdateRulebaseScript() {
UtilityConfig::SetupRepairLogDir() {
std::string File = GetRulebaseScriptName();
string LogDir = GetLogPath();
if (!FileExists(File)) {
if (!FileExists(LogDir)) {
Copy(SampleRulebaseScriptFile, File); // Copy if !Explain().
MkDir(LogDir);
}
if (UpdateCredentialsSpecified()) {
SetMode(LogDir, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
SetOwnerGroup(LogDir);
UpdateRulebaseScriptCredentials();
}
}
void
SNFMilterConfig::SetupRepair(std::string SampleIdentityFile) {
SetMode(File, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); // Set permissions.
SetupRepairIdentityFile(SampleIdentityFile);
SetupRepairRulebaseScript();
SetupRepairIgnoreListFile();
SetupRepairLogDir();
}
@@ -590,6 +608,8 @@ UtilityConfig::UpdateRulebaseScriptCredentials() {
if (!Explain()) {
SaveFile.CreateBackupFile(File);
ofstream Output; // Write the updated contents.
Output.open(File.c_str(), ios::trunc);
@@ -631,12 +651,6 @@ UtilityConfig::UpdateRulebaseScriptCredentials() {
void
UtilityConfig::DownloadRulebase() {
if (!UpdateCredentialsSpecified()) {
return;
}
if (Verbose()) {
std::cout << "Downloading the rulebase...";
@@ -678,6 +692,8 @@ UtilityConfig::DownloadRulebase() {
if (!Explain()) {
SaveFile.CreateBackupFile(GetRulebaseFileName()); // Save the current rulebase file.
if (0 != remove(StatusFile.c_str())) { // Delete the status file.
if (ENOENT != errno) { // No error if the file doesn't exist.
@@ -743,62 +759,169 @@ UtilityConfig::UpdateIdentityFile() {
std::string File = GetIdentityFileName();
if (UpdateCredentialsSpecified()) {
if (Verbose()) {
cout << "Update authentication and license ID in the identity file " << File << "--\n";
}
ifstream Input;
Input.open(File.c_str()); // Read the contents.
if (!Input) {
string Temp;
Temp = "Error opening identity file " + File;
Temp += " for reading: ";
Temp += strerror(errno);
throw runtime_error(Temp);
}
ostringstream InputContents;
if (!Input.eof()) { // Copy if there are characters.
// Copying an empty file causes
InputContents << Input.rdbuf(); // failbit to be set.
}
if (InputContents.bad() || InputContents.fail()) {
std::string Temp;
Temp = "Error reading identity file " + File;
throw std::runtime_error(Temp);
}
Input.close();
if (Input.bad()) {
string Temp;
Temp = "Error closing the identity file " + File;
Temp += " after reading: ";
Temp += strerror(errno);
throw runtime_error(Temp);
}
string Content = InputContent.str();
try {
ReplaceXmlAttribute(&Content, IdentityElementName, LicenseAttributeName, LicenseId);
ReplaceXmlAttribute(&Content, IdentityElementName, AuthenticationAtributeName, Authentication);
} catch (std::exception &e) {
std::string Temp;
Temp = "Error updating credentials for identity file " + File;
Temp += ": " + e.what();
throw runtime_error(Temp);
}
if (!Explain()) {
SaveFile.CreateBackupFile(File);
ofstream Output;
if (Verbose()) {
Output.open(File.c_str(), ios::trunc);
if (!Output) {
string Temp;
cout << "Create identity file " << File << "...";
Temp = "Error opening identity file " + File;
Temp += " for writing: ";
Temp += strerror(errno);
throw runtime_error(Temp);
}
Output << Content;
if (!Output) {
string Temp;
Temp = "Error writing the identity file " + File;
Temp += ": ";
Temp += strerror(errno);
throw runtime_error(Temp);
}
if (!Explain()) {
Output.close();
if (!Output) {
string Temp;
Output.open(File.c_str());
if (!Output) {
string Temp;
Temp = "Error closing the identity file " + File;
Temp += " after writing: ";
Temp += strerror(errno);
throw runtime_error(Temp);
}
Temp = "Error opening identity file " + File;
Temp += ": ";
Temp += strerror(errno);
throw runtime_error(Temp);
}
}
Output << "<!-- License file created by SNFIdentity-->\n"
<< "<snf>\n"
<< " <identity licenseid='" << LicenseId << "' authentication='"
<< Authentication << "'/>\n"
<< "</snf>\n";
if (!Output) {
string Temp;
OutputVerboseEnd();
Temp = "Error writing identity file " + File;
Temp += ": ";
Temp += strerror(errno);
throw runtime_error(Temp);
}
}
Output.close();
if (!Output) {
string Temp;
#if 0
void
UtilityConfig::UpdateIdentityFileOld() {
Temp = "Error closing identity file " + File;
Temp += ": ";
Temp += strerror(errno);
throw runtime_error(Temp);
}
std::string File = GetIdentityFileName();
ofstream Output;
if (Verbose()) {
cout << "Create identity file " << File << "...";
}
if (!Explain()) {
SaveFile.CreateBackupFile(File);
Output.open(File.c_str());
if (!Output) {
string Temp;
Temp = "Error opening identity file " + File;
Temp += ": ";
Temp += strerror(errno);
throw runtime_error(Temp);
}
OutputVerboseEnd();
Output << "<!-- License file created by SNFIdentity-->\n"
<< "<snf>\n"
<< " <identity licenseid='" << LicenseId << "' authentication='"
<< Authentication << "'/>\n"
<< "</snf>\n";
if (!Output) {
string Temp;
Temp = "Error writing identity file " + File;
Temp += ": ";
Temp += strerror(errno);
throw runtime_error(Temp);
}
Output.close();
if (!Output) {
string Temp;
Temp = "Error closing identity file " + File;
Temp += ": ";
Temp += strerror(errno);
throw runtime_error(Temp);
}
}
OutputVerboseEnd();
SetOwnerGroup(File); // Set the user and group.
SetMode(File, S_IRUSR); // Set to readonly by owner.
}
#endif
void
UtilityConfig::StartSniffer(std::string Script) {
@@ -907,12 +1030,17 @@ UtilityConfig::CommandLineIsOkay() {
}
std::string
UtilityConfig::HelpCommandLine() {
UtilityConfig::HelpCommandLine(std::string ExclusiveCommandsHelp) {
std::string Help;
Help = "[" + ConfigFileKey + "snf-config-file] ";
Help += "[" + LicenseIdKey + "licenseid " + AuthenticationKey + "authentication] ";
Help = SetupKey + " | ";
Help += RepairKey + " | ";
Help += ExclusiveCommandsHelp + " | ";
Help += LicenseIdKey + "licenseid " + AuthenticationKey + "authentication | ";
Help += StartSnifferKey + " | ";
Help += StopSnifferKey + " ";
Help += "[" + ConfigFileKey + "snf-config-file] ";
Help += "[ " + VerboseKey + " " + ExplainKey + " ]";
return Help;
@@ -920,11 +1048,15 @@ UtilityConfig::HelpCommandLine() {
}
std::string
UtilityConfig::HelpDescription() {
UtilityConfig::HelpDescription(std::string ExclusiveCommandsHelp) {
std::string Desc;
Desc = " -config=snf-config-file Specifies the configuration file\n";
Desc = "creates the configuration files (snf-config-file and the\n";
Desc += "ignore list file), the rulebase download script (default: getRulebase) if\n";
Desc += "they don't exist, and also the identity file.\n\n";
Desc += ExclusiveCommandsHelp;
Desc += " -config=snf-config-file Specifies the configuration file\n";
Desc += " -id=licenseid Specifies the license ID\n";
Desc += " -auth=authentication Specifies the Authentication\n";
Desc += " -v Provide verbose output\n";
@@ -934,7 +1066,6 @@ UtilityConfig::HelpDescription() {
return Desc;
}
void
UtilityConfig::SetSetupRepair(bool Specified) {
@@ -949,6 +1080,14 @@ UtilityConfig::SetupRepairSpecified() {
}
bool
UtilityConfig::UpdateCredentialsSpecified() {
return ( (LicenseId.length() > 0) && (Authentication.length() > 0) );
}
void
UtilityConfig::SetStartSniffer(bool Specified) {

+ 83
- 66
Common/UtilityConfig.hpp Ver arquivo

@@ -32,7 +32,7 @@ public:
};
/// Default constructor.
UtilityConfig();
UtilityConfig(void);
/// Object to back up and restore files.
FileBackup SaveFile;
@@ -55,7 +55,7 @@ public:
void CheckAndSetConfigFileName(const std::string DefaultFile[], int NumDefaultFiles);
/// If the configuration file doesn't exist, create it from the
/// sample file.
/// sample file. In any case, set the owner and mode.
//
// This method creates the default configuration file if the
// specified configuration file doesn't exist.
@@ -68,19 +68,11 @@ public:
//
void CreateDefaultConfigFile(std::string SampleConfigFile);
/// If the identity file doesn't exist, create it from the sample
/// file.
/// Setup/repair the configuration.
//
// This method creates the default identity file if the identity
// file specified in the configuration file doesn't exist.
//
// The method CheckAndSetConfigFileName must be called before this
// method.
//
// \param[in] SampleIdentityFile is the name of the sample
// identity file.
//
void CreateDefaultIdentityFile(std::string SampleIdentityFile);
// This method creates any configuration files that don't exist
// from the sample files.
void SetupCreate(void);
/// Load the configuration from the file specified by SetConfigFileName.
//
@@ -140,7 +132,7 @@ public:
//
// \returns the name of the rulebase file, including the path.
//
std::string GetRulebaseFileName();
std::string GetRulebaseFileName(void);
/// Get the operating system type.
//
@@ -164,7 +156,7 @@ public:
// This method updates the public members that contain the OS
// specification and file paths.
//
void LoadInfo();
void LoadInfo(void);
/// Postfix main.cf file path.
std::string PostfixMainCfPath;
@@ -175,48 +167,16 @@ public:
/// Directory containing the Sniffer start script.
std::string SnifferStartScriptDir;
/// Create or update the ignore list file.
//
// The ignore list file is created if it dosn't exist. In any
// case, the owner/group is changed by SetOwnerGroup(), and the
// permissions are changed to readonly for everyone, and
// read/write for the owner.
void UpdateIgnoreListFile();
/// Create or update the log directory.
//
// The log directory is created if it dosn't exist. In any case,
// the owner/group is changed by SetOwnerGroup(), and the
// permissions are changed to r-x for everyone, and rwx for the
// owner.
void UpdateLogDir();
/// Determine whether the credentials should be updated.
//
// This method determines whether the credentials should be
// updated. If the user specified both the License ID and
// Authentication, then the credentials should be updated.
//
// \returns true if the credentials should be updated.
//
bool UpdateCredentialsSpecified();
/// Create or update the rulebase script.
/// Update the rulebase script credentials.
//
// If the rulebase script doesn't exist, this method creates the
// rulebase script from the sample rulebase script.
//
// If the credentials were supplied, this method updates the
// rulebase with the supplied credentials.
// This method updates the rulebase with the credentials specified
// on the command line.
//
// In either case, the permissions of the rulebase script are
// updated.
//
void CreateUpdateRulebaseScript();
void UpdateRulebaseScriptCredentials(void);
/// Download the rulebase.
//
void DownloadRulebase();
void DownloadRulebase(void);
/// Update the identity file.
//
@@ -261,13 +221,23 @@ public:
//
// \returns if the command-line parameters were specified
// correctly, false otherwise.
bool CommandLineIsOkay();
bool CommandLineIsOkay(void);
/// Output the legal command-line input.
std::string HelpCommandLine();
//
// \param[in] ExclusiveCommands contains the command-line help of
// the additional commands implemented by the descendent classes.
// Only one command may be specified when invoking the
// configuration utility.
//
std::string HelpCommandLine(std::string ExclusiveCommands);
/// Output the description of the legal command-line input.
std::string HelpDescription();
//
// \param[in] ExclusiveCommandsHelp contains the description of
// the additional commands implemented by the descendent classes.
//
std::string HelpDescription(std::string ExclusiveCommandsHelp);
/// Store whether the setup/help command was specified.
//
@@ -279,7 +249,17 @@ public:
//
// \returns true if the setup/help command was specified on the command line.
//
bool SetupRepairSpecified();
bool SetupRepairSpecified(void);
/// Determine whether the credentials should be updated.
//
// This method determines whether the credentials should be
// updated. If the user specified both the License ID and
// Authentication, then the credentials should be updated.
//
// \returns true if the credentials should be updated.
//
bool UpdateCredentialsSpecified(void);
/// Store whether the start sniffer command was specified.
//
@@ -291,7 +271,7 @@ public:
//
// \returns true if the start sniffer command was specified on the command line.
//
bool StartSnifferSpecified();
bool StartSnifferSpecified(void);
/// Store whether the stop sniffer command was specified.
//
@@ -303,23 +283,60 @@ public:
//
// \returns true if the stop sniffer command was specified on the command line.
//
bool StopSnifferSpecified();
bool StopSnifferSpecified(void);
private:
/// Update the credentials of an existing rulebase script.
/// Setup/repair the identity file.
//
// If the identity file doesn't exist, create it from the sample
// file.
//
// In any case, set the owner and permissions of the identity
// file.
//
// This method does the actual work of updating the credentials of
// the rulebase script.
// \param[in] SampleIdentityFile is the name of the sample
// identity file.
//
// \pre The rulebase script file must exist.
// \note The configuration information must be loaded before calling this method.
//
// Side effect: The rulebase script is updated.
// \see CheckAndSetConfigFileName.
//
void UpdateRulebaseScriptCredentials();
// \see CreateDefaultConfigFile.
//
// \see LoadConfig.
//
// \see LoadInfo.
//
void SetupRepairIdentityFile(std::string SampleIdentityFile);
/// Setup/repair the rulebase script.
//
// If the rulebase script doesn't exist, this method creates the
// rulebase script from the sample rulebase script.
//
// In any case, set the owner and permissions of the rulebase
// script.
//
void SetupRepairRulebaseScript(void);
/// Setup/repair the ignore list file.
//
// The ignore list file is created if it dosn't exist. In any
// case, the owner/group is changed by SetOwnerGroup(), and the
// permissions are changed to readonly for everyone, and
// read/write for the owner.
void SetupRepairIgnoreListFile(void);
/// Setup/repair the log directory.
//
// The log directory is created if it dosn't exist. In any case,
// the owner/group is changed by SetOwnerGroup(), and the
// permissions are changed to r-x for everyone, and rwx for the
// owner.
void SetupRepairLogDir(void);
std::string ConfigFileName; ///< Configuration file name.
bool ConfigFileExists; ///< True if the configuration file exists.
std::string LicenseId; ///< License ID string.
bool LicenseIdIsSpecified; ///< true if the License ID was specified on the command line.
std::string Authentication; ///< Authentication string.

+ 8
- 2
CommonTests/Makefile.am Ver arquivo

@@ -14,14 +14,20 @@
CXXFLAGS = $(SNF_CXXFLAGS) -I@top_srcdir@/SNFUtility/Common

TESTS = \
TestFileBackup
TestFileBackup \
TestUtility

check_PROGRAMS = \
TestFileBackup
TestFileBackup \
TestUtility

TestFileBackup_SOURCES = \
TestFileBackup.cpp \
@top_srcdir@/SNFUtility/Common/FileBackup.cpp

TestUtility_SOURCES = \
TestUtility.cpp \
@top_srcdir@/SNFUtility/Common/Utility.cpp

clean-local:
rm -f *.gcno *.gcov *.gcda *~

+ 399
- 0
CommonTests/TestUtility.cpp Ver arquivo

@@ -0,0 +1,399 @@
// $Id$
//
// \file TestUtility.cpp
//
// Copyright (C) 2012, ARM Research Labs, LLC.
// See www.armresearch.com for the copyright terms.
//
// This is the unit test for the class Utility.
//
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <cstdlib>
#include <cstring>
#include <cerrno>
#include "Utility.hpp"
/// Output error.
#define Error(msg) \
{ \
std::cerr << "In file " << __FILE__ << ":" << __LINE__ << ": "; \
std::cerr << msg; \
}
/// Exit with error.
#define ErrorExit(msg) \
{ \
Error(msg) \
std::exit(-1); \
}
bool
TestReplaceXmlAttribute() {
std::string Content;
std::string ExpectedContent;
std::string ElementName = "TestElement";
std::string AttributeName = "TestAttribute";
std::string AttributeNewValue = "NewValue";
// Test with valid input.
std::string OriginalContent;
Content = "<!-- License file created by SNFIdentity-->\n"
"<snf>\n"
"<TestElement TestAttribute='testmode' authentication='setuptestingonly'/>\n"
"<TestXXX XXXAttribute='testmode' authentication='setuptestingonly'/>\n"
"</snf>\n";
OriginalContent = Content;
ExpectedContent = "<!-- License file created by SNFIdentity-->\n"
"<snf>\n"
"<TestElement TestAttribute='NewValue' authentication='setuptestingonly'/>\n"
"<TestXXX XXXAttribute='testmode' authentication='setuptestingonly'/>\n"
"</snf>\n";
try {
Utility::ReplaceXmlAttribute(&Content, ElementName, AttributeName, AttributeNewValue);
} catch (std::exception &e) {
std::string Temp;
Temp = "TestReplaceXmlAttribute: Exception thrown with valid input: ";
Temp += e.what();
Temp += "\n\nOriginal Content:\n\n";
Temp += OriginalContent + "\n";
Error(Temp);
return false;
}
if (Content != ExpectedContent) {
std::string Temp;
Temp = "TestReplaceXmlAttribute: Incorrect result with valid input. Content after replacement:\n\n";
Temp += Content;
Temp += "\n\nExpected:\n\n";
Temp += ExpectedContent + "\n";
Error(Temp);
return false;
}
Content = "<!-- License file created by SNFIdentity-->\n"
"<snf>\n"
"<TestElement TestAttribute\n\t= \n\t\t 'testmode' authentication='setuptestingonly'>\n"
"</TestElement>"
"</snf>\n";
OriginalContent = Content;
ExpectedContent = "<!-- License file created by SNFIdentity-->\n"
"<snf>\n"
"<TestElement TestAttribute\n\t= \n\t\t 'NewValue' authentication='setuptestingonly'>\n"
"</TestElement>"
"</snf>\n";
try {
Utility::ReplaceXmlAttribute(&Content, ElementName, AttributeName, AttributeNewValue);
} catch (std::exception &e) {
std::string Temp;
Temp = "TestReplaceXmlAttribute: Exception thrown with valid input: ";
Temp += e.what();
Temp += "\n\nOriginal Content:\n\n";
Temp += OriginalContent + "\n";
Error(Temp);
return false;
}
if (Content != ExpectedContent) {
std::string Temp;
Temp = "TestReplaceXmlAttribute: Incorrect result with valid input. Content after replacement:\n\n";
Temp += Content;
Temp += "\n\nExpected:\n\n";
Temp += ExpectedContent + "\n";
Error(Temp);
return false;
}
Content = "<!-- License file created by SNFIdentity-->\n"
"<snf>\n"
"<TestElement TestAttribute=\"testmode\" TestXXAttribute='setuptestingonly'/>\n"
"</snf>\n";
OriginalContent = Content;
ExpectedContent = "<!-- License file created by SNFIdentity-->\n"
"<snf>\n"
"<TestElement TestAttribute=\"NewValue\" TestXXAttribute='setuptestingonly'/>\n"
"</snf>\n";
try {
Utility::ReplaceXmlAttribute(&Content, ElementName, AttributeName, AttributeNewValue);
} catch (std::exception &e) {
std::string Temp;
Temp = "TestReplaceXmlAttribute: Exception thrown with valid input: ";
Temp += e.what();
Temp += "\n\nOriginal Content:\n\n";
Temp += OriginalContent + "\n";
Error(Temp);
return false;
}
if (Content != ExpectedContent) {
std::string Temp;
Temp = "TestReplaceXmlAttribute: Incorrect result with valid input. Content after replacement:\n\n";
Temp += Content;
Temp += "\n\nExpected:\n\n";
Temp += ExpectedContent + "\n";
Error(Temp);
return false;
}
Content = "<!-- License file created by SNFIdentity-->\n"
"<snf>\n"
"<TestElement TestAttribute\t\n= \"testmode\" authentication='setuptestingonly'/>\n"
"</snf>\n";
OriginalContent = Content;
ExpectedContent = "<!-- License file created by SNFIdentity-->\n"
"<snf>\n"
"<TestElement TestAttribute\t\n= \"NewValue\" authentication='setuptestingonly'/>\n"
"</snf>\n";
try {
Utility::ReplaceXmlAttribute(&Content, ElementName, AttributeName, AttributeNewValue);
} catch (std::exception &e) {
std::string Temp;
Temp = "TestReplaceXmlAttribute: Exception thrown with valid input: ";
Temp += e.what();
Temp += "\n\nOriginal Content:\n\n";
Temp += OriginalContent + "\n";
Error(Temp);
return false;
}
if (Content != ExpectedContent) {
std::string Temp;
Temp = "TestReplaceXmlAttribute: Incorrect result with valid input. Content after replacement:\n\n";
Temp += Content;
Temp += "\n\nExpected:\n\n";
Temp += ExpectedContent + "\n";
Error(Temp);
return false;
}
// Test with invalid input.
// Duplicate element.
Content = "<!-- License file created by SNFIdentity-->\n"
"<snf>\n"
"<TestElement TestAttribute\t\n= \"testmode\" authentication='setuptestingonly'/>\n"
"<TestElement TestAttribute\t\n= \"testmode\" authentication='setuptestingonly'/>\n"
"</snf>\n";
OriginalContent = Content;
try {
Utility::ReplaceXmlAttribute(&Content, ElementName, AttributeName, AttributeNewValue);
std::string Temp;
Temp = "TestReplaceXmlAttribute: Exception not thrown with two <TestElement> elements. Original content:\n\n";
Temp += OriginalContent + "\n";
Error(Temp);
return false;
} catch (std::exception &e) {
std::cout << "Duplicate TestElement: " << e.what() << "\n\n";
}
// Missing element.
Content = "<!-- License file created by SNFIdentity-->\n"
"<snf>\n"
"</snf>\n";
OriginalContent = Content;
try {
Utility::ReplaceXmlAttribute(&Content, ElementName, AttributeName, AttributeNewValue);
std::string Temp;
Temp = "TestReplaceXmlAttribute: Exception not thrown with missing <TestElement> element. Original content:\n\n";
Temp += OriginalContent + "\n";
Error(Temp);
return false;
} catch (std::exception &e) {
std::cout << "Missing TestElement: " << e.what() << "\n\n";
}
// Malformed element.
Content = "<!-- License file created by SNFIdentity-->\n"
"<snf>\n"
"<TestElement TestAttribute\t\n= \"testmode\" authentication='setuptestingonly'\n"
"</snf>\n";
OriginalContent = Content;
try {
Utility::ReplaceXmlAttribute(&Content, ElementName, AttributeName, AttributeNewValue);
std::string Temp;
Temp = "TestReplaceXmlAttribute: Exception not thrown with malformed <TestElement> element. Original content:\n\n";
Temp += OriginalContent + "\n";
Error(Temp);
return false;
} catch (std::exception &e) {
std::cout << "No closing to TestElement: " << e.what() << "\n\n";
}
// Duplicate attribute.
Content = "<!-- License file created by SNFIdentity-->\n"
"<snf>\n"
"<TestElement TestAttribute\t\n= \"testmode\" TestAttribute='setuptestingonly'/>\n"
"</snf>\n";
OriginalContent = Content;
try {
Utility::ReplaceXmlAttribute(&Content, ElementName, AttributeName, AttributeNewValue);
std::string Temp;
Temp = "TestReplaceXmlAttribute: Exception not thrown with two TestAttribute attributes. Original content:\n\n";
Temp += OriginalContent + "\n";
Error(Temp);
return false;
} catch (std::exception &e) {
std::cout << "Duplicate attribute: " << e.what() << "\n\n";
}
// Attribute in another element
Content = "<!-- License file created by SNFIdentity-->\n"
"<snf>\n"
"<TestElement XXXTestAttribute='setuptestingonly'/>\n"
"<ATestElement TestAttribute\t\n= \"testmode\"/>\n"
"</snf>\n";
OriginalContent = Content;
try {
Utility::ReplaceXmlAttribute(&Content, ElementName, AttributeName, AttributeNewValue);
std::string Temp;
Temp = "TestReplaceXmlAttribute: Exception not thrown with TestAttribute attribute in another element. "
"Original content:\n\n";
Temp += OriginalContent + "\n";
Error(Temp);
return false;
} catch (std::exception &e) {
std::cout << "TestAttribute in another element: " << e.what() << "\n\n";
}
// Missing attribute.
Content = "<!-- License file created by SNFIdentity-->\n"
"<snf>\n"
"<TestElement XXXTestAttribute\t\n= \"testmode\" YYYTestAttribute='setuptestingonly'/>\n"
"</snf>\n";
OriginalContent = Content;
try {
Utility::ReplaceXmlAttribute(&Content, ElementName, AttributeName, AttributeNewValue);
std::string Temp;
Temp = "TestReplaceXmlAttribute: Exception not thrown with missing TestAttribute attribute. Original content:\n\n";
Temp += OriginalContent + "\n";
Error(Temp);
return false;
} catch (std::exception &e) {
std::cout << "Missing attribute: " << e.what() << "\n\n";
}
// Malformed attribute value.
Content = "<!-- License file created by SNFIdentity-->\n"
"<snf>\n"
"<TestElement TestAttribute\t\n= \"testmode' />\n"
"</snf>\n";
OriginalContent = Content;
try {
Utility::ReplaceXmlAttribute(&Content, ElementName, AttributeName, AttributeNewValue);
std::string Temp;
Temp = "TestReplaceXmlAttribute: Exception not thrown with malformed TestAttribute value. "
"Original content:\n\n";
Temp += OriginalContent + "\n";
Error(Temp);
return false;
} catch (std::exception &e) {
std::cout << "No closing to attribute: " << e.what() << "\n\n";
}
return true;
}
/// Unit tests for Utility.
//
int main(int argc, char* argv[]) {
try { // Catch anything that breaks loose.
// Test ReplaceXmlAttribute().
if (!TestReplaceXmlAttribute()) {
ErrorExit("TestReplaceXmlAttribute() failure.\n");
}
} // That's all folks.
catch(std::exception& e) { // Report any normal exceptions.
std::cerr << "Utility exception: " << e.what() << std::endl;
return -1;
}
catch(...) { // Report any unexpected exceptions.
std::cerr << "Panic! Unknown Exception!" << std::endl;
return -1;
}
return 0; // Normally we return zero.
}

+ 114
- 37
SNFMilterConfig/SNFMilterConfig.cpp Ver arquivo

@@ -74,22 +74,25 @@ const string SnfMilterMainCfIntegrationString("smtpd_milters = unix:/var/snf-mil
void
SNFMilterConfig::DisplayHelp(std::string Version) {
std::string ExclusiveCommands;
std::string ExclusiveCommandsHelp;
ExclusiveCommands = IntegrateWithPostfixKey + " | ";
ExclusiveCommands += IntegrateWithSendmailKey + " | ";
ExclusiveCommands += IntegrateWithNoneKey;
ExclusiveCommandsHelp = " -mta=postfix Integrate with postfix\n";
ExclusiveCommandsHelp += " -mta=sendmail Integrate with sendmail\n";
ExclusiveCommandsHelp += " -mta=none Remove any integration with all supported MTAs\n";
cout
<< Version << endl
<< "Copyright (C) 2012, ARM Research Labs, LLC (www.armresearch.com)\n\n"
<< "Usage:\n\n"
<< "SNFMilterConfig "
<< IntegrateWithPostfixKey << " | "
<< IntegrateWithSendmailKey << " | "
<< IntegrateWithNoneKey << " "
<< UtilityConfig::HelpCommandLine() << "\n\n"
<< "SNFMilterConfig creates the configuration files (snf-config-file and the\n"
<< "ignore list file), the rulebase download script (default: getRulebase) if\n"
<< "they don't exist, and also the identity file.\n\n"
<< " -mta=postfix Integrate with postfix\n"
<< " -mta=sendmail Integrate with sendmail\n"
<< " -mta=none Remove any integration with all supported MTAs\n"
<< UtilityConfig::HelpDescription() << "\n"
<< UtilityConfig::HelpCommandLine(ExclusiveCommands) << "\n\n"
<< "SNFMilterConfig "
<< UtilityConfig::HelpDescription(ExclusiveCommandsHelp) << "\n"
<< "If snf-config-file is not specified, then the following file is used if it exists:\n\n"
<< " " << DefaultConfigFile << "\n\n"
<< "If snf-config-file is not specified and the above file doesn't exist, then it is\n"
@@ -143,7 +146,7 @@ SNFMilterConfig::GetCommandLineInput(int argc, char* argv[]) {
if (UpdateCredentialsSpecified()) {
Command = UpdateCredentialsCommand;
NumCommandsfound++;
NumCommandsFound++;
}
@@ -172,6 +175,99 @@ SNFMilterConfig::GetCommandLineInput(int argc, char* argv[]) {
}
void
SNFMilterConfig::ExecuteCommand() {
switch (Command) {
case SetupRepairCommand:
CreateLoadConfig(); // Save config file state create default
// config if necessary, and load config.
SetupRepair(SampleIdentityFile);
SetupRepairSocketDir();
break;
case UpdateCredentialsCommand:
UpdateRulebaseScriptCredentials();
DownloadRulebase();
UpdateIdentityFile();
break;
case IntegrateWithPostfixCommand:
break;
case IntegrateWithSendmailCommand:
break;
case IntegrateWithNoneCommand:
break;
case StartSnifferCommand:
break;
case StopSnifferCommand:
break;
default:
break;
}
#if 0
SnifferRunningStatue RunningStatus;
#endif
SnfMilterConfig.CreateLoadConfig(); // Save config file state and load config.
// Load the default if necessary.
#if 0
SnfMilterConfig.SaveFileState(); // Save state of all other files.
RunningStatus = SnfMilterConfig.GetSnifferRunningStatus(); // Get state before changing anything.
#endif
SnfMilterConfig.UpdateConfigFiles(); // Create/update config files
SnfMilterConfig.CreateUpdateRulebaseScript(); // Create/update GetRulebase.
SnfMilterConfig.DownloadRulebase(); // Download rulebase.
SnfMilterConfig.UpdateIdentityFile(); // Update Identity file with credentials,
// if credentials were specified.
SnfMilterConfig.DoIntegrationCommand(); // Integrate/unintegrate.
#if 0
if (SnifferIsStopped == RunningStatus) {
SnfMilterConfig.StartSniffer();
} else if (SnifferRunningStatusIsUknown == RunningStatus) {
std::cout << "SNFMilterConfig: Unable to determine whether SNFMilter is running.\n"
<< "Please start SNFMilter if it isn't running.\n";
}
#else
SnfMilterConfig.StartSniffer("snf-milter");
#endif
}
void
SNFMilterConfig::LoadSocketInfo() {
@@ -192,7 +288,7 @@ SNFMilterConfig::LoadSocketInfo() {
}
void
SNFMilterConfig::CreateSocketDir() {
SNFMilterConfig::SetupRepairSocketDir() {
std::string SocketDir;
@@ -228,13 +324,8 @@ SNFMilterConfig::CreateLoadConfig() {
CheckAndSetConfigFileName(&DefaultConfigFile, 1); // Load the config file name.
if (!Explain()) {
SaveFile.CreateBackupFile(GetConfigFileName());
}
CreateDefaultConfigFile(SampleConfigFile); // Create the file if it doesn't exist.
CreateDefaultConfigFile(SampleConfigFile); // Create the file if it doesn't exist,
// Set owner and mode in any case.
LoadConfig();
LoadInfo(); // Load the file paths.
@@ -261,20 +352,6 @@ SNFMilterConfig::SaveFileState() {
}
void
SNFMilterConfig::UpdateConfigFiles() {
SetMode(GetConfigFileName(), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); // Set permissions.
SetOwnerGroup(GetConfigFileName()); // Set to sniffer user.
CreateDefaultIdentityFile(SampleIdentityFile);
CreateUpdateRulebaseScript();
UpdateLogDir();
UpdateIgnoreListFile();
}
void
SNFMilterConfig::DoIntegrationCommand() {
@@ -283,16 +360,16 @@ SNFMilterConfig::DoIntegrationCommand() {
case NoCommand:
break;
case IntegrateWithNoneCmd:
case IntegrateWithNoneCommand:
UnintegrateWithAllExcept();
break;
case IntegrateWithPostfixCmd:
case IntegrateWithPostfixCommand:
UnintegrateWithAllExcept("postfix");
Postfix.Integrate(&SaveFile);
break;
case IntegrateWithSendmailCmd:
case IntegrateWithSendmailCommand:
UnintegrateWithAllExcept("sendmail");
// Sendmail.Integrate(&SaveFile);
break;

+ 21
- 8
SNFMilterConfig/SNFMilterConfig.hpp Ver arquivo

@@ -30,10 +30,10 @@ public:
/// Command specified.
enum CommandEnum {
SetupRepairCommand, ///< Setup or repair the configuration.
UpdateCredentialsCommand, ///< Update the credentials.
IntegrateWithPostfixCommand, ///< Integrate with postfix.
IntegrateWithSendmailCommand, ///< Integrate with sendmail.
IntegrateWithNoneCommand, ///< Unintegrate with all supported MTAs.
UpdateCredentialsCommand, ///< Update the credentials.
StartSnifferCommand, ///< Start the Sniffer.
StopSnifferCommand, ///< Stop the Sniffer.
NoCommand, ///< No command specified.
@@ -72,19 +72,32 @@ public:
//
void CreateLoadConfig(void);
/// Execute the command specified by the command-line parameters.
//
void ExecuteCommand(void);
/// Save the state of all files that might be changed, except the
/// config file.
//
void SaveFileState(void);
void SaveFileState(void); // OBSOLETE.
/// Create or update the configuration files.
/// Setup/repair the configuration.
//
// Copy the following files from the sample files if they don't
// exist:
//
// <ol>
// <li> Identity file. </li>
// <li> Ignore list file. </li>
// <li> Rulebase script. </li>
// </ol>
//
// Set the owner/group of each of the above files.
//
// The SNFMilter.xml and GBUdbIgnoreList.txt files are created if
// they don't exist. In any case, the owner/group is changed by
// SetOwnerGroup(), and the permissions are changed to readonly
// for everyone, and read/write for the owner.
// Make sure that the log directory exists and has the correct
// owner and permissions.
//
void UpdateConfigFiles();
void SetupRepair();
/// Execute the command to integrate/unintegrate with the MTAs.
void DoIntegrationCommand();

+ 1
- 38
SNFMilterConfig/main.cpp Ver arquivo

@@ -82,44 +82,7 @@ int main(int argc, char* argv[]) {
try { // Catch anything that breaks loose.
#if 0
SnifferRunningStatue RunningStatus;
#endif
SnfMilterConfig.CreateLoadConfig(); // Save config file state and load config.
// Load the default if necessary.
SnfMilterConfig.SaveFileState(); // Save state of all other files.
#if 0
RunningStatus = SnfMilterConfig.GetSnifferRunningStatus(); // Get state before changing anything.
#endif
SnfMilterConfig.UpdateConfigFiles(); // Create/update config files
SnfMilterConfig.CreateUpdateRulebaseScript(); // Create/update GetRulebase.
SnfMilterConfig.DownloadRulebase(); // Download rulebase.
SnfMilterConfig.UpdateIdentityFile(); // Update Identity file with credentials,
// if credentials were specified.
SnfMilterConfig.DoIntegrationCommand(); // Integrate/unintegrate.
#if 0
if (SnifferIsStopped == RunningStatus) {
SnfMilterConfig.StartSniffer();
} else if (SnifferRunningStatusIsUknown == RunningStatus) {
std::cout << "SNFMilterConfig: Unable to determine whether SNFMilter is running.\n"
<< "Please start SNFMilter if it isn't running.\n";
}
#else
SnfMilterConfig.StartSniffer("snf-milter");
#endif
SnfMilterConfig.ExecuteCommand();
} // That's all folks.

Carregando…
Cancelar
Salvar