Przeglądaj źródła

Initial revision. SNFIdentity and SNFMilterConfig are functional (for

integrating/unintegrating with postfix), but backup/restore of
configuration files is not implemented.  Also, SNFIdentity does not
download a new rulebase.


git-svn-id: https://svn.microneil.com/svn/SNFUtility/trunk@2 aa37657e-1934-4a5f-aa6d-2d8eab27ff7c
master
adeniz 13 lat temu
rodzic
commit
9fb8373620

+ 0
- 0
Common/ChangeLog Wyświetl plik


+ 29
- 0
Common/Makefile.am Wyświetl plik

@@ -0,0 +1,29 @@
## Process this file with automake to produce Makefile.in
##
## $Id$
##
##
## Author: Alban Deniz
##
## Copyright (C) 2011 by MicroNeil Corporation. All rights reserved.
##

CXXFLAGS = $(SNF_CXXFLAGS) -I@top_srcdir@/SNFMulti \
-DSNF_OSTYPE=\"$(SNF_OSTYPE)\" -DDEFAULT_DATA_DIR=\"@datadir@/$(PACKAGE_NAME)\" \
-DSBIN_DIR=\"$(DESTDIR)$(sbindir)\"

noinst_LIBRARIES = \
libUtilityCommon.a

libUtilityCommon_a_SOURCES = \
@top_srcdir@/SNFUtility/Common/UtilityConfig.cpp

noinst_HEADERS = \
@top_srcdir@/SNFUtility/Common/UtilityConfig.hpp

EXTRA_DIST = \
Makefile.am \
ChangeLog

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

+ 710
- 0
Common/UtilityConfig.cpp Wyświetl plik

@@ -0,0 +1,710 @@
// UtilityConfig.cpp
//
// Copyright (C) 2011, ARM Research Labs, LLC.
// See www.armresearch.com for the copyright terms.
//
// This file implements the common functionality for the configuration
// utilities.
#include <cerrno>
#include <cstring>
#include <unistd.h>
#include <pwd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdexcept>
#include <sstream>
#include <iostream>
#include <fstream>
#include <vector>
#include "UtilityConfig.hpp"
using namespace std;
//////////////////////////////////////////////////////////////////////////////////////////////////////////
// Configuration. ////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////
// Initialize sample ignore list file path.
#ifdef WIN
// Windows OS.
const std::string UtilityConfig::SampleIgnoreListFile("C:\\SNF\\GBUdbIgnoreList.txt.sample");
#else
#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");
#else
// Not Windows, and DEFAULT_DATA_DIR is not specified on the compile
// command line. In this case, we don't know the path for the sample
// ignore list file.
#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");
#else
// Not Windows, and SBIN_DIR is not specified on the compile
// command line. In this case, we don't know the path for the sample
// ignore list file.
#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");
const std::string DirectorySeparator("\\");
#else
const std::string DirectorySeparator("/");
#ifdef SNF_OSTYPE
// *nix, SNF_OSTYPE is specified on the compile command line.
const std::string UtilityConfig::OperatingSystemType(SNF_OSTYPE);
#else
// Not Windows, and SNF_OSTYPE is not specified on the compile command
// line. In this case, we don't know the operating system.
#error SNF_OSTYPE must be defined by -DSNF_OSTYPE="..." when compiling.
#endif
#endif
/// SNF user name.
const string SNFUserName = "snfuser";
/// SNF group name.
const string SNFGroupName = "snfuser";
/// Verbose command-line input.
const string VerboseKey("-v");
/// Explain command-line input.
const string ExplainKey("-explain");
/// Help command-line input.
const string HelpKey("-h");
const std::string UtilityConfig::BackupSuffix("_snf_backup");
//////////////////////////////////////////////////////////////////////////////////////////////////////////
// End of configuration. /////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////
UtilityConfig::UtilityConfig() :
ExplainRequested(false), VerboseRequested(false), HelpRequested(false) {
}
bool
UtilityConfig::FileExists(const std::string File) {
if (Verbose()) {
cout << "Check whether " << File << " exists...";
}
struct stat StatBuf;
if (0 != stat(File.c_str(), &StatBuf)) { // Error checking whether file exists.
if (ENOENT == errno) { // Doesn't exist.
OutputVerboseEnd();
return false;
}
string Temp; // Other error from stat().
Temp = "Error getting info for file " + File;
Temp += ": ";
Temp += strerror(errno);
throw runtime_error(Temp);
}
OutputVerboseEnd();
return true;
}
void
UtilityConfig::CheckAndLoadConfigFile(const std::string DefaultFile[], int NumDefaultFiles) {
string ProvisionalConfigFile = ConfigFile;
if (ProvisionalConfigFile.length() == 0) {
int i;
vector<string> FoundFile;
for (i = 0; i < NumDefaultFiles; i++) {
if (!FileExists(DefaultFile[i])) {
continue; // File doesn't exist.
}
FoundFile.push_back(DefaultFile[i]); // Update list of found files.
ProvisionalConfigFile = DefaultFile[i]; // Found configuration file.
}
if (0 == FoundFile.size()) { // No default file found.
string Temp;
Temp = "Configuration file was not specified, and no default configuration file was found. ";
Temp += "Checked:\n\n";
for (i = 0; i < NumDefaultFiles; i++) {
Temp += " ";
Temp += DefaultFile[i] + "\n";
}
throw runtime_error(Temp);
}
if (FoundFile.size() > 1) { // No default file found.
string Temp;
Temp = "Configuration file was not specified, and more than one default configuration file was found::\n\n";
for (i = 0; i < FoundFile.size(); i++) {
Temp += " ";
Temp += FoundFile[i] + "\n";
}
throw runtime_error(Temp);
}
}
LoadConfigFile(ProvisionalConfigFile);
}
void
UtilityConfig::LoadConfigFile(std::string Name) {
SetConfigFileName(Name);
if (Verbose()) {
cout << "Using configuration file " << ConfigFile << ".\n";
}
// Load the data.
try {
CFGData.initializeFromFile(GetConfigFileName().c_str());
} catch(...) {
string Temp;
Temp = "Error reading configuration file " + GetConfigFileName();
Temp += ".";
throw runtime_error(Temp);
}
if ( (CFGData.paths_workspace_path.length() == 0) ||
(CFGData.paths_rulebase_path.length() == 0) ||
(CFGData.paths_log_path.length() == 0) ||
(CFGData.update_script_call.length() == 0) ||
(CFGData.node_identity.length() == 0) ) {
string Temp;
Temp = "The configuration file " + GetConfigFileName();
Temp += " did not have the necessary specification of one or more paths:\n";
Temp += "\n Workspace path: " + CFGData.paths_workspace_path;
Temp += "\n Rulebase path: " + CFGData.paths_rulebase_path;
Temp += "\n Log path: " + CFGData.paths_log_path;
Temp += "\n Update script: " + CFGData.update_script_call;
Temp += "\n Identity file: " + CFGData.node_identity;
throw runtime_error(Temp);
}
}
string
UtilityConfig::GetPlatformContents(void) {
return CFGData.PlatformElementContents;
}
string
UtilityConfig::GetConfigFileName(void) {
return ConfigFile;
}
void
UtilityConfig::SetConfigFileName(string Name) {
ConfigFile = Name;
}
string
UtilityConfig::GetWorkspacePath(void) {
return CFGData.paths_workspace_path;
}
string
UtilityConfig::GetRulebasePath(void) {
return CFGData.paths_rulebase_path;
}
string
UtilityConfig::GetLogPath(void) {
return CFGData.paths_log_path;
}
string
UtilityConfig::GetIdentityFileName(void) {
return CFGData.node_identity;
}
string
UtilityConfig::GetRulebaseScriptName(void) {
return CFGData.update_script_call;
}
void
UtilityConfig::Copy(std::string From, std::string To) {
if (Verbose()) {
cout << "Copy " << From << " to " << To << "...";
}
if (!Explain()) {
ifstream Input;
Input.open(From.c_str()); // Read the contents.
if (!Input) {
string Temp;
Temp = "Error opening the file " + From;
Temp += " to copy from: ";
Temp += strerror(errno);
throw runtime_error(Temp);
}
string Content;
string Line;
while (getline(Input, Line)) {
Content += Line + "\n"; // Copy this line.
}
if (!Input.eof()) { // Should be at end-of-file.
string Temp;
Temp = "Error reading the " + From;
Temp += " to copy from: ";
Temp += strerror(errno);
throw runtime_error(Temp);
}
Input.close();
if (Input.bad()) {
string Temp;
Temp = "Error closing the file " + From;
Temp += " to copy from: ";
Temp += strerror(errno);
throw runtime_error(Temp);
}
ofstream Output; // Write the contents.
Output.open(To.c_str(), ios::trunc);
if (!Output) {
string Temp;
Temp = "Error opening the file " + To;
Temp += " to copy to: ";
Temp += strerror(errno);
throw runtime_error(Temp);
}
Output << Content;
if (!Output) {
string Temp;
Temp = "Error writing the file " + To;
Temp += " to copy to: ";
Temp += strerror(errno);
throw runtime_error(Temp);
}
Output.close();
if (!Output) {
string Temp;
Temp = "Error closing the file " + To;
Temp += " to copy to: ";
Temp += strerror(errno);
throw runtime_error(Temp);
}
}
OutputVerboseEnd();
}
void
UtilityConfig::SetOwnerGroup(std::string &File) {
struct passwd *SNFPasswd;
uid_t SNFUid;
struct group *SNFGroup;
gid_t SNFGid;
if (Verbose()) {
cout << "Set owner:group of " << File << " to "
<< SNFUserName << ":" << SNFGroupName << "...";
}
if (!Explain()) {
SNFPasswd = getpwnam(SNFUserName.c_str());
if (SNFPasswd == 0) {
string Temp;
Temp = "Error getting info for Sniffer user " + SNFUserName;
Temp += ": ";
Temp += strerror(errno);
throw runtime_error(Temp);
}
SNFUid = SNFPasswd->pw_uid;
SNFGid = SNFPasswd->pw_gid;
if (chown(File.c_str(), SNFUid, SNFGid) != 0) {
string Temp;
Temp = "Error changing group and owner of file " + File;
Temp += " to " + SNFUserName + ":" + SNFGroupName;
Temp += ": ";
Temp += strerror(errno);
throw runtime_error(Temp);
}
}
OutputVerboseEnd();
}
void
UtilityConfig::SetMode(std::string &File, mode_t mode) {
if (Verbose()) {
cout << "Set mode of " << File << " to "
<< std::oct << mode << "...";
}
if (!Explain()) {
if (chmod(File.c_str(), mode) != 0) {
ostringstream Temp;
Temp << "Error changing permissions of file " << File
<< " to " << mode << ": " << strerror(errno);
throw runtime_error(Temp.str());
}
}
OutputVerboseEnd();
}
void
UtilityConfig::MkDir(std::string &Dir) {
if (Verbose()) {
cout << "Create directory " << Dir << "...";
}
if (!Explain()) {
if (mkdir(Dir.c_str(), 0) != 0) {
ostringstream Temp;
Temp << "Error creating directory " << Dir << ": " << strerror(errno);
throw runtime_error(Temp.str());
}
}
OutputVerboseEnd();
}
void
UtilityConfig::StartOrRestartMta(std::string Mta) {
if (Verbose()) {
cout << "Restarting the " << Mta << " MTA...";
}
if (!Explain()) {
cout << "restarting the MTA is not implemented...";
}
OutputVerboseEnd();
}
bool
UtilityConfig::CheckForString(std::string Line, std::string SearchString) {
string::size_type Indx;
Indx = Line.find_first_not_of(" \t"); // Trim leading whitespace.
if (string::npos != Indx) {
Line = Line.substr(Indx);
}
if (Line.substr(0, SearchString.length()) == SearchString) {
return true;
}
return false;
}
void
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";
} else {
ostringstream Temp;
Temp << "Internal error in UtilityConfig::GetOsSpec: Invalid value of OperatingSystemType: "
<< OperatingSystemType;
throw runtime_error(Temp.str());
}
}
void
UtilityConfig::UpdateIgnoreListFile() {
string IgnoreListPath = GetWorkspacePath();
string IgnoreListFile;
IgnoreListFile = IgnoreListPath + DirectorySeparator;
IgnoreListFile += "GBUdbIgnoreList.txt";
if (!FileExists(IgnoreListFile)) {
Copy(SampleIgnoreListFile, IgnoreListFile); // Use SNFMilter.xml.sample.
}
SetMode(IgnoreListFile, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); // Set permissions.
SetOwnerGroup(IgnoreListFile); // Set to sniffer user.
}
void
UtilityConfig::UpdateLogDir() {
string LogDir = GetLogPath();
if (!FileExists(LogDir)) {
MkDir(LogDir);
}
SetMode(LogDir, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
SetOwnerGroup(LogDir);
}
bool
UtilityConfig::ProcessCommandLineItem(std::string OneInput) {
bool ValidCommand = false;
if (OneInput == VerboseKey) {
VerboseRequested = true;
ValidCommand = true;
} else if (OneInput == ExplainKey) {
ExplainRequested = true;
ValidCommand = true;
} else if (OneInput == HelpKey) {
HelpRequested = true;
ValidCommand = true;
}
return ValidCommand;
}
bool
UtilityConfig::Verbose() {
return (VerboseRequested || ExplainRequested);
}
bool
UtilityConfig::Explain() {
return ExplainRequested;
}
bool
UtilityConfig::Help() {
return HelpRequested;
}
std::string
UtilityConfig::HelpCommandLine() {
std::string Help;
Help = "[ " + VerboseKey + " | " + ExplainKey + " ]";
return Help;
}
std::string
UtilityConfig::HelpDescription() {
std::string Desc;
Desc = " -v Provide verbose output\n";
Desc += " -explain Provide an explaination of the actions\n";
Desc += " without executing any commands\n";
return Desc;
}
void
UtilityConfig::OutputVerboseEnd() {
if (Verbose() && !Explain()) {
cout << "done.\n";
} else if (Explain()) {
cout << "\n";
}
}

+ 305
- 0
Common/UtilityConfig.hpp Wyświetl plik

@@ -0,0 +1,305 @@
// UtilityConfig.hpp
//
// Copyright (C) 2011 ARM Research Labs, LLC.
// See www.armresearch.com for the copyright terms.
//
// This file defines the interface used by the configuration utilities.
//
#ifndef UtilityConfighpp_included
#define UtilityConfighpp_included
#include "SNFMulti.hpp"
#include <string>
/// Base class for the Sniffer configuration.
//
// This class provides capability common to the configuration applications.
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////
class UtilityConfig {
public:
/// Default constructor.
UtilityConfig();
/// Check whether a file exists.
//
// \returns true if the file exists, false otherwise.
//
bool FileExists(std::string File);
/// Load the specified or default config file.
//
// 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.
//
// \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 CheckAndLoadConfigFile(const std::string DefaultFile[], int NumDefaultFiles);
/// Load the specified configuration file.
//
// \param[in] Name is the name of the configuration file.
//
void LoadConfigFile(std::string Name);
/// Set the configuration file name.
//
// \param[in] Name is the name of the configuration file.
//
void SetConfigFileName(std::string Name);
/// Get the configuration file name.
//
// \returns the name of the configuration file.
//
std::string GetConfigFileName(void);
/// Get the contents of the <platform> element of the loaded
/// config file.
//
// \returns the contents of the <platform> element.
//
string GetPlatformContents(void);
/// Get the workspace path.
//
// \returns the workspace path.
std::string GetWorkspacePath(void);
/// Get the rulebase path.
//
// \returns the rulebase path.
std::string GetRulebasePath(void);
/// Get the log path.
//
// \returns the log path.
std::string GetLogPath(void);
/// Get the identity file name.
//
// \returns the identity file name.
std::string GetIdentityFileName(void);
/// Get the rulebase script file name.
//
// \returns the rulebase script file name.
std::string GetRulebaseScriptName(void);
/// Copy a file.
//
// \param[in] From is the name of the source file.
//
// \param[in] To is the name of the destination file.
//
void Copy(std::string From, std::string To);
/// Set the owner and group of the specified file.
//
// This function sets the owner and group of the specified file to the
// value specified in UtilityConfig.cpp.
//
// \param[in] File is the specified file.
//
// \see SNFUserName.
//
// \see SNFGroupName.
//
void SetOwnerGroup(std::string &File);
/// Set the mode of a file.
//
// This function sets the mode of the specified file. If an error
// occurs, an exception is thrown.
//
// \param[in] File is the specified file.
//
// \param[in] is the mode.
//
void SetMode(std::string &File, mode_t mode);
/// Create a directory.
//
// This function creates the specified directory. If an error
// occurs, an exception is thrown.
//
// \param[in] Dir is the directory to create.
//
void MkDir(std::string &Dir);
/// Create a backup link of the specified file.
//
// This method creates a backup of the specified file by creating
// a link to the file. The name of the link is the name of the
// file appended by the BackupSuffix data member.
//
// The file can be restored from the backup link by
// RestoreFromBackupLink.
//
// \param[in] File is the file name to create a backup link for.
//
// \throws std::runtime_error in case of error.
//
// \see RestoreFromBackupLink.
//
void CreateBackupLink(std::string File);
/// Remove the backup link of the specified file.
//
// This method removes the backup link of the specified file by
// creating a link to the file. The name of the link is the name
// of the file appended by the BackupSuffix data member.
//
// \param[in] File is the file name whose backup link is to be
// removed.
//
void RemoveBackupLink(std::string File);
/// Restore the specified file from the backup link.
//
// This method restores the specified from the backup link created
// by CreateBackupLink().
//
// \param[in] File is the file name whose backup link is to be
// removed.
//
// \see CreateBackupLink.
//
void RestoreFromBackupLink(std::string File);
/// Restart the MTA.
//
// This function starts or restarts the MTA.
//
// \param[in] Mta specifies the MTA. The acceptable values are
// "postfix" and "sendmail".
//
void StartOrRestartMta(std::string Mta);
/// Check for a specified string at the beginning of a line.
//
// This function checks for the specified string at the beginning of a
// line. Leading whitespace in the line is ignored.
//
// \param[in] Line is the line.
//
// \param[in] SearchString is the string to check for.
//
static bool CheckForString(std::string Line, std::string SearchString);
/// Operating system specification.
enum OperatingSystemSpecEnum {
OpenBSD, ///< OpenBSD OS.
FreeBSD, ///< FreeBSD OS.
Ubuntu, ///< Ubuntu and variants.
RedHat, ///< RedHat and variants.
Suse ///< Suse and variants.
};
/// Load the operating-system-dependent info (file locations, etc).
//
// This method updates the public members that contain the OS
// specification and file paths.
//
void LoadInfo();
/// OS specification.
OperatingSystemSpecEnum OsSpec;
/// Postfix main.cf file path.
std::string PostfixMainCfPath;
/// Postfix main.cf file path.
std::string PostfixMasterCfPath;
/// Create or update the ignore list file.
//
// The ignore list file is created if it dosn't exist. In any
// case, the owner/group is changed by SetOwnerGroup(), and the
// permissions are changed to readonly for everyone, and
// read/write for the owner.
void UpdateIgnoreListFile();
/// Create or update the log directory.
//
// The log directory is created if it dosn't exist. In any case,
// the owner/group is changed by SetOwnerGroup(), and the
// permissions are changed to r-x for everyone, and rwx for the
// owner.
void UpdateLogDir();
/// Process one command-line item.
//
// \param[in] OneInput is the command-line item to process.
//
bool ProcessCommandLineItem(std::string OneInput);
/// Provide verbose output?
//
// \returns true if the application is to provide verbose output.
//
bool Verbose();
/// Provide an explanation of the actions only?
//
// \returns true if the application is to provide an explanation
// of the actions without executing any commands.
//
bool Explain();
/// Provide help?
//
// \returns true if the application is to output a help message.
//
bool Help();
/// Output the legal command-line input.
std::string HelpCommandLine();
/// Output the description of the legal command-line input.
std::string HelpDescription();
/// Output the end of a verbose output line.
void OutputVerboseEnd();
private:
bool VerboseRequested; ///< User requested verbose processing.
bool ExplainRequested; ///< User requested verbose processing but without actually executing the commands.
bool HelpRequested; ///< User requested help.
std::string ConfigFile; ///< Configuration file name.
static const std::string SampleIgnoreListFile; ///< Sample ignore list file.
static const std::string SampleRulebaseScriptFile; ///< Sample rulebase script file.
static const std::string BackupSuffix; ///< Suffix appended to create backup file name.
snfCFGData CFGData; ///< Configuration data.
/// Operating system type.
//
// This is either Windows or the value specified for
// --enable-os-type when configuring for *nix.
static const std::string OperatingSystemType;
};
#endif

+ 0
- 0
SNFIdentity/ChangeLog Wyświetl plik


+ 41
- 0
SNFIdentity/Makefile.am Wyświetl plik

@@ -0,0 +1,41 @@
## Process this file with automake to produce Makefile.in
##
## $Id$
##
## automake input for the MicroNeil SNFMilter application (SNFMilter directory).
##
## Author: Alban Deniz
##
## Copyright (C) 2011 ARM Research Labs, LLC.
## See www.armresearch.com for the copyright terms.
##
##

LIBS = @SNF_LIBS@ -L../../SNFMulti -L../../CodeDweller -L../Common -lUtilityCommon \
-lSNFMulti -lCodeDweller @LIBS@

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

sbin_PROGRAMS = \
SNFIdentity

SNFIdentity_SOURCES = \
@top_srcdir@/SNFUtility/SNFIdentity/main.cpp \
@top_srcdir@/SNFUtility/SNFIdentity/SNFIdentityConfig.cpp

noinst_HEADERS = \
@top_srcdir@/SNFUtility/SNFIdentity/SNFIdentityConfig.hpp

EXTRA_DIST = \
Makefile.am \
ChangeLog

install-exec-hook:
ln -f $(DESTDIR)$(sbindir)/SNFIdentity$(EXEEXT) $(DESTDIR)$(sbindir)/SNFDebugIdentity$(EXEEXT)

uninstall-hook:
rm -f $(DESTDIR)$(sbindir)/SNFDebugIdentity$(EXEEXT)

clean-local:
rm -f *.gcno *.gcov *.gcda *~ $(CONFDATA)

+ 317
- 0
SNFIdentity/SNFIdentityConfig.cpp Wyświetl plik

@@ -0,0 +1,317 @@
// SNFIdentity.cpp
//
// Copyright (C) 2011, ARM Research Labs, LLC.
// See www.armresearch.com for the copyright terms.
//
// This file contains the functions for SNFIdentityConfig.
//
// $Id$
//
///////////////////////////////////////////////////////////////////////////////////////////////////
#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 <exception>
#include <stdexcept>
#include <sstream>
#include <iostream>
#include <fstream>
#include <vector>
#include "SNFIdentityConfig.hpp"
using namespace std;
//////////////////////////////////////////////////////////////////////////////////////////////////////////
// Configuration. ////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////
const string LicenseSearchString = "LICENSE_ID=";
const string AuthSearchString = "AUTHENTICATION=";
const string ConfigFileKey("-config=");
const string LicenseIdKey("-id=");
const string AuthenticationKey("-auth=");
//////////////////////////////////////////////////////////////////////////////////////////////////////////
// End of configuration. /////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////
void
SNFIdentityConfig::DisplayHelp(std::string Version, const std::string DefaultConfigFile[], int NumDefaultConfigFiles) {
cout
<< Version << endl
<< "Copyright (C) 2011, ARM Research Labs, LLC (www.armresearch.com)\n\n"
<< "Usage:\n\n"
<< "SNFIdentity [" << ConfigFileKey << "snf-config-file] " << LicenseIdKey << "licenseid "
<< AuthenticationKey << "authentication "
<< UtilityConfig::HelpCommandLine() << "\n\n"
<< " -config=snf-config-file Specifies the configuration file\n"
<< " -id=licenseid Specifies the license ID\n"
<< " -auth=authentication Specifies the Authentication\n"
<< UtilityConfig::HelpDescription() << "\n"
<< "If snf-config-file is not specified, then the following files are tried:\n\n";
for (int i = 0; i < NumDefaultConfigFiles; i++) {
cout << " " << DefaultConfigFile[i] + "\n";
}
cout << "\nIf more than one default file is found, then SNFIdentity aborts.\n";
};
bool
SNFIdentityConfig::GetCommandLineInput(int argc, char* argv[]) {
int i;
string OneInput;
for (i = 1; i < argc; i++) { // Check each input.
OneInput = argv[i];
if (0 == OneInput.find(ConfigFileKey)) {
SetConfigFileName(OneInput.substr(ConfigFileKey.length()));
} else if (0 == OneInput.find(LicenseIdKey)) {
LicenseID = OneInput.substr(LicenseIdKey.length());
} else if (0 == OneInput.find(AuthenticationKey)) {
Authentication = OneInput.substr(AuthenticationKey.length());
} else {
// Process command-line input by the base class.
if (!ProcessCommandLineItem(OneInput)) {
return false; // Illegal input.
}
}
}
return ( (LicenseID.length() > 0) &&
(Authentication.length() > 0));
}
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() {
std::string File = GetRulebaseScriptName();
if (Verbose()) {
cout << "Update authentication and license ID in the rulebase file " << File << "--\n";
}
ifstream Input;
Input.open(File.c_str()); // Read the contents.
if (!Input) {
string Temp;
Temp = "Error opening rulebase 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 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 SNFIdentity";
}
if (CheckForString(Line, AuthSearchString)) { // Check for authentication line.
if (FoundAuth) { // Second authentication line found?
string Temp;
Temp = "Rulebase 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 SNFIdentity";
}
Content += Line + "\n";
}
if (!FoundLicense || !FoundAuth) {
string Temp;
Temp = "Rulebase 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 file " + File;
Temp += ": ";
Temp += strerror(errno);
throw runtime_error(Temp);
}
Input.close();
if (Input.bad()) {
string Temp;
Temp = "Error closing the rulebase 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 file " + File;
Temp += " for writing: ";
Temp += strerror(errno);
throw runtime_error(Temp);
}
Output << Content;
if (!Output) {
string Temp;
Temp = "Error writing the rulebase file " + File;
Temp += ": ";
Temp += strerror(errno);
throw runtime_error(Temp);
}
Output.close();
if (!Output) {
string Temp;
Temp = "Error closing the rulebase file " + File;
Temp += " after writing: ";
Temp += strerror(errno);
throw runtime_error(Temp);
}
}
OutputVerboseEnd();
SetMode(File, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); // Set permissions.
}

+ 81
- 0
SNFIdentity/SNFIdentityConfig.hpp Wyświetl plik

@@ -0,0 +1,81 @@
// \file SNFIdentityConfig.hpp
//
// Copyright (C) 2011 ARM Research Labs, LLC.
// See www.armresearch.com for the copyright terms.
//
// This file defines the SNFIdentityConfig interface.
//
// $Id$
//
///////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef SNFIdentityConfighpp_included
#define SNFIdentityConfighpp_included
#include <string>
#include "UtilityConfig.hpp"
/// Class to manage the sniffer credentials.
//
// This class creates the sniffer identity.xml file, and updates the
// getRulebase script with the specified sniffer credentials.
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////
class SNFIdentityConfig : public UtilityConfig {
public:
/// Structure to hold the command-line parameters.
struct CommandLineInput {
std::string ConfigFile; ///< Configuration file name.
std::string LicenseID; ///< License ID credentials.
std::string Authentication; ///< Authentication credentials.
};
/// Display usage.
//
// \param[in] Version is the SNFIdentity version.
//
// \param[in] DefaultConfigFile is the list of default locations of the
// configuration file.
//
// \param[in] NumDefaultConfigFiles is the number of default configuration files.
//
void DisplayHelp(std::string Version, const std::string DefaultConfigFile[], int NumDefaultConfigFiles);
/// Get the command-line input parameters for SNFIdentity.
//
// \param[in] argc is the number of parameters.
//
// \param[in] argv is the parameters.
//
// \returns true if all the required command line parameters are
// present and there are no unknown command-line parameters, false
// otherwise.
//
bool GetCommandLineInput(int argc, char* argv[]);
/// Create the identity file.
//
// The file is created, the owner/group is changed by SetOwnerGroup(),
// and the permissions are changed to readonly for the owner.
//
// \see SetOwnerGroup().
//
void CreateIdentityFile();
/// Update the rulebase script with the credentials.
//
void UpdateRulebaseScriptCredentials();
private:
std::string LicenseID; ///< License ID string.
std::string Authentication; ///< Authentication string.
};
#endif

+ 103
- 0
SNFIdentity/main.cpp Wyświetl plik

@@ -0,0 +1,103 @@
// main.cpp
//
// Copyright (C) 2011, ARM Research Labs, LLC.
// See www.armresearch.com for the copyright terms.
//
// Configure the identity.xml and getRulebase files with the license
// and authentication credentials.
//
// The license and authentication credentials are specified on the
// command line, and are used to create the identity.xml and update
// the getRulebase files with that information.
//
// $Id$
//
///////////////////////////////////////////////////////////////////////////////////////////////////
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>
#include <sys/stat.h>
#include <exception>
#include <iostream>
#include <fstream>
#include "SNFMulti.hpp"
#include "SNFIdentityConfig.hpp"
using namespace std;
//////////////////////////////////////////////////////////////////////////////////////////////////////////
// Configuration. ////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Version string.
const char* SNF_IDENTITY_VERSION = "SNFIdentity 0.0.1 Build: " __DATE__ " " __TIME__;
/// Locations to search for default configuration files.
const string DefaultConfigFile[] = {
"/etc/snf-milter/SNFMilter.xml",
"/usr/local/etc/snf-milter/SNFMilter.xml",
"/etc/snf-server/SNFServer.xml",
"/usr/local/etc/snf-server/SNFServer.xml"
};
const size_t DefaultConfigFileSize = sizeof DefaultConfigFile / sizeof DefaultConfigFile[0];
//////////////////////////////////////////////////////////////////////////////////////////////////////////
// End of configuration. /////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////
int main(int argc, char* argv[]) {
SNFIdentityConfig SnfIdentityConfig;
if (!SnfIdentityConfig.GetCommandLineInput(argc, argv) || // If our command line arguments
SnfIdentityConfig.Help()) { // don't look right, or if help is
// requested then display our help
SnfIdentityConfig.DisplayHelp(SNF_IDENTITY_VERSION, // screen.
DefaultConfigFile,
DefaultConfigFileSize);
return 0;
}
bool DebugMode = false; // This will be our debug mode.
string argv0(argv[0]); // Capture how we were called.
if(
string::npos != argv0.find("Debug") || // If we find "Debug" or
string::npos != argv0.find("debug") // "debug" in our command path
) { // then we are in DebugMode.
DebugMode = true; // Set the flag and tell the
cout << SNF_IDENTITY_VERSION << endl; // watchers.
cout << "Debug Mode" << endl;
}
try { // Catch anything that breaks loose.
SnfIdentityConfig.CheckAndLoadConfigFile(DefaultConfigFile, // Load configuration from the
DefaultConfigFileSize); // config file specified on the
// command line, or the default file.
SnfIdentityConfig.CreateIdentityFile();
SnfIdentityConfig.UpdateRulebaseScriptCredentials();
} // That's all folks.
catch(exception& e) { // Report any normal exceptions.
cerr << "SNFIdentity Exception: " << e.what() << endl;
}
catch (snfCFGmgr::LoadFailure) { // Error loading configuration file.
cerr << "snfCFGmgr Exception: Unable to load the configuration file "
<< SnfIdentityConfig.GetConfigFileName() << endl;
}
catch(...) { // Report any unexpected exceptions.
cerr << "SNFIdentity Panic! Unknown Exception!" << endl;
}
return 0; // Normally we return zero.
}

+ 0
- 0
SNFMilterConfig/ChangeLog Wyświetl plik


+ 41
- 0
SNFMilterConfig/Makefile.am Wyświetl plik

@@ -0,0 +1,41 @@
## Process this file with automake to produce Makefile.in
##
## $Id$
##
## automake input for the MicroNeil SNFMilter application (SNFMilter directory).
##
## Author: Alban Deniz
##
## Copyright (C) 2011 ARM Research Labs, LLC.
## See www.armresearch.com for the copyright terms.
##
##

LIBS = @SNF_LIBS@ -L../../SNFMulti -L../../CodeDweller -L../Common -lUtilityCommon \
-lSNFMulti -lCodeDweller @LIBS@

CXXFLAGS = $(SNF_CXXFLAGS) -I@top_srcdir@/SNFMulti -I@top_srcdir@/CodeDweller \
-I@top_srcdir@/SNFUtility/Common -DDEFAULT_CONFIG_DIR=\"@sysconfdir@\"

sbin_PROGRAMS = \
SNFMilterConfig

SNFMilterConfig_SOURCES = \
@top_srcdir@/SNFUtility/SNFMilterConfig/main.cpp \
@top_srcdir@/SNFUtility/SNFMilterConfig/SNFMilterConfig.cpp

noinst_HEADERS = \
@top_srcdir@/SNFUtility/SNFMilterConfig/SNFMilterConfig.hpp

EXTRA_DIST = \
Makefile.am \
ChangeLog

install-exec-hook:
ln -f $(DESTDIR)$(sbindir)/SNFMilterConfig$(EXEEXT) $(DESTDIR)$(sbindir)/SNFDebugMilterConfig$(EXEEXT)

uninstall-hook:
rm -f $(DESTDIR)$(sbindir)/SNFDebugMilterConfig$(EXEEXT)

clean-local:
rm -f *.gcno *.gcov *.gcda *~ $(CONFDATA)

+ 442
- 0
SNFMilterConfig/SNFMilterConfig.cpp Wyświetl plik

@@ -0,0 +1,442 @@
// /file SNFMilterConfig.cpp
//
// Copyright (C) 2011, ARM Research Labs, LLC.
// See www.armresearch.com for the copyright terms.
//
// This file contains the functions for SNFMilterConfig.
//
// $Id$
//
///////////////////////////////////////////////////////////////////////////////////////////////////
#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 <exception>
#include <stdexcept>
#include <sstream>
#include <iostream>
#include <fstream>
#include <vector>
#include "SNFMilterConfig.hpp"
using namespace std;
//////////////////////////////////////////////////////////////////////////////////////////////////////////
// Configuration. ////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////
// Initialize default configuration file path.
#ifdef WIN
// Windows OS.
const std::string SNFMilterConfig::DefaultConfigFile("C:\\SNF\\SNFMilter.xml");
const std::string SNFMilterConfig::DefaultSampleConfigFile("C:\\SNF\\SNFMilter.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");
#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("");
#endif
#endif
const string ConfigFileKey("-config=");
const string IntegrateWithNoneKey("-mta=none");
const string IntegrateWithPostfixKey("-mta=postfix");
const string IntegrateWithSendmailKey("-mta=sendmail");
const string SnfMilterMainCfSearchString("Added by SNFMilterConfig");
const string SnfMilterMainCfIntegrationString("smtpd_milters = unix:/var/snf-milter/socket $smtpd_milters # Added by SNFMilterConfig");
//////////////////////////////////////////////////////////////////////////////////////////////////////////
// End of configuration. /////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////
void
SNFMilterConfig::DisplayHelp(std::string Version) {
cout
<< Version << endl
<< "Copyright (C) 2012, ARM Research Labs, LLC (www.armresearch.com)\n\n"
<< "Usage:\n\n"
<< "SNFMilterConfig [" << ConfigFileKey << "snf-config-file] "
<< 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"
<< " -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";
};
bool
SNFMilterConfig::GetCommandLineInput(int argc, char* argv[]) {
int i;
int NumCommandsFound = 0;
string OneInput;
string ConfigFile;
for (i = 1; i < argc; i++) { // Check each input.
OneInput = argv[i];
if (0 == OneInput.find(ConfigFileKey)) {
ConfigFile = OneInput.substr(ConfigFileKey.length());
} else if (OneInput == IntegrateWithNoneKey) {
Command = IntegrateWithNoneCmd;
NumCommandsFound++;
} else if (OneInput == IntegrateWithPostfixKey) {
Command = IntegrateWithPostfixCmd;
NumCommandsFound++;
} else if (0 == OneInput.find(IntegrateWithSendmailKey)) {
Command = IntegrateWithSendmailCmd;
NumCommandsFound++;
} else {
// Process command-line input by the base class.
if (!ProcessCommandLineItem(OneInput)) {
return false; // Illegal input.
}
}
}
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);
}
void
SNFMilterConfig::LoadSocketInfo() {
std::string MilterElement = GetPlatformContents();
ConfigurationData PlatformConfig(MilterElement.c_str(), MilterElement.length());
ConfigurationElement SocketReader("milter");
SocketReader
.Element("socket")
.Attribute("path", SocketFileName)
.End("socket")
.End("milter");
SocketReader.interpret(PlatformConfig);
}
void
SNFMilterConfig::CreateSocketDir() {
std::string SocketDir;
std::string::size_type LastDirSepIndex = SocketFileName.rfind("/");
SocketDir = ( (std::string::npos == LastDirSepIndex) ? SocketFileName : SocketFileName.substr(0, LastDirSepIndex));
if (Verbose()) {
cout << "Create the milter socket directory " << SocketDir << "...";
}
if (!Explain()) {
if (!FileExists(SocketDir)) {
MkDir(SocketDir);
}
SetMode(SocketDir, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP);
SetOwnerGroup(SocketDir);
}
OutputVerboseEnd();
}
void
SNFMilterConfig::UpdateConfigFiles() {
std::string ConfigFileName = GetConfigFileName();
if (!FileExists(ConfigFileName)) {
Copy(DefaultSampleConfigFile, ConfigFileName); // Use SNFMilter.xml.sample.
}
SetMode(ConfigFileName, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); // Set permissions.
SetOwnerGroup(ConfigFileName); // Set to sniffer user.
UpdateLogDir();
UpdateIgnoreListFile();
}
void
SNFMilterConfig::DoIntegrationCommand() {
switch (Command) {
case IntegrateWithNoneCmd:
UnintegrateWithAll();
break;
case IntegrateWithPostfixCmd:
IntegrateWithPostfix();
break;
case IntegrateWithSendmailCmd:
IntegrateWithSendmail();
break;
default:
{
ostringstream Temp;
Temp << "Internal error in SNFMilterConfig::DoCommand: Invalid value of command: " << Command;
throw runtime_error(Temp.str());
}
}
}
void
SNFMilterConfig::UnintegrateWithAll() {
UnintegrateWithPostfix();
UnintegrateWithSendmail();
// TODO: Restart MTA.
// Do not remove the socket directory; users might have placed
// files in it. This happened with the /tmp directory; it was
// supposed to be only for files that would be deleted on reboot.
// However, admins stored files that they wished to be persistent
// across reboots in /tmp.
}
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";
}

+ 94
- 0
SNFMilterConfig/SNFMilterConfig.hpp Wyświetl plik

@@ -0,0 +1,94 @@
// \file SNFMilterConfig.hpp
//
// Copyright (C) 2011 ARM Research Labs, LLC.
// See www.armresearch.com for the copyright terms.
//
// This file defines the SNFMilterConfig interface.
//
// $Id$
//
///////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef SNFMilterConfighpp_included
#define SNFMilterConfighpp_included
#include <string>
#include "UtilityConfig.hpp"
/// Class to manage the SNFMilter configuration.
//
// This class creates/maintains the sniffer configuration file, and
// integrates/unintegrates with MTAs.
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////
class SNFMilterConfig : public UtilityConfig {
public:
/// Command.
enum CommandEnum {
IntegrateWithNoneCmd, ///< Remove integration with all MTAs.
IntegrateWithPostfixCmd, ///< Integrate with postfix.
IntegrateWithSendmailCmd ///< Integrate with sendmail.
};
/// Display usage.
//
// \param[in] Version is the SNFMilter version.
//
void DisplayHelp(std::string Version);
/// Get the command-line input parameters for SNFMilter.
//
// \param[in] argc is the number of parameters.
//
// \param[in] argv is the parameters.
//
// \returns true if all the required command line parameters are
// present and there are no unknown command-line parameters, false
// otherwise.
//
bool GetCommandLineInput(int argc, char* argv[]);
/// Create or update the configuration files.
//
// The SNFMilter.xml and GBUdbIgnoreList.txt files are created if
// they don't exist. In any case, the owner/group is changed by
// SetOwnerGroup(), and the permissions are changed to readonly
// for everyone, and read/write for the owner.
//
void UpdateConfigFiles();
/// Execute the command to integrate/unintegrate with the MTAs.
void DoIntegrationCommand();
private:
/// Load the socket info (file name) from the <platform> section
/// of the loaded config file.
void LoadSocketInfo();
void CreateSocketDir();
void IntegrateWithPostfix(); ///< Integrate with postfix.
void UnintegrateWithPostfix(); ///< Unintegrate with postfix.
void IntegrateWithSendmail(); ///< Integrate with sendmail.
void UnintegrateWithSendmail(); ///< Unintegrate with sendmail.
void UnintegrateWithAll(); ///< Unintegrate with all MTAs.
CommandEnum Command; ///< Specified command.
static const std::string DefaultConfigFile; ///< Default config file.
static const std::string DefaultSampleConfigFile; ///< Sample config file.
std::string SocketFileName;
};
#endif

+ 88
- 0
SNFMilterConfig/main.cpp Wyświetl plik

@@ -0,0 +1,88 @@
// main.cpp
//
// Copyright (C) 2012, ARM Research Labs, LLC.
// See www.armresearch.com for the copyright terms.
//
// Create and maintain the sniffer configuration file for SNFMilter.
//
// The configuration file and instructions are specified on the
// command line, and are used to create/modify the configuration file,
// and integrate or unintegrate with the specified MTA.
//
//
// $Id$
//
///////////////////////////////////////////////////////////////////////////////////////////////////
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>
#include <sys/stat.h>
#include <exception>
#include <iostream>
#include <fstream>
#include "SNFMulti.hpp"
#include "SNFMilterConfig.hpp"
using namespace std;
//////////////////////////////////////////////////////////////////////////////////////////////////////////
// Configuration. ////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Version string.
const char* SNF_MILTERCONFIG_VERSION = "SNFMilterConfig 0.0.1 Build: " __DATE__ " " __TIME__;
//////////////////////////////////////////////////////////////////////////////////////////////////////////
// End of configuration. /////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////
int main(int argc, char* argv[]) {
SNFMilterConfig SnfMilterConfig;
if (!SnfMilterConfig.GetCommandLineInput(argc, argv) || // If our command line arguments
SnfMilterConfig.Help()) { // don't look right, or if help is
// requested then display our help
SnfMilterConfig.DisplayHelp(SNF_MILTERCONFIG_VERSION); // screen.
return 0;
}
bool DebugMode = false; // This will be our debug mode.
string argv0(argv[0]); // Capture how we were called.
if(
string::npos != argv0.find("Debug") || // If we find "Debug" or
string::npos != argv0.find("debug") // "debug" in our command path
) { // then we are in DebugMode.
DebugMode = true; // Set the flag and tell the
cout << SNF_MILTERCONFIG_VERSION << endl; // watchers.
cout << "Debug Mode" << endl;
}
try { // Catch anything that breaks loose.
SnfMilterConfig.UpdateConfigFiles(); // Create config files if they don't
// exist, or update config files.
SnfMilterConfig.DoIntegrationCommand(); // Integrate/unintegrate.
} // That's all folks.
catch(exception& e) { // Report any normal exceptions.
cerr << "SNFMilterConfig Exception: " << e.what() << endl;
}
catch (snfCFGmgr::LoadFailure) { // Error loading configuration file.
cerr << "snfCFGmgr Exception: Unable to load the configuration file "
<< SnfMilterConfig.GetConfigFileName() << endl;
}
catch(...) { // Report any unexpected exceptions.
cerr << "SNFMilterConfig Panic! Unknown Exception!" << endl;
}
return 0; // Normally we return zero.
}

Ładowanie…
Anuluj
Zapisz