Browse Source

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 years ago
parent
commit
b15b3d2aa9

+ 146
- 0
Common/Utility.cpp View File

} }
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 bool
Utility::CheckForString(std::string Line, std::string SearchString) { Utility::CheckForString(std::string Line, std::string SearchString) {

+ 14
- 0
Common/Utility.hpp View File

// //
static bool CheckForString(std::string Line, std::string SearchString); 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. /// Trim whitespace from a string.
// //
// This method removes leading " ", "\t", "\r", and "\n" from the specified string. // This method removes leading " ", "\t", "\r", and "\n" from the specified string.

+ 232
- 93
Common/UtilityConfig.cpp View File

const string LicenseSearchString = "LICENSE_ID="; const string LicenseSearchString = "LICENSE_ID=";
const string AuthSearchString = "AUTHENTICATION="; const string AuthSearchString = "AUTHENTICATION=";
const string IdentityElementName = "identity";
const string LicenseAttributeName = "licenseid";
const string AuthenticationAttributeName = "authentication";
////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////
// End of configuration. ///////////////////////////////////////////////////////////////////////////////// // End of configuration. /////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////
UtilityConfig::UtilityConfig() : UtilityConfig::UtilityConfig() :
LicenseIdIsSpecified(false), AuthenticationIsSpecified(false), ConfigFileExists(true)
LicenseIdIsSpecified(false), AuthenticationIsSpecified(false)
{ {
SetExplain(false); SetExplain(false);
if (NumDefaultFiles > 0) { if (NumDefaultFiles > 0) {
ProvisionalConfigFile = DefaultFile[0]; // Use the first default file. ProvisionalConfigFile = DefaultFile[0]; // Use the first default file.
ConfigFileExists = false;
} else { // No default config file was specified. } else { // No default config file was specified.
throw runtime_error(Temp); throw runtime_error(Temp);
} else {
ConfigFileExists = true; // Config file was found.
} }
} else {
ConfigFileExists = FileExists(ProvisionalConfigFile);
} }
SetConfigFileName(ProvisionalConfigFile); SetConfigFileName(ProvisionalConfigFile);
std::string File = GetConfigFileName(); 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. // 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 void
} }
void 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 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 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();
} }
if (!Explain()) { if (!Explain()) {
SaveFile.CreateBackupFile(File);
ofstream Output; // Write the updated contents. ofstream Output; // Write the updated contents.
Output.open(File.c_str(), ios::trunc); Output.open(File.c_str(), ios::trunc);
void void
UtilityConfig::DownloadRulebase() { UtilityConfig::DownloadRulebase() {
if (!UpdateCredentialsSpecified()) {
return;
}
if (Verbose()) { if (Verbose()) {
std::cout << "Downloading the rulebase..."; std::cout << "Downloading the rulebase...";
if (!Explain()) { if (!Explain()) {
SaveFile.CreateBackupFile(GetRulebaseFileName()); // Save the current rulebase file.
if (0 != remove(StatusFile.c_str())) { // Delete the status file. if (0 != remove(StatusFile.c_str())) { // Delete the status file.
if (ENOENT != errno) { // No error if the file doesn't exist. if (ENOENT != errno) { // No error if the file doesn't exist.
std::string File = GetIdentityFileName(); 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; 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. SetOwnerGroup(File); // Set the user and group.
SetMode(File, S_IRUSR); // Set to readonly by owner. SetMode(File, S_IRUSR); // Set to readonly by owner.
} }
#endif
void void
UtilityConfig::StartSniffer(std::string Script) { UtilityConfig::StartSniffer(std::string Script) {
} }
std::string std::string
UtilityConfig::HelpCommandLine() {
UtilityConfig::HelpCommandLine(std::string ExclusiveCommandsHelp) {
std::string Help; 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 + " ]"; Help += "[ " + VerboseKey + " " + ExplainKey + " ]";
return Help; return Help;
} }
std::string std::string
UtilityConfig::HelpDescription() {
UtilityConfig::HelpDescription(std::string ExclusiveCommandsHelp) {
std::string Desc; 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 += " -id=licenseid Specifies the license ID\n";
Desc += " -auth=authentication Specifies the Authentication\n"; Desc += " -auth=authentication Specifies the Authentication\n";
Desc += " -v Provide verbose output\n"; Desc += " -v Provide verbose output\n";
return Desc; return Desc;
} }
void void
UtilityConfig::SetSetupRepair(bool Specified) { UtilityConfig::SetSetupRepair(bool Specified) {
} }
bool
UtilityConfig::UpdateCredentialsSpecified() {
return ( (LicenseId.length() > 0) && (Authentication.length() > 0) );
}
void void
UtilityConfig::SetStartSniffer(bool Specified) { UtilityConfig::SetStartSniffer(bool Specified) {

+ 83
- 66
Common/UtilityConfig.hpp View File

}; };
/// Default constructor. /// Default constructor.
UtilityConfig();
UtilityConfig(void);
/// Object to back up and restore files. /// Object to back up and restore files.
FileBackup SaveFile; FileBackup SaveFile;
void CheckAndSetConfigFileName(const std::string DefaultFile[], int NumDefaultFiles); void CheckAndSetConfigFileName(const std::string DefaultFile[], int NumDefaultFiles);
/// If the configuration file doesn't exist, create it from the /// 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 // This method creates the default configuration file if the
// specified configuration file doesn't exist. // specified configuration file doesn't exist.
// //
void CreateDefaultConfigFile(std::string SampleConfigFile); 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. /// Load the configuration from the file specified by SetConfigFileName.
// //
// //
// \returns the name of the rulebase file, including the path. // \returns the name of the rulebase file, including the path.
// //
std::string GetRulebaseFileName();
std::string GetRulebaseFileName(void);
/// Get the operating system type. /// Get the operating system type.
// //
// This method updates the public members that contain the OS // This method updates the public members that contain the OS
// specification and file paths. // specification and file paths.
// //
void LoadInfo();
void LoadInfo(void);
/// Postfix main.cf file path. /// Postfix main.cf file path.
std::string PostfixMainCfPath; std::string PostfixMainCfPath;
/// Directory containing the Sniffer start script. /// Directory containing the Sniffer start script.
std::string SnifferStartScriptDir; 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. /// Download the rulebase.
// //
void DownloadRulebase();
void DownloadRulebase(void);
/// Update the identity file. /// Update the identity file.
// //
// //
// \returns if the command-line parameters were specified // \returns if the command-line parameters were specified
// correctly, false otherwise. // correctly, false otherwise.
bool CommandLineIsOkay();
bool CommandLineIsOkay(void);
/// Output the legal command-line input. /// 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. /// 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. /// Store whether the setup/help command was specified.
// //
// //
// \returns true if the setup/help command was specified on the command line. // \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. /// Store whether the start sniffer command was specified.
// //
// //
// \returns true if the start sniffer command was specified on the command line. // \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. /// Store whether the stop sniffer command was specified.
// //
// //
// \returns true if the stop sniffer command was specified on the command line. // \returns true if the stop sniffer command was specified on the command line.
// //
bool StopSnifferSpecified();
bool StopSnifferSpecified(void);
private: 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. std::string ConfigFileName; ///< Configuration file name.
bool ConfigFileExists; ///< True if the configuration file exists.
std::string LicenseId; ///< License ID string. std::string LicenseId; ///< License ID string.
bool LicenseIdIsSpecified; ///< true if the License ID was specified on the command line. bool LicenseIdIsSpecified; ///< true if the License ID was specified on the command line.
std::string Authentication; ///< Authentication string. std::string Authentication; ///< Authentication string.

+ 8
- 2
CommonTests/Makefile.am View File

CXXFLAGS = $(SNF_CXXFLAGS) -I@top_srcdir@/SNFUtility/Common CXXFLAGS = $(SNF_CXXFLAGS) -I@top_srcdir@/SNFUtility/Common


TESTS = \ TESTS = \
TestFileBackup
TestFileBackup \
TestUtility


check_PROGRAMS = \ check_PROGRAMS = \
TestFileBackup
TestFileBackup \
TestUtility


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


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

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

+ 399
- 0
CommonTests/TestUtility.cpp View File

// $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 View File

void void
SNFMilterConfig::DisplayHelp(std::string Version) { 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 cout
<< Version << endl << Version << endl
<< "Copyright (C) 2012, ARM Research Labs, LLC (www.armresearch.com)\n\n" << "Copyright (C) 2012, ARM Research Labs, LLC (www.armresearch.com)\n\n"
<< "Usage:\n\n" << "Usage:\n\n"
<< "SNFMilterConfig " << "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" << "If snf-config-file is not specified, then the following file is used if it exists:\n\n"
<< " " << DefaultConfigFile << "\n\n" << " " << DefaultConfigFile << "\n\n"
<< "If snf-config-file is not specified and the above file doesn't exist, then it is\n" << "If snf-config-file is not specified and the above file doesn't exist, then it is\n"
if (UpdateCredentialsSpecified()) { if (UpdateCredentialsSpecified()) {
Command = UpdateCredentialsCommand; Command = UpdateCredentialsCommand;
NumCommandsfound++;
NumCommandsFound++;
} }
} }
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 void
SNFMilterConfig::LoadSocketInfo() { SNFMilterConfig::LoadSocketInfo() {
} }
void void
SNFMilterConfig::CreateSocketDir() {
SNFMilterConfig::SetupRepairSocketDir() {
std::string SocketDir; std::string SocketDir;
CheckAndSetConfigFileName(&DefaultConfigFile, 1); // Load the config file name. 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(); LoadConfig();
LoadInfo(); // Load the file paths. LoadInfo(); // Load the file paths.
} }
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 void
SNFMilterConfig::DoIntegrationCommand() { SNFMilterConfig::DoIntegrationCommand() {
case NoCommand: case NoCommand:
break; break;
case IntegrateWithNoneCmd:
case IntegrateWithNoneCommand:
UnintegrateWithAllExcept(); UnintegrateWithAllExcept();
break; break;
case IntegrateWithPostfixCmd:
case IntegrateWithPostfixCommand:
UnintegrateWithAllExcept("postfix"); UnintegrateWithAllExcept("postfix");
Postfix.Integrate(&SaveFile); Postfix.Integrate(&SaveFile);
break; break;
case IntegrateWithSendmailCmd:
case IntegrateWithSendmailCommand:
UnintegrateWithAllExcept("sendmail"); UnintegrateWithAllExcept("sendmail");
// Sendmail.Integrate(&SaveFile); // Sendmail.Integrate(&SaveFile);
break; break;

+ 21
- 8
SNFMilterConfig/SNFMilterConfig.hpp View File

/// Command specified. /// Command specified.
enum CommandEnum { enum CommandEnum {
SetupRepairCommand, ///< Setup or repair the configuration. SetupRepairCommand, ///< Setup or repair the configuration.
UpdateCredentialsCommand, ///< Update the credentials.
IntegrateWithPostfixCommand, ///< Integrate with postfix. IntegrateWithPostfixCommand, ///< Integrate with postfix.
IntegrateWithSendmailCommand, ///< Integrate with sendmail. IntegrateWithSendmailCommand, ///< Integrate with sendmail.
IntegrateWithNoneCommand, ///< Unintegrate with all supported MTAs. IntegrateWithNoneCommand, ///< Unintegrate with all supported MTAs.
UpdateCredentialsCommand, ///< Update the credentials.
StartSnifferCommand, ///< Start the Sniffer. StartSnifferCommand, ///< Start the Sniffer.
StopSnifferCommand, ///< Stop the Sniffer. StopSnifferCommand, ///< Stop the Sniffer.
NoCommand, ///< No command specified. NoCommand, ///< No command specified.
// //
void CreateLoadConfig(void); 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 /// Save the state of all files that might be changed, except the
/// config file. /// 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. /// Execute the command to integrate/unintegrate with the MTAs.
void DoIntegrationCommand(); void DoIntegrationCommand();

+ 1
- 38
SNFMilterConfig/main.cpp View File

try { // Catch anything that breaks loose. 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. } // That's all folks.

Loading…
Cancel
Save