소스 검색

Moved SNFIdentity functionality to SNFMilterConfig.

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-2d8eab27ff7c
master
adeniz 12 년 전
부모
커밋
06b2ca5907

+ 17
- 10
Common/FileBackup.cpp 파일 보기

@@ -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;
}
}

+ 0
- 2
Common/MtaIntegrate.cpp 파일 보기

@@ -9,8 +9,6 @@
//
///////////////////////////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include "MtaIntegrate.hpp"
MtaIntegrate::MtaIntegrate() {

+ 17
- 0
Common/MtaIntegrate.hpp 파일 보기

@@ -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.

+ 30
- 2
Common/Utility.cpp 파일 보기

@@ -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) {

+ 13
- 2
Common/Utility.hpp 파일 보기

@@ -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.

+ 440
- 67
Common/UtilityConfig.cpp 파일 보기

@@ -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";

+ 134
- 32
Common/UtilityConfig.hpp 파일 보기

@@ -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.

+ 77
- 2
CommonTests/TestFileBackup.cpp 파일 보기

@@ -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.

+ 150
- 67
SNFIdentity/SNFIdentityConfig.cpp 파일 보기

@@ -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;
}

+ 18
- 4
SNFIdentity/SNFIdentityConfig.hpp 파일 보기

@@ -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

+ 23
- 2
SNFIdentity/main.cpp 파일 보기

@@ -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.

+ 126
- 64
SNFMilterConfig/PostfixIntegrate.cpp 파일 보기

@@ -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() {

+ 10
- 0
SNFMilterConfig/PostfixIntegrate.hpp 파일 보기

@@ -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

+ 59
- 210
SNFMilterConfig/SNFMilterConfig.cpp 파일 보기

@@ -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";
}

+ 26
- 12
SNFMilterConfig/SNFMilterConfig.hpp 파일 보기

@@ -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;

+ 33
- 2
SNFMilterConfig/main.cpp 파일 보기

@@ -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.
}

Loading…
취소
저장