Create any config files that don't exist from the sample files. SNFMilterConfig is responsible for saving and restoring all config files. SNFIdentity is deprecated. git-svn-id: https://svn.microneil.com/svn/SNFUtility/trunk@8 aa37657e-1934-4a5f-aa6d-2d8eab27ff7cmaster
@@ -6,14 +6,14 @@ | |||
// This file implements the common functionality for the configuration | |||
// utilities. | |||
#include <sstream> | |||
#include <stdexcept> | |||
#include <fstream> | |||
#include <cerrno> | |||
#include <cstring> | |||
#include <cstdio> | |||
#include <sstream> | |||
#include <stdexcept> | |||
#include <fstream> | |||
#include "FileBackup.hpp" | |||
////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
@@ -126,7 +126,9 @@ FileBackup::FileExists(std::string File) { | |||
void | |||
FileBackup::CreateBackupFile(std::string File) { | |||
if (OriginalFileExists[File] = FileExists(File)) { // Back up if the file exists. | |||
bool ThisFileExists = FileExists(File); | |||
if (ThisFileExists) { // Back up if the file exists. | |||
try { | |||
@@ -144,6 +146,8 @@ FileBackup::CreateBackupFile(std::string File) { | |||
} | |||
OriginalFileExists[File] = ThisFileExists; | |||
} | |||
void | |||
@@ -193,7 +197,6 @@ FileBackup::RestoreAllFilesFromBackup() { | |||
iFile++) { | |||
std::string BackupFileName; | |||
if (iFile->second) { // Original file existed? | |||
try { // Yes. | |||
@@ -213,12 +216,16 @@ FileBackup::RestoreAllFilesFromBackup() { | |||
} else { // No. | |||
if (0 != remove(iFile->first.c_str())) { | |||
if (FileExists(iFile->first)) { | |||
ErrorMessage << "Unable to remove backup file " << BackupFileName | |||
<< ": " << strerror(errno) << "\n"; | |||
if (0 != remove(iFile->first.c_str())) { | |||
ErrorOccurred = true; | |||
ErrorMessage << "Unable to remove backup file " << BackupFileName | |||
<< ": " << strerror(errno) << "\n"; | |||
ErrorOccurred = true; | |||
} | |||
} | |||
@@ -9,8 +9,6 @@ | |||
// | |||
/////////////////////////////////////////////////////////////////////////////////////////////////// | |||
#include <iostream> | |||
#include "MtaIntegrate.hpp" | |||
MtaIntegrate::MtaIntegrate() { |
@@ -54,6 +54,23 @@ public: | |||
// | |||
virtual void Unintegrate(FileBackup *SaveFile) = 0; | |||
/// Check whether the MTA is determined to be running. | |||
// | |||
// \return true if the MTA is determined to be running. If the | |||
// MTA is not running, or the running status cannot be determined, | |||
// the return value is false. | |||
// | |||
virtual bool MtaIsRunningDetected() = 0; | |||
/// Reload the MTA configuration. | |||
// | |||
// This method causes the MTA to reload its configuration. | |||
// | |||
// \return true if the MTA successfully reloaded its | |||
// configuration, false otherwise. | |||
// | |||
virtual bool ReloadMta() = 0; | |||
private: | |||
/// Determine whether the MTA is integrated. |
@@ -39,6 +39,10 @@ const string SNFGroupName = "snfuser"; | |||
// End of configuration. ///////////////////////////////////////////////////////////////////////////////// | |||
////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
Utility::Utility() { | |||
} | |||
bool | |||
Utility::FileExists(const std::string File) { | |||
@@ -151,7 +155,7 @@ Utility::Copy(std::string From, std::string To) { | |||
void | |||
Utility::SetOwnerGroup(std::string &File) { | |||
Utility::SetOwnerGroup(std::string File) { | |||
struct passwd *SNFPasswd; | |||
uid_t SNFUid; | |||
@@ -196,7 +200,7 @@ Utility::SetOwnerGroup(std::string &File) { | |||
} | |||
void | |||
Utility::SetMode(std::string &File, mode_t mode) { | |||
Utility::SetMode(std::string File, mode_t mode) { | |||
if (Verbose()) { | |||
@@ -267,6 +271,30 @@ Utility::CheckForString(std::string Line, std::string SearchString) { | |||
} | |||
std::string | |||
Utility::Trim(std::string String) { | |||
std::string Whitespace(" \n\r\t"); | |||
std::string::size_type End = String.find_last_not_of(Whitespace); | |||
if (End == std::string::npos) { | |||
return std::string(); | |||
} | |||
std::string::size_type Start = String.find_first_not_of(Whitespace); | |||
if (Start == std::string::npos) { | |||
Start = 0; | |||
} | |||
return String.substr(Start, (End - Start) + 1); | |||
} | |||
void | |||
Utility::SetVerbose(bool Mode) { | |||
@@ -50,7 +50,7 @@ public: | |||
// | |||
// \see SNFGroupName. | |||
// | |||
void SetOwnerGroup(std::string &File); | |||
void SetOwnerGroup(std::string File); | |||
/// Set the mode of a file. | |||
// | |||
@@ -61,7 +61,7 @@ public: | |||
// | |||
// \param[in] is the mode. | |||
// | |||
void SetMode(std::string &File, mode_t mode); | |||
void SetMode(std::string File, mode_t mode); | |||
/// Create a directory. | |||
// | |||
@@ -83,6 +83,15 @@ public: | |||
// | |||
static bool CheckForString(std::string Line, std::string SearchString); | |||
/// Trim whitespace from a string. | |||
// | |||
// This method removes leading " ", "\t", "\r", and "\n" from the specified string. | |||
// | |||
// \param[in] String is the string to trim. | |||
// | |||
// \returns String with the leading and trailing whitespace removed. | |||
static std::string Trim(std::string String); | |||
/// Store the Verbose mode. | |||
// | |||
// \param[in] Mode stores the Verbose mode. | |||
@@ -126,6 +135,8 @@ public: | |||
/// Directory separator. | |||
static const std::string DirectorySeparator; | |||
/// Trim whitespace from a string. | |||
private: | |||
bool VerboseRequested; ///< User requested verbose processing. |
@@ -27,14 +27,33 @@ using namespace std; | |||
// Configuration. //////////////////////////////////////////////////////////////////////////////////////// | |||
////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
// Initialize sample ignore list file path. | |||
// Initialize OS-dependent constants. | |||
#ifdef WIN | |||
// Windows OS. | |||
const std::string UtilityConfig::SampleIgnoreListFile("C:\\SNF\\GBUdbIgnoreList.txt.sample"); | |||
const std::string UtilityConfig::RulebaseDownloadCommand("FIX THIS"); | |||
const std::string ScriptNameKey("FIX THIS"); ///< Text to replace with script name. | |||
const std::string SnifferPathKey("FIX THIS"); ///< Text to replace with directory of the rulebase. | |||
const std::string UtilityConfig::SampleRulebaseScriptFile("C:\\SNF\\getRulebase.sample"); | |||
const std::string UtilityConfig::OperatingSystemType("Windows"); | |||
#else | |||
// *nix OS. | |||
// SCRIPT is replaced with the full path of the script run, | |||
// SNIFFER_PATH is replaced with the path of the rulebase. | |||
const std::string UtilityConfig::RulebaseDownloadCommand | |||
("(cd SNIFFER_PATH; touch UpdateReady.txt; chown snfuser UpdateReady.txt; su -m snfuser -c SCRIPT)"); | |||
const std::string ScriptNameKey("SCRIPT"); ///< Text to replace with script name. | |||
const std::string SnifferPathKey("SNIFFER_PATH"); ///< Text to replace with directory of the rulebase. | |||
#ifdef DEFAULT_DATA_DIR | |||
// *nix, DEFAULT_DATA_DIR is specified on the compile command line. | |||
const std::string UtilityConfig::SampleIgnoreListFile(DEFAULT_DATA_DIR "/GBUdbIgnoreList.txt.sample"); | |||
@@ -45,16 +64,6 @@ const std::string UtilityConfig::SampleIgnoreListFile(DEFAULT_DATA_DIR "/GBUdbIg | |||
#error DEFAULT_DATA_DIR must be defined by -DDEFAULT_DATA_DIR="..." when compiling. | |||
#endif | |||
#endif | |||
// Initialize sample rulebase script file. | |||
#ifdef WIN | |||
// Windows OS. | |||
const std::string UtilityConfig::SampleRulebaseScriptFile("C:\\SNF\\getRulebase.sample"); | |||
#else | |||
#ifdef SBIN_DIR | |||
// *nix, SBIN_DIR is specified on the compile command line. | |||
const std::string UtilityConfig::SampleRulebaseScriptFile(SBIN_DIR "/getRulebase.sample"); | |||
@@ -65,13 +74,6 @@ const std::string UtilityConfig::SampleRulebaseScriptFile(SBIN_DIR "/getRulebase | |||
#error SBIN_DIR must be defined by -DSBIN_DIR="..." when compiling. | |||
#endif | |||
#endif | |||
// Initialize OS-specific values. | |||
#ifdef WIN | |||
// Windows OS. | |||
const std::string UtilityConfig::OperatingSystemType("Windows"); | |||
#else | |||
#ifdef SNF_OSTYPE | |||
// *nix, SNF_OSTYPE is specified on the compile command line. | |||
const std::string UtilityConfig::OperatingSystemType(SNF_OSTYPE); | |||
@@ -80,6 +82,7 @@ const std::string UtilityConfig::OperatingSystemType(SNF_OSTYPE); | |||
// line. In this case, we don't know the operating system. | |||
#error SNF_OSTYPE must be defined by -DSNF_OSTYPE="..." when compiling. | |||
#endif | |||
#endif | |||
/// Verbose command-line input. | |||
@@ -91,11 +94,25 @@ const string ExplainKey("-explain"); | |||
/// Help command-line input. | |||
const string HelpKey("-h"); | |||
/// Configuration file command-line input. | |||
const string ConfigFileKey("-config="); | |||
/// License ID command-line input. | |||
const string LicenseIdKey("-id="); | |||
/// Authentication command-line input. | |||
const string AuthenticationKey("-auth="); | |||
const string LicenseSearchString = "LICENSE_ID="; | |||
const string AuthSearchString = "AUTHENTICATION="; | |||
////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
// End of configuration. ///////////////////////////////////////////////////////////////////////////////// | |||
////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
UtilityConfig::UtilityConfig() { | |||
UtilityConfig::UtilityConfig() : | |||
LicenseIdIsSpecified(false), AuthenticationIsSpecified(false), ConfigFileExists(true) | |||
{ | |||
SetExplain(false); | |||
SetVerbose(false); | |||
@@ -104,9 +121,9 @@ UtilityConfig::UtilityConfig() { | |||
} | |||
void | |||
UtilityConfig::CheckAndLoadConfigFile(const std::string DefaultFile[], int NumDefaultFiles) { | |||
UtilityConfig::CheckAndSetConfigFileName(const std::string DefaultFile[], int NumDefaultFiles) { | |||
string ProvisionalConfigFile = ConfigFile; | |||
string ProvisionalConfigFile = ConfigFileName; | |||
if (ProvisionalConfigFile.length() == 0) { | |||
@@ -128,23 +145,22 @@ UtilityConfig::CheckAndLoadConfigFile(const std::string DefaultFile[], int NumDe | |||
if (0 == FoundFile.size()) { // No default file found. | |||
string Temp; | |||
if (NumDefaultFiles > 0) { | |||
Temp = "Configuration file was not specified, and no default configuration file was found. "; | |||
Temp += "Checked:\n\n"; | |||
ProvisionalConfigFile = DefaultFile[0]; // Use the first default file. | |||
ConfigFileExists = false; | |||
for (i = 0; i < NumDefaultFiles; i++) { | |||
} else { // No default config file was specified. | |||
Temp += " "; | |||
Temp += DefaultFile[i] + "\n"; | |||
ostringstream Temp; | |||
} | |||
Temp << "Internal error: NumDefaultFiles <= 0 at " << __FILE__ << ":" << __LINE__; | |||
throw runtime_error(Temp); | |||
throw runtime_error(Temp.str()); | |||
} | |||
} | |||
if (FoundFile.size() > 1) { // No default file found. | |||
} else if (FoundFile.size() > 1) { // Multiple default files found. | |||
string Temp; | |||
@@ -159,22 +175,56 @@ UtilityConfig::CheckAndLoadConfigFile(const std::string DefaultFile[], int NumDe | |||
throw runtime_error(Temp); | |||
} else { | |||
ConfigFileExists = true; // Config file was found. | |||
} | |||
} else { | |||
ConfigFileExists = FileExists(ProvisionalConfigFile); | |||
} | |||
LoadConfigFile(ProvisionalConfigFile); | |||
SetConfigFileName(ProvisionalConfigFile); | |||
} | |||
void | |||
UtilityConfig::CreateDefaultConfigFile(std::string SampleConfigFile) { | |||
std::string File = GetConfigFileName(); | |||
if (!ConfigFileExists) { | |||
// Create the config file. | |||
Copy(SampleConfigFile, File); | |||
} | |||
} | |||
void | |||
UtilityConfig::LoadConfigFile(std::string Name) { | |||
UtilityConfig::CreateDefaultIdentityFile(std::string SampleIdentityFile) { | |||
std::string File = GetIdentityFileName(); | |||
if (!FileExists(File)) { | |||
// Create the config file. | |||
Copy(SampleIdentityFile, File); | |||
} | |||
} | |||
SetConfigFileName(Name); | |||
void | |||
UtilityConfig::LoadConfig() { | |||
if (Verbose()) { | |||
cout << "Using configuration file " << ConfigFile << ".\n"; | |||
cout << "Using configuration file " << GetConfigFileName() << ".\n"; | |||
} | |||
@@ -224,14 +274,14 @@ UtilityConfig::GetPlatformContents(void) { | |||
string | |||
UtilityConfig::GetConfigFileName(void) { | |||
return ConfigFile; | |||
return ConfigFileName; | |||
} | |||
void | |||
UtilityConfig::SetConfigFileName(string Name) { | |||
ConfigFile = Name; | |||
ConfigFileName = Name; | |||
} | |||
@@ -270,22 +320,29 @@ UtilityConfig::GetRulebaseScriptName(void) { | |||
} | |||
void | |||
UtilityConfig::StartOrRestartMta(std::string Mta) { | |||
string | |||
UtilityConfig::GetIgnoreListFileName(void) { | |||
if (Verbose()) { | |||
return GetWorkspacePath() + "GBUdbIgnoreList.txt"; | |||
cout << "Restarting the " << Mta << " MTA..."; | |||
} | |||
} | |||
string | |||
UtilityConfig::GetRulebaseFileName(void) { | |||
if (!Explain()) { | |||
std::string Name; | |||
cout << "restarting the MTA is not implemented..."; | |||
Name = GetRulebasePath(); | |||
Name += LicenseId + ".snf"; | |||
} | |||
return Name; | |||
OutputVerboseEnd(); | |||
} | |||
string | |||
UtilityConfig::GetOperatingSystemType(void) { | |||
return OperatingSystemType; | |||
} | |||
@@ -294,31 +351,26 @@ UtilityConfig::LoadInfo(){ | |||
if ("OpenBSD" == OperatingSystemType) { | |||
OsSpec = OpenBSD; | |||
PostfixMainCfPath = "/usr/local/etc/postfix/main.cf"; | |||
PostfixMasterCfPath = "/usr/local/etc/postfix/master.cf"; | |||
} else if ("FreeBSD" == OperatingSystemType) { | |||
OsSpec = FreeBSD; | |||
PostfixMainCfPath = "/etc/postfix/main.cf"; | |||
PostfixMasterCfPath = "/etc/postfix/master.cf"; | |||
} else if ("Ubuntu" == OperatingSystemType) { | |||
OsSpec = Ubuntu; | |||
PostfixMainCfPath = "/etc/postfix/main.cf"; | |||
PostfixMasterCfPath = "/etc/postfix/master.cf"; | |||
} else if ("RedHat" == OperatingSystemType) { | |||
OsSpec = RedHat; | |||
PostfixMainCfPath = "/etc/postfix/main.cf"; | |||
PostfixMasterCfPath = "/etc/postfix/master.cf"; | |||
} else if ("Suse" == OperatingSystemType) { | |||
OsSpec = Suse; | |||
PostfixMainCfPath = "/etc/postfix/main.cf"; | |||
PostfixMasterCfPath = "/etc/postfix/master.cf"; | |||
@@ -326,7 +378,7 @@ UtilityConfig::LoadInfo(){ | |||
ostringstream Temp; | |||
Temp << "Internal error in UtilityConfig::GetOsSpec: Invalid value of OperatingSystemType: " | |||
Temp << "Internal error in UtilityConfig::LoadInfo: Invalid value of OperatingSystemType: " | |||
<< OperatingSystemType; | |||
throw runtime_error(Temp.str()); | |||
@@ -338,18 +390,11 @@ UtilityConfig::LoadInfo(){ | |||
void | |||
UtilityConfig::UpdateIgnoreListFile() { | |||
string IgnoreListPath = GetWorkspacePath(); | |||
string IgnoreListFile; | |||
IgnoreListFile = IgnoreListPath + DirectorySeparator; | |||
IgnoreListFile += "GBUdbIgnoreList.txt"; | |||
SaveFile.CreateBackupFile(IgnoreListFile); // Save any existing file. | |||
string IgnoreListFile = GetIgnoreListFileName(); | |||
if (!FileExists(IgnoreListFile)) { | |||
Copy(SampleIgnoreListFile, IgnoreListFile); // Use SNFMilter.xml.sample. | |||
Copy(SampleIgnoreListFile, IgnoreListFile); | |||
} | |||
@@ -374,25 +419,341 @@ UtilityConfig::UpdateLogDir() { | |||
} | |||
bool | |||
UtilityConfig::UpdateCredentialsSpecified() { | |||
return ( (LicenseId.length() > 0) && (Authentication.length() > 0) ); | |||
} | |||
void | |||
UtilityConfig::CreateUpdateRulebaseScript() { | |||
std::string File = GetRulebaseScriptName(); | |||
if (!FileExists(File)) { | |||
Copy(SampleRulebaseScriptFile, File); // Copy if !Explain(). | |||
} | |||
if (UpdateCredentialsSpecified()) { | |||
UpdateRulebaseScriptCredentials(); | |||
} | |||
SetMode(File, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); // Set permissions. | |||
} | |||
void | |||
UtilityConfig::UpdateRulebaseScriptCredentials() { | |||
std::string File = GetRulebaseScriptName(); | |||
if (Verbose()) { | |||
cout << "Update authentication and license ID in the rulebase download script file " << File << "--\n"; | |||
} | |||
ifstream Input; | |||
Input.open(File.c_str()); // Read the contents. | |||
if (!Input) { | |||
string Temp; | |||
Temp = "Error opening rulebase download script file " + File; | |||
Temp += " for reading: "; | |||
Temp += strerror(errno); | |||
throw runtime_error(Temp); | |||
} | |||
string Content; | |||
string Line; | |||
bool FoundLicense = false; | |||
bool FoundAuth = false; | |||
while (getline(Input, Line)) { | |||
if (CheckForString(Line, LicenseSearchString)) { // Check for license line. | |||
if (FoundLicense) { // Second license line found? | |||
string Temp; | |||
Temp = "Rulebase sownload script file " + File; | |||
Temp += " has the wrong format: Found two lines beginning with " + LicenseSearchString; | |||
throw runtime_error(Temp); | |||
} | |||
if (Verbose()) { | |||
cout << " Modify line: '" << Line << "'...\n"; | |||
} | |||
FoundLicense = true; | |||
Line = LicenseSearchString + LicenseId; // Add license line. | |||
Line += " # Added by SNFSetup"; | |||
} | |||
if (CheckForString(Line, AuthSearchString)) { // Check for authentication line. | |||
if (FoundAuth) { // Second authentication line found? | |||
string Temp; | |||
Temp = "Rulebase download script file " + File; | |||
Temp += " has the wrong format: Found two lines beginning with " + AuthSearchString; | |||
throw runtime_error(Temp); | |||
} | |||
if (Verbose()) { | |||
cout << " Modify line: '" << Line << "'...\n"; | |||
} | |||
FoundAuth = true; | |||
Line = AuthSearchString + Authentication; // Add authentication line. | |||
Line += " # Added by SNFSetup"; | |||
} | |||
Content += Line + "\n"; | |||
} | |||
if (!FoundLicense || !FoundAuth) { | |||
string Temp; | |||
Temp = "Rulebase download script file " + File; | |||
Temp += " has the wrong format: Missing required line beginning with '" + LicenseSearchString; | |||
Temp += "' or '" + AuthSearchString; | |||
Temp += "'"; | |||
throw runtime_error(Temp); | |||
} | |||
if (!Input.eof()) { // Should be at end-of-file. | |||
string Temp; | |||
Temp = "Error reading the rulebase download script file " + File; | |||
Temp += ": "; | |||
Temp += strerror(errno); | |||
throw runtime_error(Temp); | |||
} | |||
Input.close(); | |||
if (Input.bad()) { | |||
string Temp; | |||
Temp = "Error closing the rulebase download script file " + File; | |||
Temp += " after reading: "; | |||
Temp += strerror(errno); | |||
throw runtime_error(Temp); | |||
} | |||
if (!Explain()) { | |||
ofstream Output; // Write the updated contents. | |||
Output.open(File.c_str(), ios::trunc); | |||
if (!Output) { | |||
string Temp; | |||
Temp = "Error opening rulebase download script file " + File; | |||
Temp += " for writing: "; | |||
Temp += strerror(errno); | |||
throw runtime_error(Temp); | |||
} | |||
Output << Content; | |||
if (!Output) { | |||
string Temp; | |||
Temp = "Error writing the rulebase download script file " + File; | |||
Temp += ": "; | |||
Temp += strerror(errno); | |||
throw runtime_error(Temp); | |||
} | |||
Output.close(); | |||
if (!Output) { | |||
string Temp; | |||
Temp = "Error closing the rulebase download script file " + File; | |||
Temp += " after writing: "; | |||
Temp += strerror(errno); | |||
throw runtime_error(Temp); | |||
} | |||
} | |||
OutputVerboseEnd(); | |||
} | |||
void | |||
UtilityConfig::DownloadRulebase() { | |||
if (!UpdateCredentialsSpecified()) { | |||
return; | |||
} | |||
if (Verbose()) { | |||
std::cout << "Downloading the rulebase..."; | |||
} | |||
std::string Command; | |||
Command = RulebaseDownloadCommand; | |||
std::string::size_type ScriptIndex = Command.find(ScriptNameKey); | |||
if (ScriptIndex != std::string::npos) { // Insert script full path? | |||
Command.replace(ScriptIndex, ScriptNameKey.length(), GetRulebaseScriptName()); | |||
} | |||
std::string::size_type SnifferPathIndex = Command.find(SnifferPathKey); | |||
if (SnifferPathIndex != std::string::npos) { // Insert rulebase location? | |||
Command.replace(SnifferPathIndex, SnifferPathKey.length(), GetRulebasePath()); | |||
} | |||
if (!Explain()) { | |||
if (std::system(Command.c_str()) != 0) { | |||
string Temp; | |||
Temp = "Error running the command '" + Command; | |||
Temp += "'."; | |||
throw runtime_error(Temp); | |||
} | |||
} | |||
OutputVerboseEnd(); | |||
} | |||
void | |||
UtilityConfig::UpdateIdentityFile() { | |||
std::string File = GetIdentityFileName(); | |||
if (UpdateCredentialsSpecified()) { | |||
ofstream Output; | |||
if (Verbose()) { | |||
cout << "Create identity file " << File << "..."; | |||
} | |||
if (!Explain()) { | |||
Output.open(File.c_str()); | |||
if (!Output) { | |||
string 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; | |||
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. | |||
} | |||
bool | |||
UtilityConfig::ProcessCommandLineItem(std::string OneInput) { | |||
bool ValidCommand = false; | |||
bool ValidCommand = true; | |||
std::string TempString; | |||
if (OneInput == VerboseKey) { | |||
SetVerbose(true); | |||
ValidCommand = true; | |||
} else if (OneInput == ExplainKey) { | |||
SetExplain(true); | |||
ValidCommand = true; | |||
} else if (OneInput == HelpKey) { | |||
SetHelp(true); | |||
ValidCommand = true; | |||
} else if (OneInput == ConfigFileKey) { | |||
SetConfigFileName(OneInput.substr(ConfigFileKey.length())); | |||
} else if (0 == OneInput.find(LicenseIdKey)) { | |||
TempString = Trim(OneInput.substr(LicenseIdKey.length())); // Copy only if not null after trimming. | |||
if (!TempString.empty()) { | |||
LicenseId = TempString; | |||
LicenseIdIsSpecified = true; | |||
} else { | |||
ValidCommand = false; | |||
} | |||
} else if (0 == OneInput.find(AuthenticationKey)) { | |||
Authentication = Trim(OneInput.substr(AuthenticationKey.length())); | |||
AuthenticationIsSpecified = true; | |||
} else { | |||
ValidCommand = false; | |||
} | |||
@@ -400,12 +761,21 @@ UtilityConfig::ProcessCommandLineItem(std::string OneInput) { | |||
} | |||
bool | |||
UtilityConfig::CommandLineIsOkay() { | |||
return (AuthenticationIsSpecified == LicenseIdIsSpecified); | |||
} | |||
std::string | |||
UtilityConfig::HelpCommandLine() { | |||
std::string Help; | |||
Help = "[ " + VerboseKey + " | " + ExplainKey + " ]"; | |||
Help = "[" + ConfigFileKey + "snf-config-file] "; | |||
Help += "[" + LicenseIdKey + "licenseid " + AuthenticationKey + "authentication] "; | |||
Help += "[ " + VerboseKey + " " + ExplainKey + " ]"; | |||
return Help; | |||
@@ -416,7 +786,10 @@ UtilityConfig::HelpDescription() { | |||
std::string Desc; | |||
Desc = " -v Provide verbose output\n"; | |||
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"; | |||
Desc += " -explain Provide an explaination of the actions\n"; | |||
Desc += " without executing any commands\n"; | |||
@@ -30,31 +30,54 @@ public: | |||
/// Object to back up and restore files. | |||
FileBackup SaveFile; | |||
/// Load the specified or default config file. | |||
/// Set the config file name to the default if it wasn't specified. | |||
// | |||
// This function loads (or reloads) the config file specified in | |||
// the most recent call to LoadConfigFile. If LoadConfigFile has | |||
// not been called, then this method searches for a unique default | |||
// config file in the specified list, and loads that config file. | |||
// If the configuration file wasn't specified by | |||
// SetConfigFileName() on the command line, then this method sets | |||
// the config file to the default. The default is the unique file | |||
// that exists in the specified list. If more than one file in | |||
// the specified list exists, an exception is thrown. | |||
// | |||
// If the configuration file was specified by SetConfigFileName() | |||
// or on the command line, then this method does nothing. | |||
// | |||
// \param[in] DefaultFile is the list of default locations of the file. | |||
// | |||
// \param[in] NumDefaultFiles is the number of defaultlocations. | |||
// | |||
// If the local data member ConfigFile has a value of "" on input, | |||
// then this function checks for the existence (but not | |||
// readability) of a configuration file in several locations. If | |||
// exactly one file exists, then that file is loaded and | |||
// ConfigFile is set to that name. Otherwise, an exception is | |||
// thrown. | |||
void CheckAndSetConfigFileName(const std::string DefaultFile[], int NumDefaultFiles); | |||
/// If the configuration file doesn't exist, create it from the | |||
/// sample file. | |||
// | |||
// This method creates the default configuration file if the | |||
// specified configuration file doesn't exist. | |||
// | |||
void CheckAndLoadConfigFile(const std::string DefaultFile[], int NumDefaultFiles); | |||
// The method CheckAndSetConfigFileName must be called before this | |||
// method. | |||
// | |||
// \param[in] SampleConfigFile is the name of the sample | |||
// configuration file. | |||
// | |||
void CreateDefaultConfigFile(std::string SampleConfigFile); | |||
/// Load the specified configuration file. | |||
/// If the identity file doesn't exist, create it from the sample | |||
/// file. | |||
// | |||
// \param[in] Name is the name of the configuration file. | |||
// This method creates the default identity file if the identity | |||
// file specified in the configuration file doesn't exist. | |||
// | |||
void LoadConfigFile(std::string Name); | |||
// 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); | |||
/// Load the configuration from the file specified by SetConfigFileName. | |||
// | |||
void LoadConfig(void); | |||
/// Set the configuration file name. | |||
// | |||
@@ -100,23 +123,34 @@ public: | |||
// \returns the rulebase script file name. | |||
std::string GetRulebaseScriptName(void); | |||
/// Restart the MTA. | |||
/// Get the ignore list file name. | |||
// | |||
// \returns the ignore list file name. | |||
// | |||
// This function starts or restarts the MTA. | |||
std::string GetIgnoreListFileName(void); | |||
/// Return the rulebase file name. | |||
// | |||
// \param[in] Mta specifies the MTA. The acceptable values are | |||
// "postfix" and "sendmail". | |||
// \returns the name of the rulebase file, including the path. | |||
// | |||
void StartOrRestartMta(std::string Mta); | |||
std::string GetRulebaseFileName(); | |||
/// Operating system specification. | |||
enum OperatingSystemSpecEnum { | |||
OpenBSD, ///< OpenBSD OS. | |||
FreeBSD, ///< FreeBSD OS. | |||
Ubuntu, ///< Ubuntu and variants. | |||
RedHat, ///< RedHat and variants. | |||
Suse ///< Suse and variants. | |||
}; | |||
/// Get the operating system type. | |||
// | |||
// \returns the operating system type. This is the value of | |||
// SNF_OSTYPE specified on the compile commandline. For *nix, it | |||
// is identical to the value of the --enable-os-type command-line | |||
// input to ./configure: | |||
// | |||
// <ol> | |||
// <li>OpenBSD</li> | |||
// <li>FreeBSD</li> | |||
// <li>Suse</li> | |||
// <li>RedHat</li> | |||
// <li>Ubuntu</li> | |||
// </ol> | |||
// | |||
std::string GetOperatingSystemType(void); | |||
/// Load the operating-system-dependent info (file locations, etc). | |||
// | |||
@@ -125,9 +159,6 @@ public: | |||
// | |||
void LoadInfo(); | |||
/// OS specification. | |||
OperatingSystemSpecEnum OsSpec; | |||
/// Postfix main.cf file path. | |||
std::string PostfixMainCfPath; | |||
@@ -150,12 +181,54 @@ public: | |||
// owner. | |||
void UpdateLogDir(); | |||
/// Create or update the rulebase script. | |||
// | |||
// 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. | |||
// | |||
// In either case, the permissions of the rulebase script are | |||
// updated. | |||
// | |||
void CreateUpdateRulebaseScript(); | |||
/// Download the rulebase. | |||
// | |||
void DownloadRulebase(); | |||
/// Update the identity file. | |||
// | |||
// If the credentials were supplied, this method updates the | |||
// identity file with the supplied credentials. | |||
// | |||
// In any case, the owner/group is changed by SetOwnerGroup(), and | |||
// the permissions are changed to readonly for the owner. | |||
// | |||
// \pre Either the identity file must exist, or the credentials | |||
// must be supplied so that the identity file is created. | |||
// | |||
// \see SetOwnerGroup(). | |||
// | |||
void UpdateIdentityFile(void); | |||
/// Process one command-line item. | |||
// | |||
// \param[in] OneInput is the command-line item to process. | |||
// | |||
bool ProcessCommandLineItem(std::string OneInput); | |||
/// Check whether the command-line parameters were specified | |||
/// correctly. | |||
// | |||
// This function check that either both the LicenseID and | |||
// Authentication were specified, or neither were. | |||
// | |||
// \returns if the command-line parameters were specified | |||
// correctly, false otherwise. | |||
bool CommandLineIsOkay(); | |||
/// Output the legal command-line input. | |||
std::string HelpCommandLine(); | |||
@@ -164,7 +237,36 @@ public: | |||
private: | |||
std::string ConfigFile; ///< Configuration file name. | |||
/// 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(); | |||
/// Update the credentials of an existing rulebase script. | |||
// | |||
// This method does the actual work of updating the credentials of | |||
// the rulebase script. | |||
// | |||
// \pre The rulebase script file must exist. | |||
// | |||
// Side effect: The rulebase script is updated. | |||
// | |||
void UpdateRulebaseScriptCredentials(); | |||
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. | |||
bool AuthenticationIsSpecified; ///< true if the Authentication was specified on the command line. | |||
static const std::string RulebaseDownloadCommand; ///< Command to download the rulebase. | |||
static const std::string SampleIgnoreListFile; ///< Sample ignore list file. | |||
static const std::string SampleRulebaseScriptFile; ///< Sample rulebase script file. | |||
@@ -82,8 +82,6 @@ Initialize() { | |||
FileName.push_back("File4.txt"); | |||
FileSize.push_back(203043); | |||
const char *CharPtr = RandomChar.data(); | |||
std::vector<int>::iterator iSize = FileSize.begin(); | |||
for (StringContainer::iterator iFile = FileName.begin(); // Create random data. | |||
@@ -337,6 +335,73 @@ TestFileExists() { | |||
} | |||
bool | |||
TestBackupRestoreWithNoFiles() { | |||
/// Unit under test. | |||
FileBackup TestNoFileBackup; | |||
for (int i = 0; i < NoFileName.size(); i++) { // Backup and overwrite files that don't exist. | |||
TestNoFileBackup.CreateBackupFile(NoFileName[i]); | |||
OverwriteFile(NoFileName[i]); | |||
} | |||
TestNoFileBackup.RestoreAllFilesFromBackup(); | |||
bool ResultIsPass = true; | |||
for (int i = 0; i < NoFileName.size(); i++) { // Check that files don't exist. | |||
if (FileBackup::FileExists(NoFileName[i])) { | |||
std::string Temp; | |||
Temp = "TestBackupRestoreWithNoFiles: File " + NoFileName[i]; | |||
Temp += " was supposed to be deleted by RestoreAllFilesFromBackup, "; | |||
Temp += "but was determined to exist.\n"; | |||
throw std::runtime_error(Temp); | |||
} | |||
} | |||
return ResultIsPass; | |||
} | |||
bool | |||
TestBackupRestoreWithNoFilesNoOverwrite() { | |||
/// Unit under test. | |||
FileBackup TestNoFileBackup; | |||
for (int i = 0; i < NoFileName.size(); i++) { // Backup and overwrite files that don't exist. | |||
TestNoFileBackup.CreateBackupFile(NoFileName[i]); | |||
} | |||
TestNoFileBackup.RestoreAllFilesFromBackup(); | |||
bool ResultIsPass = true; | |||
for (int i = 0; i < NoFileName.size(); i++) { // Check that files don't exist. | |||
if (FileBackup::FileExists(NoFileName[i])) { | |||
std::string Temp; | |||
Temp = "TestBackupRestoreWithNoFilesNoOverwrite: File " + NoFileName[i]; | |||
Temp += " was supposed to be deleted by RestoreAllFilesFromBackup, "; | |||
Temp += "but was determined to exist.\n"; | |||
throw std::runtime_error(Temp); | |||
} | |||
} | |||
return ResultIsPass; | |||
} | |||
void | |||
Finalize() { | |||
@@ -377,6 +442,16 @@ int main(int argc, char* argv[]) { | |||
Finalize(); // Remove test files. | |||
// Test backup/restore with no files. | |||
if (!TestBackupRestoreWithNoFiles()) { | |||
ErrorExit("TestBackupRestoreWithNoFiles() failure.\n"); | |||
} | |||
// Test backup/restore with no files and no overwriting of files. | |||
if (!TestBackupRestoreWithNoFilesNoOverwrite()) { | |||
ErrorExit("TestBackupRestoreWithNoFilesNoOverwrite() failure.\n"); | |||
} | |||
} // That's all folks. | |||
catch(std::exception& e) { // Report any normal exceptions. |
@@ -33,6 +33,24 @@ using namespace std; | |||
// Configuration. //////////////////////////////////////////////////////////////////////////////////////// | |||
////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
// Initialize command to download the rulebase. | |||
#ifdef WIN | |||
// Windows OS. | |||
const std::string SNFIdentityConfig::RulebaseDownloadCommand("FIX THIS"); | |||
#else | |||
// *nix OS. SCRIPT is replaced with the full path of the script run, | |||
// SNIFFER_PATH is replaced with the path of the rulebase. | |||
const std::string SNFIdentityConfig::RulebaseDownloadCommand | |||
("(cd SNIFFER_PATH; touch UpdateReady.txt; chown snfuser UpdateReady.txt; su -m snfuser -c SCRIPT)"); | |||
#endif | |||
const std::string ScriptNameKey("SCRIPT"); ///< Text to replace with script name. | |||
const std::string SnifferPathKey("SNIFFER_PATH"); ///< Text to replace with directory of the rulebase. | |||
const string LicenseSearchString = "LICENSE_ID="; | |||
const string AuthSearchString = "AUTHENTICATION="; | |||
@@ -110,63 +128,6 @@ SNFIdentityConfig::GetCommandLineInput(int argc, char* argv[]) { | |||
} | |||
void | |||
SNFIdentityConfig::CreateIdentityFile() { | |||
ofstream Output; | |||
std::string File = GetIdentityFileName(); | |||
if (Verbose()) { | |||
cout << "Create identity file " << File << "..."; | |||
} | |||
if (!Explain()) { | |||
Output.open(File.c_str()); | |||
if (!Output) { | |||
string 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; | |||
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. | |||
} | |||
void | |||
SNFIdentityConfig::UpdateRulebaseScriptCredentials() { | |||
@@ -174,7 +135,7 @@ SNFIdentityConfig::UpdateRulebaseScriptCredentials() { | |||
if (Verbose()) { | |||
cout << "Update authentication and license ID in the rulebase file " << File << "--\n"; | |||
cout << "Update authentication and license ID in the rulebase download script file " << File << "--\n"; | |||
} | |||
@@ -184,7 +145,7 @@ SNFIdentityConfig::UpdateRulebaseScriptCredentials() { | |||
if (!Input) { | |||
string Temp; | |||
Temp = "Error opening rulebase file " + File; | |||
Temp = "Error opening rulebase download script file " + File; | |||
Temp += " for reading: "; | |||
Temp += strerror(errno); | |||
throw runtime_error(Temp); | |||
@@ -202,7 +163,7 @@ SNFIdentityConfig::UpdateRulebaseScriptCredentials() { | |||
if (FoundLicense) { // Second license line found? | |||
string Temp; | |||
Temp = "Rulebase file " + File; | |||
Temp = "Rulebase sownload script file " + File; | |||
Temp += " has the wrong format: Found two lines beginning with " + LicenseSearchString; | |||
throw runtime_error(Temp); | |||
@@ -224,7 +185,7 @@ SNFIdentityConfig::UpdateRulebaseScriptCredentials() { | |||
if (FoundAuth) { // Second authentication line found? | |||
string Temp; | |||
Temp = "Rulebase file " + File; | |||
Temp = "Rulebase download script file " + File; | |||
Temp += " has the wrong format: Found two lines beginning with " + AuthSearchString; | |||
throw runtime_error(Temp); | |||
} | |||
@@ -247,7 +208,7 @@ SNFIdentityConfig::UpdateRulebaseScriptCredentials() { | |||
if (!FoundLicense || !FoundAuth) { | |||
string Temp; | |||
Temp = "Rulebase file " + File; | |||
Temp = "Rulebase download script file " + File; | |||
Temp += " has the wrong format: Missing required line beginning with '" + LicenseSearchString; | |||
Temp += "' or '" + AuthSearchString; | |||
Temp += "'"; | |||
@@ -257,7 +218,7 @@ SNFIdentityConfig::UpdateRulebaseScriptCredentials() { | |||
if (!Input.eof()) { // Should be at end-of-file. | |||
string Temp; | |||
Temp = "Error reading the rulebase file " + File; | |||
Temp = "Error reading the rulebase download script file " + File; | |||
Temp += ": "; | |||
Temp += strerror(errno); | |||
throw runtime_error(Temp); | |||
@@ -267,7 +228,7 @@ SNFIdentityConfig::UpdateRulebaseScriptCredentials() { | |||
if (Input.bad()) { | |||
string Temp; | |||
Temp = "Error closing the rulebase file " + File; | |||
Temp = "Error closing the rulebase download script file " + File; | |||
Temp += " after reading: "; | |||
Temp += strerror(errno); | |||
throw runtime_error(Temp); | |||
@@ -276,13 +237,15 @@ SNFIdentityConfig::UpdateRulebaseScriptCredentials() { | |||
if (!Explain()) { | |||
SaveFile.CreateBackupFile(File); // Save the existing file. | |||
ofstream Output; // Write the updated contents. | |||
Output.open(File.c_str(), ios::trunc); | |||
if (!Output) { | |||
string Temp; | |||
Temp = "Error opening rulebase file " + File; | |||
Temp = "Error opening rulebase download script file " + File; | |||
Temp += " for writing: "; | |||
Temp += strerror(errno); | |||
throw runtime_error(Temp); | |||
@@ -292,7 +255,7 @@ SNFIdentityConfig::UpdateRulebaseScriptCredentials() { | |||
if (!Output) { | |||
string Temp; | |||
Temp = "Error writing the rulebase file " + File; | |||
Temp = "Error writing the rulebase download script file " + File; | |||
Temp += ": "; | |||
Temp += strerror(errno); | |||
throw runtime_error(Temp); | |||
@@ -302,7 +265,7 @@ SNFIdentityConfig::UpdateRulebaseScriptCredentials() { | |||
if (!Output) { | |||
string Temp; | |||
Temp = "Error closing the rulebase file " + File; | |||
Temp = "Error closing the rulebase download script file " + File; | |||
Temp += " after writing: "; | |||
Temp += strerror(errno); | |||
throw runtime_error(Temp); | |||
@@ -315,3 +278,123 @@ SNFIdentityConfig::UpdateRulebaseScriptCredentials() { | |||
SetMode(File, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); // Set permissions. | |||
} | |||
void | |||
SNFIdentityConfig::DownloadRulebase() { | |||
if (Verbose()) { | |||
std::cout << "Downloading the rulebase..."; | |||
} | |||
std::string Command; | |||
Command = RulebaseDownloadCommand; | |||
std::string::size_type ScriptIndex = Command.find(ScriptNameKey); | |||
if (ScriptIndex != std::string::npos) { // Insert script full path? | |||
Command.replace(ScriptIndex, ScriptNameKey.length(), GetRulebaseScriptName()); | |||
} | |||
std::string::size_type SnifferPathIndex = Command.find(SnifferPathKey); | |||
if (SnifferPathIndex != std::string::npos) { // Insert rulebase location? | |||
Command.replace(SnifferPathIndex, SnifferPathKey.length(), GetRulebasePath()); | |||
} | |||
if (!Explain()) { | |||
SaveFile.CreateBackupFile(GetRulebaseFileName()); | |||
if (std::system(Command.c_str()) != 0) { | |||
string Temp; | |||
Temp = "Error running the command '" + Command; | |||
Temp += "'."; | |||
throw runtime_error(Temp); | |||
} | |||
} | |||
OutputVerboseEnd(); | |||
} | |||
void | |||
SNFIdentityConfig::CreateIdentityFile() { | |||
ofstream Output; | |||
std::string File = GetIdentityFileName(); | |||
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); | |||
} | |||
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. | |||
} | |||
string | |||
SNFIdentityConfig::GetRulebaseFileName(void) { | |||
std::string Name; | |||
Name = GetRulebasePath(); | |||
Name += LicenseID + ".snf"; | |||
return Name; | |||
} |
@@ -58,6 +58,15 @@ public: | |||
// | |||
bool GetCommandLineInput(int argc, char* argv[]); | |||
#if 0 | |||
/// Update the rulebase script with the credentials. | |||
// | |||
void UpdateRulebaseScriptCredentials(); | |||
/// Download the rulebase. | |||
// | |||
void DownloadRulebase(); | |||
/// Create the identity file. | |||
// | |||
// The file is created, the owner/group is changed by SetOwnerGroup(), | |||
@@ -67,15 +76,20 @@ public: | |||
// | |||
void CreateIdentityFile(); | |||
/// Update the rulebase script with the credentials. | |||
// | |||
void UpdateRulebaseScriptCredentials(); | |||
private: | |||
/// Return the rulebase file name. | |||
// | |||
// \returns the name of the rulebase file, including the path. | |||
// | |||
std::string GetRulebaseFileName(); | |||
std::string LicenseID; ///< License ID string. | |||
std::string Authentication; ///< Authentication string. | |||
static const std::string RulebaseDownloadCommand; ///< Command to download the rulebase. | |||
#endif | |||
}; | |||
#endif |
@@ -51,6 +51,22 @@ const size_t DefaultConfigFileSize = sizeof DefaultConfigFile / sizeof DefaultCo | |||
// End of configuration. ///////////////////////////////////////////////////////////////////////////////// | |||
////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
void RestoreFiles(SNFIdentityConfig *Config) { | |||
try { | |||
cerr << "Restoring all configuration files..."; | |||
Config->SaveFile.RestoreAllFilesFromBackup(); | |||
cerr << "done.\n"; | |||
} | |||
catch(exception& e) { | |||
cerr << "SNFIdentityConfig::SaveFile Exception: " << e.what() << endl; | |||
} | |||
} | |||
int main(int argc, char* argv[]) { | |||
SNFIdentityConfig SnfIdentityConfig; | |||
@@ -82,21 +98,26 @@ int main(int argc, char* argv[]) { | |||
DefaultConfigFileSize); // config file specified on the | |||
// command line, or the default file. | |||
SnfIdentityConfig.CreateIdentityFile(); | |||
SnfIdentityConfig.UpdateRulebaseScriptCredentials(); | |||
SnfIdentityConfig.DownloadRulebase(); | |||
SnfIdentityConfig.CreateIdentityFile(); | |||
} // That's all folks. | |||
catch(exception& e) { // Report any normal exceptions. | |||
cerr << "SNFIdentity Exception: " << e.what() << endl; | |||
RestoreFiles(&SnfIdentityConfig); | |||
} | |||
catch (snfCFGmgr::LoadFailure) { // Error loading configuration file. | |||
cerr << "snfCFGmgr Exception: Unable to load the configuration file " | |||
<< SnfIdentityConfig.GetConfigFileName() << endl; | |||
RestoreFiles(&SnfIdentityConfig); | |||
} | |||
catch(...) { // Report any unexpected exceptions. | |||
cerr << "SNFIdentity Panic! Unknown Exception!" << endl; | |||
RestoreFiles(&SnfIdentityConfig); | |||
} | |||
return 0; // Normally we return zero. |
@@ -9,22 +9,15 @@ | |||
// | |||
/////////////////////////////////////////////////////////////////////////////////////////////////// | |||
#include <errno.h> | |||
#include <string.h> | |||
#include <unistd.h> | |||
#include <sys/types.h> | |||
#include <pwd.h> | |||
#include <sys/types.h> | |||
#include <sys/stat.h> | |||
#include <unistd.h> | |||
#include <cstdlib> | |||
#include <cerrno> | |||
#include <cstring> | |||
#include <iostream> | |||
#include <exception> | |||
#include <stdexcept> | |||
#include <sstream> | |||
#include <fstream> | |||
#include <vector> | |||
#include "PostfixIntegrate.hpp" | |||
@@ -43,30 +36,37 @@ const std::string SnfMilterMainCfIntegrationString("smtpd_milters = unix:/var/sn | |||
void | |||
PostfixIntegrate::SetOperatingSystem(std::string OperatingSystemType) { | |||
MtaIsRunningCommand = "ps -axl root | grep -v grep | grep -q 'postfix/master'"; | |||
if ("OpenBSD" == OperatingSystemType) { | |||
PostfixMainCfPath = "/usr/local/etc/postfix/main.cf"; | |||
PostfixMasterCfPath = "/usr/local/etc/postfix/master.cf"; | |||
ReloadMtaCommand = "/usr/local/sbin/postfix reload"; | |||
} else if ("FreeBSD" == OperatingSystemType) { | |||
PostfixMainCfPath = "/etc/postfix/main.cf"; | |||
PostfixMasterCfPath = "/etc/postfix/master.cf"; | |||
ReloadMtaCommand = "/usr/local/sbin/postfix reload"; | |||
} else if ("Ubuntu" == OperatingSystemType) { | |||
PostfixMainCfPath = "/etc/postfix/main.cf"; | |||
PostfixMasterCfPath = "/etc/postfix/master.cf"; | |||
ReloadMtaCommand = "/usr/sbin/postfix reload"; | |||
} else if ("RedHat" == OperatingSystemType) { | |||
PostfixMainCfPath = "/etc/postfix/main.cf"; | |||
PostfixMasterCfPath = "/etc/postfix/master.cf"; | |||
ReloadMtaCommand = "/usr/sbin/postfix reload"; | |||
} else if ("Suse" == OperatingSystemType) { | |||
PostfixMainCfPath = "/etc/postfix/main.cf"; | |||
PostfixMasterCfPath = "/etc/postfix/master.cf"; | |||
ReloadMtaCommand = "/usr/sbin/postfix reload"; | |||
} else { | |||
@@ -99,6 +99,8 @@ PostfixIntegrate::Integrate(FileBackup *SaveFile) { | |||
if (!Explain()) { | |||
SaveFile->CreateBackupFile(PostfixMainCfPath); // Save any existing file. | |||
std::ofstream Output; // Append the configuration. | |||
Output.open(PostfixMainCfPath.c_str(), std::ios::app); | |||
@@ -155,95 +157,155 @@ PostfixIntegrate::Unintegrate(FileBackup *SaveFile) { | |||
} | |||
Input.open(PostfixMainCfPath.c_str()); // Read the contents. | |||
if (!Input) { | |||
std::string Temp; | |||
Temp = "Error opening the postfix configuration file " + PostfixMainCfPath; | |||
Temp += " for reading: "; | |||
Temp += strerror(errno); | |||
throw std::runtime_error(Temp); | |||
} | |||
std::string Content; | |||
std::string Line; | |||
while (getline(Input, Line)) { | |||
if (std::string::npos != Line.find(SnfMilterMainCfSearchString)) { // Check for integration line. | |||
if (Verbose()) { | |||
if (!Explain()) { | |||
std::cout << " Remove '" << Line << "'...\n"; | |||
SaveFile->CreateBackupFile(PostfixMainCfPath); // Save any existing file. | |||
} | |||
continue; // Do not copy this line. | |||
Input.open(PostfixMainCfPath.c_str()); // Read the contents. | |||
if (!Input) { | |||
std::string Temp; | |||
Temp = "Error opening the postfix configuration file " + PostfixMainCfPath; | |||
Temp += " for reading: "; | |||
Temp += strerror(errno); | |||
throw std::runtime_error(Temp); | |||
} | |||
Content += Line + "\n"; // Copy this line. | |||
} | |||
std::string Content; | |||
std::string Line; | |||
if (!Input.eof()) { // Should be at end-of-file. | |||
std::string Temp; | |||
while (getline(Input, Line)) { | |||
Temp = "Error reading the postfix configuration file " + PostfixMainCfPath; | |||
Temp += ": "; | |||
Temp += strerror(errno); | |||
throw std::runtime_error(Temp); | |||
} | |||
if (std::string::npos != Line.find(SnfMilterMainCfSearchString)) { // Check for integration line. | |||
Input.close(); | |||
if (Input.bad()) { | |||
std::string Temp; | |||
if (Verbose()) { | |||
Temp = "Error closing the postfix configuration file " + PostfixMainCfPath; | |||
Temp += " after reading: "; | |||
Temp += strerror(errno); | |||
throw std::runtime_error(Temp); | |||
} | |||
std::cout << " Remove '" << Line << "'...\n"; | |||
if (!Explain()) { | |||
} | |||
continue; // Do not copy this line. | |||
std::ofstream Output; // Write the updated contents. | |||
} | |||
Output.open(PostfixMainCfPath.c_str(), std::ios::trunc); | |||
if (!Output) { | |||
std::string Temp; | |||
Content += Line + "\n"; // Copy this line. | |||
Temp = "Error opening the postfix configuration file " + PostfixMainCfPath; | |||
Temp += " for writing: "; | |||
Temp += strerror(errno); | |||
throw std::runtime_error(Temp); | |||
} | |||
Output << Content; | |||
if (!Output) { | |||
if (!Input.eof()) { // Should be at end-of-file. | |||
std::string Temp; | |||
Temp = "Error writing the postfix configuration file " + PostfixMainCfPath; | |||
Temp = "Error reading the postfix configuration file " + PostfixMainCfPath; | |||
Temp += ": "; | |||
Temp += strerror(errno); | |||
throw std::runtime_error(Temp); | |||
} | |||
Output.close(); | |||
if (!Output) { | |||
Input.close(); | |||
if (Input.bad()) { | |||
std::string Temp; | |||
Temp = "Error closing the postfix configuration file " + PostfixMainCfPath; | |||
Temp += " after writing: "; | |||
Temp += " after reading: "; | |||
Temp += strerror(errno); | |||
throw std::runtime_error(Temp); | |||
} | |||
if (!Explain()) { | |||
std::ofstream Output; // Write the updated contents. | |||
Output.open(PostfixMainCfPath.c_str(), std::ios::trunc); | |||
if (!Output) { | |||
std::string Temp; | |||
Temp = "Error opening the postfix configuration file " + PostfixMainCfPath; | |||
Temp += " for writing: "; | |||
Temp += strerror(errno); | |||
throw std::runtime_error(Temp); | |||
} | |||
Output << Content; | |||
if (!Output) { | |||
std::string Temp; | |||
Temp = "Error writing the postfix configuration file " + PostfixMainCfPath; | |||
Temp += ": "; | |||
Temp += strerror(errno); | |||
throw std::runtime_error(Temp); | |||
} | |||
Output.close(); | |||
if (!Output) { | |||
std::string Temp; | |||
Temp = "Error closing the postfix configuration file " + PostfixMainCfPath; | |||
Temp += " after writing: "; | |||
Temp += strerror(errno); | |||
throw std::runtime_error(Temp); | |||
} | |||
} | |||
} | |||
OutputVerboseEnd(); | |||
} | |||
bool | |||
PostfixIntegrate::MtaIsRunningDetected() { | |||
if (Verbose()) { | |||
std::cout << "Checking whether postfix is detected to be running..."; | |||
} | |||
bool IsRunningDetected; | |||
IsRunningDetected = (std::system(MtaIsRunningCommand.c_str()) == 0); | |||
if (Verbose()) { | |||
std::cout << (IsRunningDetected ? "yes" : "no"); | |||
} | |||
OutputVerboseEnd(); | |||
return IsRunningDetected; | |||
} | |||
bool | |||
PostfixIntegrate::ReloadMta() { | |||
if (Verbose()) { | |||
std::cout << "Reloading postfix..."; | |||
} | |||
bool Succeeded; | |||
if (!Explain()) { | |||
Succeeded = (std::system(ReloadMtaCommand.c_str()) == 0); | |||
if (Verbose()) { | |||
std::cout << (Succeeded ? "succeeded" : "failed"); | |||
} | |||
} | |||
OutputVerboseEnd(); | |||
return Succeeded; | |||
} | |||
bool | |||
PostfixIntegrate::IsIntegrated() { | |||
@@ -29,6 +29,10 @@ public: | |||
virtual void Unintegrate(FileBackup *SaveFile); | |||
virtual bool MtaIsRunningDetected(); | |||
virtual bool ReloadMta(); | |||
private: | |||
virtual bool IsIntegrated(); | |||
@@ -39,6 +43,12 @@ private: | |||
/// Postfix master.cf file path. | |||
std::string PostfixMasterCfPath; | |||
/// Command to determine whether postfix is running. | |||
std::string MtaIsRunningCommand; | |||
/// Command to reload postfix. | |||
std::string ReloadMtaCommand; | |||
}; | |||
#endif |
@@ -38,25 +38,27 @@ using namespace std; | |||
// Windows OS. | |||
const std::string SNFMilterConfig::DefaultConfigFile("C:\\SNF\\SNFMilter.xml"); | |||
const std::string SNFMilterConfig::DefaultSampleConfigFile("C:\\SNF\\SNFMilter.xml.sample"); | |||
const std::string SNFMilterConfig::SampleConfigFile("C:\\SNF\\SNFMilter.xml.sample"); | |||
const std::string SNFMilterConfig::SampleIdentityFile("C:\\SNF\\identity.xml.sample"); | |||
#else | |||
#ifdef DEFAULT_CONFIG_DIR | |||
// *nix, DEFAULT_CONFIG_DIR is specified on the compile command line. | |||
const std::string SNFMilterConfig::DefaultConfigFile(DEFAULT_CONFIG_DIR "/snf-milter/SNFMilter.xml"); | |||
const std::string SNFMilterConfig::DefaultSampleConfigFile(DEFAULT_CONFIG_DIR "/snf-milter/SNFMilter.xml.sample"); | |||
const std::string SNFMilterConfig::SampleConfigFile(DEFAULT_CONFIG_DIR "/snf-milter/SNFMilter.xml.sample"); | |||
const std::string SNFMilterConfig::SampleIdentityFile(DEFAULT_CONFIG_DIR "/snf-milter/identity.xml.sample"); | |||
#else | |||
// Not Windows, and DEFAULT_CONFIG_DIR is not specified on the compile | |||
// command line. In this case, we don't know the default path for the | |||
// configuration file. | |||
const std::string SNFMilterConfig::DefaultConfigFile(""); | |||
const std::string SNFMilterConfig::DefaultSampleConfigFile(""); | |||
const std::string SNFMilterConfig::SampleConfigFile(""); | |||
const std::string SNFMilterConfig::SampleIdentityFile(""); | |||
#endif | |||
#endif | |||
const string ConfigFileKey("-config="); | |||
const string IntegrateWithNoneKey("-mta=none"); | |||
const string IntegrateWithPostfixKey("-mta=postfix"); | |||
const string IntegrateWithSendmailKey("-mta=sendmail"); | |||
@@ -76,20 +78,23 @@ SNFMilterConfig::DisplayHelp(std::string Version) { | |||
<< Version << endl | |||
<< "Copyright (C) 2012, ARM Research Labs, LLC (www.armresearch.com)\n\n" | |||
<< "Usage:\n\n" | |||
<< "SNFMilterConfig [" << ConfigFileKey << "snf-config-file] " | |||
<< "SNFMilterConfig " | |||
<< IntegrateWithPostfixKey << " | " | |||
<< IntegrateWithSendmailKey << " | " | |||
<< IntegrateWithNoneKey << " " | |||
<< UtilityConfig::HelpCommandLine() << "\n\n" | |||
<< "SNFMilterConfig creates the configuration files (snf-config-file and the ignore list file) and the\n" | |||
<< "rulebase download script (default: getRulebase) if they don't exist.\n\n" | |||
<< " -config=snf-config-file Specifies the configuration file\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" | |||
<< "If snf-config-file is not specified, then the following file is used:\n\n" | |||
<< " " << DefaultConfigFile << "\n\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" | |||
<< "copied from the following file:\n\n" | |||
<< " " << SampleConfigFile << "\n\n"; | |||
}; | |||
@@ -99,29 +104,26 @@ SNFMilterConfig::GetCommandLineInput(int argc, char* argv[]) { | |||
int i; | |||
int NumCommandsFound = 0; | |||
string OneInput; | |||
string ConfigFile; | |||
MtaCommand = NoCommand; // Default is to do nothing. | |||
for (i = 1; i < argc; i++) { // Check each input. | |||
OneInput = argv[i]; | |||
if (0 == OneInput.find(ConfigFileKey)) { | |||
ConfigFile = OneInput.substr(ConfigFileKey.length()); | |||
if (OneInput == IntegrateWithNoneKey) { | |||
} else if (OneInput == IntegrateWithNoneKey) { | |||
Command = IntegrateWithNoneCmd; | |||
MtaCommand = IntegrateWithNoneCmd; | |||
NumCommandsFound++; | |||
} else if (OneInput == IntegrateWithPostfixKey) { | |||
Command = IntegrateWithPostfixCmd; | |||
MtaCommand = IntegrateWithPostfixCmd; | |||
NumCommandsFound++; | |||
} else if (0 == OneInput.find(IntegrateWithSendmailKey)) { | |||
Command = IntegrateWithSendmailCmd; | |||
MtaCommand = IntegrateWithSendmailCmd; | |||
NumCommandsFound++; | |||
} else { | |||
@@ -137,17 +139,6 @@ SNFMilterConfig::GetCommandLineInput(int argc, char* argv[]) { | |||
} | |||
if (0 == ConfigFile.length()) { // Load default config file name. | |||
ConfigFile = DefaultConfigFile; | |||
} | |||
LoadConfigFile(ConfigFile); | |||
LoadInfo(); // Load the file paths. | |||
LoadSocketInfo(); // Load the socket path. | |||
return (NumCommandsFound == 1); | |||
} | |||
@@ -204,20 +195,46 @@ SNFMilterConfig::CreateSocketDir() { | |||
} | |||
void | |||
SNFMilterConfig::UpdateConfigFiles() { | |||
SNFMilterConfig::CreateLoadConfig() { | |||
CheckAndSetConfigFileName(&DefaultConfigFile, 1); // Load the config file name. | |||
if (!Explain()) { | |||
std::string ConfigFileName = GetConfigFileName(); | |||
SaveFile.CreateBackupFile(GetConfigFileName()); | |||
SaveFile.CreateBackupFile(ConfigFileName); // Save any existing file. | |||
} | |||
CreateDefaultConfigFile(SampleConfigFile); // Create the file if it doesn't exist. | |||
LoadConfig(); | |||
LoadInfo(); // Load the file paths. | |||
LoadSocketInfo(); // Load the socket path. | |||
if (!FileExists(ConfigFileName)) { | |||
} | |||
Copy(DefaultSampleConfigFile, ConfigFileName); // Use SNFMilter.xml.sample. | |||
void | |||
SNFMilterConfig::SaveFileState() { | |||
if (!Explain()) { | |||
SaveFile.CreateBackupFile(GetRulebaseScriptName()); | |||
SaveFile.CreateBackupFile(GetRulebaseFileName()); | |||
SaveFile.CreateBackupFile(GetIdentityFileName()); | |||
SaveFile.CreateBackupFile(GetIgnoreListFileName()); | |||
} | |||
SetMode(ConfigFileName, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); // Set permissions. | |||
SetOwnerGroup(ConfigFileName); // Set to sniffer user. | |||
} | |||
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(); | |||
@@ -227,7 +244,10 @@ SNFMilterConfig::UpdateConfigFiles() { | |||
void | |||
SNFMilterConfig::DoIntegrationCommand() { | |||
switch (Command) { | |||
switch (MtaCommand) { | |||
case NoCommand: | |||
break; | |||
case IntegrateWithNoneCmd: | |||
UnintegrateWithAllExcept(); | |||
@@ -249,7 +269,7 @@ SNFMilterConfig::DoIntegrationCommand() { | |||
ostringstream Temp; | |||
Temp << "Internal error in SNFMilterConfig::DoIntegrationCommand: Invalid value of command: " | |||
<< Command; | |||
<< MtaCommand; | |||
throw runtime_error(Temp.str()); | |||
@@ -276,174 +296,3 @@ SNFMilterConfig::UnintegrateWithAllExcept(std::string Except) { | |||
#endif | |||
} | |||
void | |||
SNFMilterConfig::IntegrateWithPostfix() { | |||
// UnintegrateWithAll(); // Remove any existing integration. | |||
if (Verbose()) { | |||
cout << "Add to postfix file " << PostfixMainCfPath << ": '" | |||
<< SnfMilterMainCfIntegrationString << "'..."; | |||
} | |||
if (!Explain()) { | |||
ofstream Output; // Append the configuration. | |||
Output.open(PostfixMainCfPath.c_str(), ios::app); | |||
if (!Output) { | |||
string Temp; | |||
Temp = "Error opening the postfix configuration file " + PostfixMainCfPath; | |||
Temp += " for writing: "; | |||
Temp += strerror(errno); | |||
throw runtime_error(Temp); | |||
} | |||
Output << SnfMilterMainCfIntegrationString << "\n"; | |||
if (!Output) { | |||
string Temp; | |||
Temp = "Error appending to the postfix configuration file " + PostfixMainCfPath; | |||
Temp += ": "; | |||
Temp += strerror(errno); | |||
throw runtime_error(Temp); | |||
} | |||
Output.close(); | |||
if (!Output) { | |||
string Temp; | |||
Temp = "Error closing the postfix configuration file " + PostfixMainCfPath; | |||
Temp += " after appending: "; | |||
Temp += strerror(errno); | |||
throw runtime_error(Temp); | |||
} | |||
} | |||
OutputVerboseEnd(); | |||
CreateSocketDir(); | |||
StartOrRestartMta("postfix"); | |||
} | |||
void | |||
SNFMilterConfig::UnintegrateWithPostfix() { | |||
ifstream Input; | |||
if (Verbose()) { | |||
cout << "Remove any integration in postfix file " << PostfixMainCfPath << "--\n"; | |||
} | |||
Input.open(PostfixMainCfPath.c_str()); // Read the contents. | |||
if (!Input) { | |||
string Temp; | |||
Temp = "Error opening the postfix configuration file " + PostfixMainCfPath; | |||
Temp += " for reading: "; | |||
Temp += strerror(errno); | |||
throw runtime_error(Temp); | |||
} | |||
string Content; | |||
string Line; | |||
while (getline(Input, Line)) { | |||
if (string::npos != Line.find(SnfMilterMainCfSearchString)) { // Check for integration line. | |||
if (Verbose()) { | |||
cout << " Remove '" << Line << "'...\n"; | |||
} | |||
continue; // Do not copy this line. | |||
} | |||
Content += Line + "\n"; // Copy this line. | |||
} | |||
if (!Input.eof()) { // Should be at end-of-file. | |||
string Temp; | |||
Temp = "Error reading the postfix configuration file " + PostfixMainCfPath; | |||
Temp += ": "; | |||
Temp += strerror(errno); | |||
throw runtime_error(Temp); | |||
} | |||
Input.close(); | |||
if (Input.bad()) { | |||
string Temp; | |||
Temp = "Error closing the postfix configuration file " + PostfixMainCfPath; | |||
Temp += " after reading: "; | |||
Temp += strerror(errno); | |||
throw runtime_error(Temp); | |||
} | |||
if (!Explain()) { | |||
ofstream Output; // Write the updated contents. | |||
Output.open(PostfixMainCfPath.c_str(), ios::trunc); | |||
if (!Output) { | |||
string Temp; | |||
Temp = "Error opening the postfix configuration file " + PostfixMainCfPath; | |||
Temp += " for writing: "; | |||
Temp += strerror(errno); | |||
throw runtime_error(Temp); | |||
} | |||
Output << Content; | |||
if (!Output) { | |||
string Temp; | |||
Temp = "Error writing the postfix configuration file " + PostfixMainCfPath; | |||
Temp += ": "; | |||
Temp += strerror(errno); | |||
throw runtime_error(Temp); | |||
} | |||
Output.close(); | |||
if (!Output) { | |||
string Temp; | |||
Temp = "Error closing the postfix configuration file " + PostfixMainCfPath; | |||
Temp += " after writing: "; | |||
Temp += strerror(errno); | |||
throw runtime_error(Temp); | |||
} | |||
} | |||
OutputVerboseEnd(); | |||
} | |||
void | |||
SNFMilterConfig::IntegrateWithSendmail() { | |||
throw runtime_error("Integration with sendmail is not implemented"); | |||
} | |||
void | |||
SNFMilterConfig::UnintegrateWithSendmail() { | |||
std::cerr << "Unintegration with sendmail is not implemented" << "\n"; | |||
} |
@@ -28,7 +28,8 @@ class SNFMilterConfig : public UtilityConfig { | |||
public: | |||
/// Command. | |||
enum CommandEnum { | |||
enum MtaCommandEnum { | |||
NoCommand, ///< Take no MTA integration/unintegration action. | |||
IntegrateWithNoneCmd, ///< Remove integration with all MTAs. | |||
IntegrateWithPostfixCmd, ///< Integrate with postfix. | |||
IntegrateWithSendmailCmd ///< Integrate with sendmail. | |||
@@ -52,6 +53,25 @@ public: | |||
// | |||
bool GetCommandLineInput(int argc, char* argv[]); | |||
/// Load the configuration, creating default configuration if necessary. | |||
// | |||
// This method load the configuration specified in the command | |||
// line, or the default config file. If the config file to load | |||
// doesn't exit, the config file is created by copying from the | |||
// sample config file. | |||
// | |||
// Side effect: The state of the config file is saved. | |||
// | |||
// Side effect: If the config file doesn't exist, a new config | |||
// file is created. | |||
// | |||
void CreateLoadConfig(void); | |||
/// Save the state of all files that might be changed, except the | |||
/// config file. | |||
// | |||
void SaveFileState(void); | |||
/// Create or update the configuration files. | |||
// | |||
// The SNFMilter.xml and GBUdbIgnoreList.txt files are created if | |||
@@ -74,15 +94,7 @@ private: | |||
PostfixIntegrate Postfix; ///< Postfix integration object. | |||
void IntegrateWithPostfix(); ///< Integrate with postfix. | |||
void UnintegrateWithPostfix(); ///< Unintegrate with postfix. | |||
void IntegrateWithSendmail(); ///< Integrate with sendmail. | |||
void UnintegrateWithSendmail(); ///< Unintegrate with sendmail. | |||
///< Unintegrate with MTAs. | |||
/// Unintegrate with MTAs. | |||
// | |||
// Unintegrate with all MTAs except the specified MTA. | |||
// | |||
@@ -99,11 +111,13 @@ private: | |||
// | |||
void UnintegrateWithAllExcept(std::string Except = ""); | |||
CommandEnum Command; ///< Specified command. | |||
MtaCommandEnum MtaCommand; ///< Specified MTA integration/unintegration command. | |||
static const std::string DefaultConfigFile; ///< Default config file. | |||
static const std::string DefaultSampleConfigFile; ///< Sample config file. | |||
static const std::string SampleConfigFile; ///< Sample config file. | |||
static const std::string SampleIdentityFile; ///< Sample identity file. | |||
std::string SocketFileName; | |||
@@ -41,6 +41,22 @@ const char* SNF_MILTERCONFIG_VERSION = "SNFMilterConfig 0.0.1 Build: " __DATE__ | |||
// End of configuration. ///////////////////////////////////////////////////////////////////////////////// | |||
////////////////////////////////////////////////////////////////////////////////////////////////////////// | |||
void RestoreFiles(SNFMilterConfig *Config) { | |||
try { | |||
cerr << "Restoring all configuration files..."; | |||
Config->SaveFile.RestoreAllFilesFromBackup(); | |||
cerr << "done.\n"; | |||
} | |||
catch(exception& e) { | |||
cerr << "SNFMilterConfig::SaveFile Exception: " << e.what() << endl; | |||
} | |||
} | |||
int main(int argc, char* argv[]) { | |||
SNFMilterConfig SnfMilterConfig; | |||
@@ -66,8 +82,19 @@ int main(int argc, char* argv[]) { | |||
try { // Catch anything that breaks loose. | |||
SnfMilterConfig.UpdateConfigFiles(); // Create config files if they don't | |||
// exist, or update config files. | |||
SnfMilterConfig.CreateLoadConfig(); // Save config file state and load config. | |||
// Load the default if necessary. | |||
SnfMilterConfig.SaveFileState(); // Save state of all other files. | |||
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. | |||
@@ -75,14 +102,18 @@ int main(int argc, char* argv[]) { | |||
catch(exception& e) { // Report any normal exceptions. | |||
cerr << "SNFMilterConfig Exception: " << e.what() << endl; | |||
RestoreFiles(&SnfMilterConfig); | |||
} | |||
catch (snfCFGmgr::LoadFailure) { // Error loading configuration file. | |||
cerr << "snfCFGmgr Exception: Unable to load the configuration file " | |||
<< SnfMilterConfig.GetConfigFileName() << endl; | |||
RestoreFiles(&SnfMilterConfig); | |||
} | |||
catch(...) { // Report any unexpected exceptions. | |||
cerr << "SNFMilterConfig Panic! Unknown Exception!" << endl; | |||
RestoreFiles(&SnfMilterConfig); | |||
} | |||
return 0; // Normally we return zero. | |||
} |