Parcourir la source

Implemented SNFServerConfig.


git-svn-id: https://svn.microneil.com/svn/PKG-SNF-CS-NIX/trunk@69 233e721a-07f6-49eb-a7da-05e0e16828fc
master
adeniz il y a 12 ans
Parent
révision
414dc47928

+ 23
- 24
SNF_CS_Developer_Package/Makefile.am Voir le fichier

@@ -11,37 +11,36 @@
## See www.armresearch.com for the copyright terms.
##

SUBDIRS = \
CodeDweller \
SNFMulti \
SNFServer \
SNFClient \
SNF2Check \
SUBDIRS = \
CodeDweller \
SNFMulti \
SNFServer \
SNFClient \
SNF2Check \
SNFUtility/Common \
SNFUtility/CommonTests \
SNFUtility/SNFMilterConfig \
SNFUtility/SNFMilterConfigTests \
Scripts \
config_files \
SNFUtility/SNFServerConfig \
Scripts \
config_files \
Docs

doc_DATA = \
BUGS \
ChangeLog \
README \
TODO \
INSTALL \
doc_DATA = \
BUGS \
ChangeLog \
README \
TODO \
INSTALL \
COPYING


EXTRA_DIST = \
$(doc_DATA) \
Makefile.am \
configure.ac \
configure.ac.in \
SNF4SA/INSTALL \
SNF4SA/README \
SNF4SA/snf4sa.cf \
EXTRA_DIST = \
$(doc_DATA) \
Makefile.am \
configure.ac \
configure.ac.in \
SNF4SA/INSTALL \
SNF4SA/README \
SNF4SA/snf4sa.cf \
SNF4SA/snf4sa.pm

DISTCHECK_CONFIGURE_FLAGS=--enable-os-type=OpenBSD

+ 46
- 0
SNF_CS_Developer_Package/SNFUtility/SNFServerConfig/Makefile.am Voir le fichier

@@ -0,0 +1,46 @@
## Process this file with automake to produce Makefile.in
##
## $Id$
##
## automake input for the MicroNeil SNFServerConfig application.
##
## Author: Alban Deniz
##
## Copyright (C) 2012 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@\" \
-DDOC_DIR=\"@docdir@\"

sbin_PROGRAMS = \
SNFServerConfig

SNFServerConfig_SOURCES = \
@top_srcdir@/SNFUtility/SNFServerConfig/main.cpp \
@top_srcdir@/SNFUtility/SNFServerConfig/SNFServerConfig.cpp \
@top_srcdir@/SNFUtility/SNFServerConfig/PostfixIntegrate.cpp \
@top_srcdir@/SNFUtility/SNFServerConfig/SendmailIntegrate.cpp

noinst_HEADERS = \
@top_srcdir@/SNFUtility/SNFServerConfig/SNFServerConfig.hpp \
@top_srcdir@/SNFUtility/SNFServerConfig/PostfixIntegrate.hpp \
@top_srcdir@/SNFUtility/SNFServerConfig/SendmailIntegrate.hpp

EXTRA_DIST = \
Makefile.am \
ChangeLog

install-exec-hook:
ln -f $(DESTDIR)$(sbindir)/SNFServerConfig$(EXEEXT) $(DESTDIR)$(sbindir)/SNFDebugServerConfig$(EXEEXT)

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

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

+ 589
- 0
SNF_CS_Developer_Package/SNFUtility/SNFServerConfig/PostfixIntegrate.cpp Voir le fichier

@@ -0,0 +1,589 @@
// /file PostfixIntegrate.cpp
//
// Copyright (C) 2012, ARM Research Labs, LLC.
// See www.armresearch.com for the copyright terms.
//
// This file contains the functions for PostfixIntegrate.
//
// $Id$
//
///////////////////////////////////////////////////////////////////////////////////////////////////
#include <cstdlib>
#include <cerrno>
#include <cstring>
#include <iostream>
#include <exception>
#include <stdexcept>
#include <sstream>
#include <fstream>
#include "PostfixIntegrate.hpp"
//////////////////////////////////////////////////////////////////////////////////////////////////////////
// Configuration. ////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////
// End of configuration. /////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////
void
PostfixIntegrate::SetOperatingSystem(std::string OperatingSystemType) {
MtaIsRunningCommand = "ps axl | grep -v grep | grep -q 'postfix/master'";
PostfixDefaultIsChrooted = false; // Overwritten if postfix is
SnfSnifferDirName = "/usr/sbin"; // by default chrooted.
SnfSnifferFileName = SnfSnifferDirName + "/snfSniffer";
SnfSnifferSampleFileName = SnfSnifferFileName + ".sample";
ContentFilterLine = " -o content_filter=snfilter:dummy\n";
ContentFilterSpec = "snfilter unix - n n - 10 pipe\n";
if ("OpenBSD" == OperatingSystemType) {
PostfixDefaultIsChrooted = true;
SnfSnifferDirName = "/var/spool/postfix/snf-server";
SnfSnifferFileName = SnfSnifferDirName + "/snfSniffer";
SnfSnifferSampleFileName = "/usr/local/sbin/snfSniffer.sample";
ContentFilterSpec += " flags=Rq user=snfuser argv=/snfSniffer\n";
PostfixMainCfPath = "/etc/postfix/main.cf";
PostfixMasterCfPath = "/etc/postfix/master.cf";
ReloadMtaCommand = "/usr/local/sbin/postfix reload";
} else if ("FreeBSD" == OperatingSystemType) {
ContentFilterSpec += " flags=Rq user=snfuser argv=/usr/sbin/snfSniffer\n";
PostfixMainCfPath = "/usr/local/etc/postfix/main.cf";
PostfixMasterCfPath = "/usr/local/etc/postfix/master.cf";
ReloadMtaCommand = "/usr/local/sbin/postfix reload";
} else if ("Ubuntu" == OperatingSystemType) {
PostfixDefaultIsChrooted = true;
SnfSnifferDirName = "/var/spool/postfix";
SnfSnifferFileName = SnfSnifferDirName + "/snfSniffer";
SnfSnifferSampleFileName = "/usr/local/sbin/snfSniffer.sample";
ContentFilterSpec += " flags=Rq user=snfuser argv=/snfSniffer\n";
PostfixMainCfPath = "/etc/postfix/main.cf";
PostfixMasterCfPath = "/etc/postfix/master.cf";
ReloadMtaCommand = "/usr/sbin/postfix reload";
} else if ("RedHat" == OperatingSystemType) {
ContentFilterSpec += " flags=Rq user=snfuser argv=/usr/sbin/snfSniffer\n";
PostfixMainCfPath = "/etc/postfix/main.cf";
PostfixMasterCfPath = "/etc/postfix/master.cf";
ReloadMtaCommand = "/usr/sbin/postfix reload";
} else if ("Suse" == OperatingSystemType) {
ContentFilterSpec += " flags=Rq user=snfuser argv=/usr/sbin/snfSniffer\n";
PostfixMainCfPath = "/etc/postfix/main.cf";
PostfixMasterCfPath = "/etc/postfix/master.cf";
ReloadMtaCommand = "/usr/sbin/postfix reload";
} else {
std::ostringstream Temp;
Temp << "***Error from PostfixIntegrate::SetOperatingSystem: Invalid value of OperatingSystemType: "
<< OperatingSystemType;
throw std::runtime_error(Temp.str());
}
ContentFilterSpec += " -f ${sender} -- ${recipient}\n";
}
void
PostfixIntegrate::Integrate(FileBackup *SaveFile) {
if (IsIntegrated()) {
return;
}
// Check whether the chroot configuration is as expected.
bool IsChrooted;
IsChrooted = MtaConfigurationIsChrooted();
if (IsChrooted != PostfixDefaultIsChrooted) {
std::string Temp;
Temp = "Error--postfix must be configured to run ";
Temp += (PostfixDefaultIsChrooted ? "" : "not ");
Temp += "chrooted, which is the default for this operating system. ";
Temp += "postfix was detected to be configured to run ";
Temp += (IsChrooted ? "" : "not ");
Temp += "chrooted.";
Temp += strerror(errno);
throw std::runtime_error(Temp);
}
std::ifstream Input;
if (Verbose()) {
std::cout << "Integrate with postfix...\n";
}
std::string Content;
if (!Explain()) {
if (!FileExists(SnfSnifferFileName)) { // Create SnfSniffer script
// if it doesn't exist.
SaveFile->CreateBackupFile(SnfSnifferFileName);
MkDir(SnfSnifferDirName);
SetMode(SnfSnifferDirName, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
SetOwnerGroup(SnfSnifferDirName);
Copy(SnfSnifferSampleFileName, SnfSnifferFileName);
SetMode(SnfSnifferFileName, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
SetOwnerGroup(SnfSnifferFileName);
}
SaveFile->CreateBackupFile(PostfixMasterCfPath);
Input.open(PostfixMasterCfPath.c_str()); // Read the contents.
if (!Input) {
std::string Temp;
Temp = "Error opening the postfix configuration file " + PostfixMasterCfPath;
Temp += " for reading: ";
Temp += strerror(errno);
throw std::runtime_error(Temp);
}
std::string Line;
while (getline(Input, Line)) {
Content += Line + "\n"; // Copy this line.
if (Line.find("smtp") == 0) {
if (Verbose()) {
std::cout << " Add\n\n " << ContentFilterLine << "\n\n after 'smtp' line in "
<< PostfixMasterCfPath << "...\n";
}
Content += ContentFilterLine + "\n";
}
}
if (!Input.eof()) { // Should be at end-of-file.
std::string Temp;
Temp = "Error reading the postfix configuration file " + PostfixMasterCfPath;
Temp += ": ";
Temp += strerror(errno);
throw std::runtime_error(Temp);
}
Input.close();
if (Input.bad()) {
std::string Temp;
Temp = "Error closing the postfix configuration file " + PostfixMasterCfPath;
Temp += " after reading: ";
Temp += strerror(errno);
throw std::runtime_error(Temp);
}
if (Verbose()) {
std::cout << " Add\n\n " << ContentFilterSpec << "\n\n to the end of "
<< PostfixMasterCfPath << "...\n";
}
Content += ContentFilterSpec;
if (!Explain()) {
std::ofstream Output; // Write the updated contents.
Output.open(PostfixMasterCfPath.c_str(), std::ios::trunc);
if (!Output) {
std::string Temp;
Temp = "Error opening the postfix configuration file " + PostfixMasterCfPath;
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 " + PostfixMasterCfPath;
Temp += ": ";
Temp += strerror(errno);
throw std::runtime_error(Temp);
}
Output.close();
if (!Output) {
std::string Temp;
Temp = "Error closing the postfix configuration file " + PostfixMasterCfPath;
Temp += " after writing: ";
Temp += strerror(errno);
throw std::runtime_error(Temp);
}
}
}
OutputVerboseEnd();
if (!ReloadMta()) {
std::cerr << "Unable to reload the postfix configuration. Please run "
<< "'postfix reload' for the integration with SNFServer to take effect.";
}
}
void
PostfixIntegrate::Unintegrate(FileBackup *SaveFile) {
if (!IsIntegrated()) {
return;
}
std::ifstream Input;
if (Verbose()) {
std::cout << "Remove integration in postfix file " << PostfixMasterCfPath << "--\n";
}
if (!Explain()) {
SaveFile->CreateBackupFile(PostfixMasterCfPath); // Save any existing file.
Input.open(PostfixMasterCfPath.c_str()); // Read the contents.
if (!Input) {
std::string Temp;
Temp = "Error opening the postfix configuration file " + PostfixMasterCfPath;
Temp += " for reading: ";
Temp += strerror(errno);
throw std::runtime_error(Temp);
}
std::ostringstream ContentStream;
ContentStream << Input.rdbuf();
Input.close();
if (!Input) {
std::string Temp;
Temp = "Error closing the postfix configuration file " + PostfixMasterCfPath;
Temp += ": ";
Temp += strerror(errno);
throw std::runtime_error(Temp);
}
std::string Content;
Content = ContentStream.str();
if (Verbose()) {
std::cout << " Remove all occurances of\n\n" << ContentFilterLine << "\n\n"
<< " from" << PostfixMasterCfPath << "...\n";
}
std::string::size_type IntegrationBegin = std::string::npos;
while ((IntegrationBegin = Content.find(ContentFilterLine)) != std::string::npos) {
Content.erase(IntegrationBegin, ContentFilterLine.length());
}
if (Verbose()) {
std::cout << " Remove all occurances of\n\n" << ContentFilterSpec << "\n\n"
<< " from" << PostfixMasterCfPath << "...\n";
}
IntegrationBegin = std::string::npos;
while ((IntegrationBegin = Content.find(ContentFilterSpec)) != std::string::npos) {
Content.erase(IntegrationBegin, ContentFilterSpec.length());
}
}
OutputVerboseEnd();
if (!ReloadMta()) {
std::cerr << "Unable to reload the postfix configuration. Please run "
<< "'postfix reload' for the integration with SNFServer to take effect.";
}
}
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 (!MtaIsRunningDetected()) {
return true;
}
if (Verbose()) {
std::cout << "Reloading postfix...\n";
std::cout.flush();
}
bool Succeeded;
if (!Explain()) {
Succeeded = (std::system(ReloadMtaCommand.c_str()) == 0);
if (Verbose()) {
std::cout << (Succeeded ? "succeeded..." : "failed...");
}
}
OutputVerboseEnd();
return Succeeded;
}
bool
PostfixIntegrate::IsIntegrated() {
if (Verbose()) {
std::cout << "Checking for any SNFServer integration in the postfix file " << PostfixMasterCfPath << "...";
}
if (!FileExists(PostfixMasterCfPath)) {
if (Verbose()) {
std::cout << "file doesn't exist; postfix is not integrated...";
}
OutputVerboseEnd();
return false;
}
std::ifstream Input;
Input.open(PostfixMasterCfPath.c_str()); // Read the contents.
if (!Input) {
std::string Temp;
Temp = "Error opening the postfix configuration file " + PostfixMasterCfPath;
Temp += " for reading: ";
Temp += strerror(errno);
throw std::runtime_error(Temp);
}
std::ostringstream ContentStream;
ContentStream << Input.rdbuf();
Input.close();
if (!Input) {
std::string Temp;
Temp = "Error closing the postfix configuration file " + PostfixMasterCfPath;
Temp += ": ";
Temp += strerror(errno);
throw std::runtime_error(Temp);
}
std::string Content;
Content = ContentStream.str();
bool FoundContentFilterLine = (Content.find(ContentFilterLine) != std::string::npos);
bool FoundContentFilterSpec = (Content.find(ContentFilterSpec) != std::string::npos);
bool Integrated = (FoundContentFilterLine || FoundContentFilterSpec);
if (Verbose()) {
if (FoundContentFilterLine) {
std::cout << "found\n\n" << ContentFilterLine << "\n\n";
}
if (FoundContentFilterSpec) {
std::cout << "found\n\n" << ContentFilterSpec << "\n\n";
}
if (!Integrated) {
} else {
std::cout << "none found...";
}
}
OutputVerboseEnd();
return Integrated;
}
bool
PostfixIntegrate::DefaultIsChrooted() {
return PostfixDefaultIsChrooted;
}
bool
PostfixIntegrate::MtaConfigurationIsChrooted() {
std::string File;
std::ifstream Input;
File = PostfixMasterCfPath;
Input.open(File.c_str());
if (!Input) {
std::string Temp;
Temp = "Error opening postfix configuration file " + File;
Temp += " for reading: ";
Temp += strerror(errno);
throw std::runtime_error(Temp);
}
std::string Line;
bool ConfigurationIsChrooted = false;
while (getline(Input, Line)) {
if (CheckForString(Line, "smtp")) { // Check for smtp line.
std::istringstream Buffer(Line); // Parse buffer line.
std::string Token[8];
for (unsigned int iToken = 0; iToken < 8; iToken++) {
Buffer >> Token[iToken];
}
if ( ("y" == Token[4]) || ("-" == Token[4]) ) {
Input.close();
if (Input.bad()) {
std::string Temp;
Temp = "Error closing the postfix configuration file " + File;
Temp += " after reading: ";
Temp += strerror(errno);
throw std::runtime_error(Temp);
}
return true;
}
}
}
Input.close();
if (Input.bad()) {
std::string Temp;
Temp = "Error closing the rulebase download script file " + File;
Temp += " after reading: ";
Temp += strerror(errno);
throw std::runtime_error(Temp);
}
return false;
}

+ 88
- 0
SNF_CS_Developer_Package/SNFUtility/SNFServerConfig/PostfixIntegrate.hpp Voir le fichier

@@ -0,0 +1,88 @@
// \file PostfixIntegrate.hpp
//
// Copyright (C) 2012 ARM Research Labs, LLC.
// See www.armresearch.com for the copyright terms.
//
// This file defines the PostfixIntegrate interface.
//
// $Id$
//
///////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef PostfixIntegratehpp_included
#define PostfixIntegratehpp_included
#include "MtaIntegrate.hpp"
/// Class to manage the SNFServer integration with postfix.
//
// This class implements the MtaIntegrate interface for postfix.
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////
class PostfixIntegrate : public MtaIntegrate {
public:
virtual void SetOperatingSystem(std::string OperatingSystemType);
virtual void Integrate(FileBackup *SaveFile);
virtual void Unintegrate(FileBackup *SaveFile);
// Return the default chroot configuration of Postfix.
//
// \returns true if the default configuration is for postfix to
// run chrooted, false otherwise.
//
bool DefaultIsChrooted();
private:
virtual bool MtaIsRunningDetected();
virtual bool ReloadMta();
virtual bool IsIntegrated();
bool MtaConfigurationIsChrooted();
/// Directory containing the snfSniffer script.
std::string SnfSnifferDirName;
/// snfSniffer script file name, including the directory.
std::string SnfSnifferFileName;
/// Sample snfSniffer script file name, including the directory.
std::string SnfSnifferSampleFileName;
/// Content filter line.
//
// To integrate, this line is added to master.cf just after the
// "smtp" line.
//
std::string ContentFilterLine;
/// Content filter specification.
//
// To integrate this is added to the end of the master.cf line.
//
std::string ContentFilterSpec;
/// Postfix main.cf file path.
std::string PostfixMainCfPath;
/// 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;
/// True if postfix runs chrooted by default.
bool PostfixDefaultIsChrooted;
};
#endif

+ 313
- 0
SNF_CS_Developer_Package/SNFUtility/SNFServerConfig/SNFServerConfig.cpp Voir le fichier

@@ -0,0 +1,313 @@
// /file SNFServerConfig.cpp
//
// Copyright (C) 2011, ARM Research Labs, LLC.
// See www.armresearch.com for the copyright terms.
//
// This file contains the functions for SNFServerConfig.
//
// $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 "SNFServerConfig.hpp"
using namespace std;
//////////////////////////////////////////////////////////////////////////////////////////////////////////
// Configuration. ////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////
// Initialize default configuration file path.
#ifdef WIN
// Windows OS.
const std::string SNFServerConfig::DefaultConfigFile("C:\\SNF\\SNFServer.xml");
const std::string SNFServerConfig::SampleConfigFile("C:\\SNF\\SNFServer.xml.sample");
const std::string SNFServerConfig::SampleIdentityFile("C:\\SNF\\identity.xml.sample");
const std::string InstallFile("");
#else
#ifdef DEFAULT_CONFIG_DIR
// *nix, DEFAULT_CONFIG_DIR is specified on the compile command line.
const std::string SNFServerConfig::DefaultConfigFile(DEFAULT_CONFIG_DIR "/snf-server/SNFServer.xml");
const std::string SNFServerConfig::SampleConfigFile(DEFAULT_CONFIG_DIR "/snf-server/SNFServer.xml.sample");
const std::string SNFServerConfig::SampleIdentityFile(DEFAULT_CONFIG_DIR "/snf-server/identity.xml.sample");
const std::string InstallFile(DOC_DIR "/INSTALL");
#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 SNFServerConfig::DefaultConfigFile("");
const std::string SNFServerConfig::SampleConfigFile("");
const std::string SNFServerConfig::SampleIdentityFile("");
const std::string InstallFile("INSTALL");
#endif
#endif
const string SNFServerConfig::ApplicationName("SNFServer");
const string IntegrateWithNoneKey("-with=none");
const string IntegrateWithPostfixKey("-with=postfix");
const string IntegrateWithSendmailKey("-with=sendmail");
//////////////////////////////////////////////////////////////////////////////////////////////////////////
// End of configuration. /////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////
void
SNFServerConfig::DisplayHelp(std::string Version) {
std::string ExclusiveCommands;
std::string ExclusiveCommandsHelp;
ExclusiveCommands = IntegrateWithPostfixKey + " | ";
ExclusiveCommands += IntegrateWithSendmailKey + " | ";
ExclusiveCommands += IntegrateWithNoneKey;
ExclusiveCommandsHelp = " -with=postfix Integrate with postfix and start/reload postfix\n";
ExclusiveCommandsHelp += " -with=sendmail Integrate with sendmail and start/reload sendmail\n";
ExclusiveCommandsHelp += " (Not available on OpenBSD or FreeBSD)\n";
ExclusiveCommandsHelp += " -with=none Remove any integration with all supported MTAs\n";
cout
<< Version << endl
<< "Copyright (C) 2012, ARM Research Labs, LLC (www.armresearch.com)\n\n"
<< "Usage:\n\n"
<< "SNFServerConfig "
<< UtilityConfig::HelpCommandLine(ExclusiveCommands) << "\n\n"
<< "SNFServerConfig "
<< UtilityConfig::HelpDescription(ExclusiveCommandsHelp) << "\n"
<< "The configuration file name is:\n\n"
<< " " << DefaultConfigFile << "\n\n"
<< "If the above file doesn't exist, then it is copied from the following file:\n\n"
<< " " << SampleConfigFile << "\n\n"
<< "If integration with an MTA is specified, the MTA's configuration is reloaded "
<< "if the MTA is running.\n\n";
};
bool
SNFServerConfig::GetCommandLineInput(int argc, char* argv[]) {
int i;
int NumCommandsFound = 0;
string OneInput;
Command = NoCommand; // Default is to do nothing.
for (i = 1; i < argc; i++) { // Check each input.
OneInput = argv[i];
if (OneInput == IntegrateWithPostfixKey) {
Command = IntegrateWithPostfixCommand;
NumCommandsFound++;
} else if (0 == OneInput.find(IntegrateWithSendmailKey)) {
std::string OsType;
OsType = GetOperatingSystemType(); // Check whether the platform is supported.
if ( ("OpenBSD" == OsType) || ("FreeBSD" == OsType) ) {
std::string Temp;
Temp = "Integration with sendmail is not supported on " + OsType;
Temp += ".\n";
Temp += "Please see " + InstallFile;
Temp += " for information on integration with sendmail.\n";
throw std::runtime_error(Temp);
}
Command = IntegrateWithSendmailCommand;
NumCommandsFound++;
} else if (OneInput == IntegrateWithNoneKey) {
Command = IntegrateWithNoneCommand;
NumCommandsFound++;
} else {
// Process command-line input by the base class.
if (!ProcessCommandLineItem(OneInput)) {
Command = UnknownCommand;
return false; // Illegal input.
}
}
}
if (UpdateCredentialsSpecified()) {
Command = UpdateCredentialsCommand;
NumCommandsFound++;
}
if (SetupRepairSpecified()) {
Command = SetupRepairCommand;
NumCommandsFound++;
}
if (StartSnifferSpecified()) {
Command = StartSnifferCommand;
NumCommandsFound++;
}
if (StopSnifferSpecified()) {
Command = StopSnifferCommand;
NumCommandsFound++;
}
return ( (NumCommandsFound == 1) && CommandLineIsOkay() );
}
void
SNFServerConfig::ExecuteCommand() {
Postfix.SetOperatingSystem(GetOperatingSystemType());
Postfix.SetVerbose(Verbose());
Postfix.SetExplain(Explain());
Sendmail.SetOperatingSystem(GetOperatingSystemType());
Sendmail.SetVerbose(Verbose());
Sendmail.SetExplain(Explain());
SetConfigFileName(DefaultConfigFile);
if (SetupRepairCommand == Command) {
CreateDefaultConfigFile(SampleConfigFile); // Create the file if it doesn't exist,
// Set owner and mode in any case.
}
LoadConfig();
LoadInfo(); // Load the file paths.
switch (Command) {
case SetupRepairCommand:
SetupRepair(SampleIdentityFile);
break;
case UpdateCredentialsCommand:
UpdateRulebaseScriptCredentials();
DownloadRulebase();
UpdateIdentityFile();
break;
case IntegrateWithPostfixCommand:
Postfix.Integrate(&SaveFile);
UnintegrateWithAllExcept("postfix");
break;
case IntegrateWithSendmailCommand:
Sendmail.Integrate(&SaveFile);
UnintegrateWithAllExcept("sendmail");
break;
case IntegrateWithNoneCommand:
UnintegrateWithAllExcept();
break;
case StartSnifferCommand:
LoadCredentials();
StartSniffer("snf-server start", ApplicationName);
break;
case StopSnifferCommand:
LoadCredentials();
StopSniffer("snf-server stop", ApplicationName);
break;
default:
break;
}
}
void
SNFServerConfig::SaveFileState() {
if (!Explain()) {
SaveFile.CreateBackupFile(GetRulebaseScriptName());
if (UpdateCredentialsSpecified()) {
SaveFile.CreateBackupFile(GetRulebaseFileName());
}
SaveFile.CreateBackupFile(GetIdentityFileName());
SaveFile.CreateBackupFile(GetIgnoreListFileName());
}
}
void
SNFServerConfig::UnintegrateWithAllExcept(std::string Except) {
if (Except != "postfix") {
Postfix.Unintegrate(&SaveFile);
}
if (Except != "sendmail") {
Sendmail.Unintegrate(&SaveFile);
}
}

+ 107
- 0
SNF_CS_Developer_Package/SNFUtility/SNFServerConfig/SNFServerConfig.hpp Voir le fichier

@@ -0,0 +1,107 @@
// \file SNFServerConfig.hpp
//
// Copyright (C) 2012 ARM Research Labs, LLC.
// See www.armresearch.com for the copyright terms.
//
// This file defines the SNFServerConfig interface.
//
// $Id$
//
///////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef SNFServerConfighpp_included
#define SNFServerConfighpp_included
#include <string>
#include "UtilityConfig.hpp"
#include "PostfixIntegrate.hpp"
#include "SendmailIntegrate.hpp"
/// Class to manage the SNFServer configuration.
//
// This class creates/maintains the sniffer configuration file, and
// integrates/unintegrates with MTAs.
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////
class SNFServerConfig : public UtilityConfig {
public:
/// Command specified.
enum CommandEnum {
SetupRepairCommand, ///< Setup or repair the configuration.
UpdateCredentialsCommand, ///< Update the credentials.
IntegrateWithPostfixCommand, ///< Integrate with postfix.
IntegrateWithSendmailCommand, ///< Integrate with sendmail.
IntegrateWithNoneCommand, ///< Unintegrate with all supported MTAs.
StartSnifferCommand, ///< Start the Sniffer.
StopSnifferCommand, ///< Stop the Sniffer.
NoCommand, ///< No command specified.
UnknownCommand ///< Unknown.
};
/// Display usage.
//
// \param[in] Version is the SNFServer version.
//
void DisplayHelp(std::string Version);
/// Get the command-line input parameters for SNFServer.
//
// \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[]);
/// Execute the command specified by the command-line parameters.
//
void ExecuteCommand(void);
/// Save the state of all files that might be changed, except the
/// config file.
//
void SaveFileState(void); // OBSOLETE.
private:
PostfixIntegrate Postfix; ///< Postfix integration object.
SendmailIntegrate Sendmail; ///< Sendmail integration object.
/// Unintegrate with MTAs.
//
// Unintegrate with all MTAs except the specified MTA.
//
// \param[in] Except is the MTA to not integrate with. The
// acceptable values are:
//
// <ol>
// <li> "postfix" </li>
// <li> "sendmail" </li>
// <li> "" </li>
// </ol>
//
// The default value is "", which specifies unintegration with all
// MTAs.
//
void UnintegrateWithAllExcept(std::string Except = "");
CommandEnum Command; ///< Specified command.
static const std::string DefaultConfigFile; ///< Default config file.
static const std::string SampleConfigFile; ///< Sample config file.
static const std::string SampleIdentityFile; ///< Sample identity file.
static const std::string ApplicationName; ///< Application name.
};
#endif

+ 459
- 0
SNF_CS_Developer_Package/SNFUtility/SNFServerConfig/SendmailIntegrate.cpp Voir le fichier

@@ -0,0 +1,459 @@
// /file SendmailIntegrate.cpp
//
// Copyright (C) 2011, ARM Research Labs, LLC.
// See www.armresearch.com for the copyright terms.
//
// This file contains the functions for SendmailIntegrate.
//
// $Id$
//
///////////////////////////////////////////////////////////////////////////////////////////////////
#include <cstdlib>
#include <cerrno>
#include <cstring>
#include <iostream>
#include <exception>
#include <stdexcept>
#include <sstream>
#include <fstream>
#include "SendmailIntegrate.hpp"
//////////////////////////////////////////////////////////////////////////////////////////////////////////
// Configuration. ////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////
const std::string SnfMilterSendmailMcSearchString("Added by SNFMilterConfig");
const std::string SnfMilterSendmailMcIntegrationString("INPUT_MAIL_FILTER(`SNFMilter', `S=unix:/var/snf-milter/socket')dnl # Added by SNFMilterConfig");
const std::string MtaIsRunningCommand("ps axl | grep -v grep | grep -q ' sendmail: '");
//////////////////////////////////////////////////////////////////////////////////////////////////////////
// End of configuration. /////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////
void
SendmailIntegrate::SetOperatingSystem(std::string OperatingSystemType) {
if ("OpenBSD" == OperatingSystemType) {
IntegrationIsSupported = false;
} else if ("FreeBSD" == OperatingSystemType) {
IntegrationIsSupported = false;
} else if ("Ubuntu" == OperatingSystemType) {
IntegrationIsSupported = true;
SendmailSendmailMcPath = "/etc/mail/sendmail.mc";
SendmailSendmailCfPath = "/etc/mail/sendmail.cf";
BuildInstallSendmailCfFile = "(cd /etc/mail && make)";
ReloadMtaCommand = "/etc/init.d/sendmail reload";
FileToBackup.push_back(SendmailSendmailMcPath);
FileToBackup.push_back(SendmailSendmailCfPath);
} else if ("RedHat" == OperatingSystemType) {
IntegrationIsSupported = true;
SendmailSendmailMcPath = "/etc/mail/sendmail.mc";
SendmailSendmailCfPath = "/etc/mail/sendmail.cf";
BuildInstallSendmailCfFile = "(cd /etc/mail && make)";
ReloadMtaCommand = "/etc/init.d/sendmail reload";
FileToBackup.push_back(SendmailSendmailMcPath);
FileToBackup.push_back(SendmailSendmailCfPath);
} else if ("Suse" == OperatingSystemType) {
IntegrationIsSupported = true;
SendmailSendmailMcPath = "/etc/mail/linux.mc";
SendmailSendmailCfPath = "/etc/mail/sendmail.cf";
BuildInstallSendmailCfFile = "(cd /etc/mail && rm -f sendmail.cf && m4 /etc/mail/linux.mc > sendmail.cf)";
ReloadMtaCommand = "/etc/init.d/sendmail reload";
FileToBackup.push_back(SendmailSendmailMcPath);
FileToBackup.push_back(SendmailSendmailCfPath);
} else {
std::ostringstream Temp;
Temp << "***Error from SendmailIntegrate::SetOperatingSystem: Invalid value of OperatingSystemType: "
<< OperatingSystemType;
throw std::runtime_error(Temp.str());
}
}
void
SendmailIntegrate::Integrate(FileBackup *SaveFile) {
if (!IntegrationIsSupported) {
return;
}
if (IsIntegrated()) {
return;
}
if (Verbose()) {
std::cout << "Add to sendmail file " << SendmailSendmailMcPath << ": '"
<< SnfMilterSendmailMcIntegrationString << "' and generate new "
<< SendmailSendmailCfPath << " file with the command '"
<< BuildInstallSendmailCfFile << "'...";
}
if (!Explain()) {
for (FileToBackupType::iterator iFile = FileToBackup.begin(); iFile != FileToBackup.end(); iFile++) {
SaveFile->CreateBackupFile(*iFile); // Save any existing file.
}
std::ofstream Output; // Append the configuration.
Output.open(SendmailSendmailMcPath.c_str(), std::ios::app);
if (!Output) {
std::string Temp;
Temp = "Error opening the sendmail configuration file " + SendmailSendmailMcPath;
Temp += " for writing: ";
Temp += strerror(errno);
throw std::runtime_error(Temp);
}
Output << SnfMilterSendmailMcIntegrationString << "\n";
if (!Output) {
std::string Temp;
Temp = "Error appending to the sendmail configuration file " + SendmailSendmailMcPath;
Temp += ": ";
Temp += strerror(errno);
throw std::runtime_error(Temp);
}
Output.close();
if (!Output) {
std::string Temp;
Temp = "Error closing the sendmail configuration file " + SendmailSendmailMcPath;
Temp += " after appending: ";
Temp += strerror(errno);
throw std::runtime_error(Temp);
}
if (std::system(BuildInstallSendmailCfFile.c_str()) != 0) {
std::string Temp;
Temp = "Error generating sendmail configuration file " + SendmailSendmailCfPath;
throw std::runtime_error(Temp);
}
}
OutputVerboseEnd();
if (!ReloadMta()) {
std::cerr << "Unable to reload the sendmail configuration. Please reload "
<< " the sendmail configuration for the integration with SNFMilter to take effect.";
}
}
void
SendmailIntegrate::Unintegrate(FileBackup *SaveFile) {
if (!IntegrationIsSupported) {
return;
}
if (!IsIntegrated()) {
return;
}
std::ifstream Input;
if (Verbose()) {
std::cout << "Remove integration in sendmail file " << SendmailSendmailMcPath
<< " and generate new " << SendmailSendmailCfPath << " file with the command '"
<< BuildInstallSendmailCfFile << "'--\n";
}
if (!Explain()) {
for (FileToBackupType::iterator iFile = FileToBackup.begin(); iFile != FileToBackup.end(); iFile++) {
SaveFile->CreateBackupFile(*iFile); // Save any existing file.
}
Input.open(SendmailSendmailMcPath.c_str()); // Read the contents.
if (!Input) {
std::string Temp;
Temp = "Error opening the sendmail configuration file " + SendmailSendmailMcPath;
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(SnfMilterSendmailMcSearchString)) { // Check for integration line.
if (Verbose()) {
std::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.
std::string Temp;
Temp = "Error reading the sendmail configuration file " + SendmailSendmailMcPath;
Temp += ": ";
Temp += strerror(errno);
throw std::runtime_error(Temp);
}
Input.close();
if (Input.bad()) {
std::string Temp;
Temp = "Error closing the sendmail configuration file " + SendmailSendmailMcPath;
Temp += " after reading: ";
Temp += strerror(errno);
throw std::runtime_error(Temp);
}
std::ofstream Output; // Write the updated contents.
Output.open(SendmailSendmailMcPath.c_str(), std::ios::trunc);
if (!Output) {
std::string Temp;
Temp = "Error opening the sendmail configuration file " + SendmailSendmailMcPath;
Temp += " for writing: ";
Temp += strerror(errno);
throw std::runtime_error(Temp);
}
Output << Content;
if (!Output) {
std::string Temp;
Temp = "Error writing the sendmail configuration file " + SendmailSendmailMcPath;
Temp += ": ";
Temp += strerror(errno);
throw std::runtime_error(Temp);
}
Output.close();
if (!Output) {
std::string Temp;
Temp = "Error closing the sendmail configuration file " + SendmailSendmailMcPath;
Temp += " after writing: ";
Temp += strerror(errno);
throw std::runtime_error(Temp);
}
if (std::system(BuildInstallSendmailCfFile.c_str()) != 0) { // Rebuild and install the sendmail configuration file.
std::string Temp;
Temp = "Error generating sendmail configuration file " + SendmailSendmailCfPath;
throw std::runtime_error(Temp);
}
}
OutputVerboseEnd();
if (!ReloadMta()) {
std::cerr << "Unable to reload the sendmail configuration. Please run "
<< "'sendmail reload' for the integration with SNFMilter to take effect.";
}
}
bool
SendmailIntegrate::MtaIsRunningDetected() {
if (Verbose()) {
std::cout << "Checking whether sendmail 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
SendmailIntegrate::ReloadMta() {
if (!MtaIsRunningDetected()) {
return true;
}
if (Verbose()) {
std::cout << "Reloading sendmail with the command '"
<< ReloadMtaCommand << "'...\n";
std::cout.flush();
}
bool Succeeded;
if (!Explain()) {
Succeeded = (std::system(ReloadMtaCommand.c_str()) == 0);
if (Verbose()) {
std::cout << (Succeeded ? "succeeded..." : "failed...");
}
}
OutputVerboseEnd();
return Succeeded;
}
bool
SendmailIntegrate::IsIntegrated() {
if (Verbose()) {
std::cout << "Checking for any SNFMilter integration in the sendmail file " << SendmailSendmailMcPath << "...";
}
if (!FileExists(SendmailSendmailMcPath)) {
if (Verbose()) {
std::cout << "file doesn't exist; sendmail is not integrated...";
}
OutputVerboseEnd();
return false;
}
bool Integrated = false;
std::ifstream Input;
Input.open(SendmailSendmailMcPath.c_str()); // Read the contents.
if (!Input) {
std::string Temp;
Temp = "Error opening the sendmail configuration file " + SendmailSendmailMcPath;
Temp += " for reading: ";
Temp += strerror(errno);
throw std::runtime_error(Temp);
}
std::string Line;
while (getline(Input, Line)) {
if (std::string::npos != Line.find(SnfMilterSendmailMcSearchString)) { // Check for integration line.
Integrated = true; // Found it.
break;
}
}
Input.close();
if (Input.bad()) {
std::string Temp;
Temp = "Error closing the sendmail configuration file " + SendmailSendmailMcPath;
Temp += " after reading: ";
Temp += strerror(errno);
throw std::runtime_error(Temp);
}
if (Verbose()) {
if (Integrated) {
std::cout << "found '" << Line << "'...";
} else {
std::cout << "none found...";
}
}
OutputVerboseEnd();
return Integrated;
}

+ 65
- 0
SNF_CS_Developer_Package/SNFUtility/SNFServerConfig/SendmailIntegrate.hpp Voir le fichier

@@ -0,0 +1,65 @@
// \file SendmailIntegrate.hpp
//
// Copyright (C) 2011 ARM Research Labs, LLC.
// See www.armresearch.com for the copyright terms.
//
// This file defines the SendmailIntegrate interface.
//
// $Id$
//
///////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef SendmailIntegratehpp_included
#define SendmailIntegratehpp_included
#include <vector>
#include "MtaIntegrate.hpp"
/// Class to manage the SNFMilter integration with sendmail.
//
// This class implements the MtaIntegrate interface for sendmail.
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////
class SendmailIntegrate : public MtaIntegrate {
public:
virtual void SetOperatingSystem(std::string OperatingSystemType);
virtual void Integrate(FileBackup *SaveFile);
virtual void Unintegrate(FileBackup *SaveFile);
private:
virtual bool MtaIsRunningDetected();
virtual bool ReloadMta();
virtual bool IsIntegrated();
/// Sendmail sendmail.mc file path.
std::string SendmailSendmailMcPath;
/// Sendmail sendmail.cf file path.
std::string SendmailSendmailCfPath;
/// Command to build and install the sendmail.cf file.
std::string BuildInstallSendmailCfFile;
/// Command to reload the MTA.
std::string ReloadMtaCommand;
/// True if integration is supported on this platform.
bool IntegrationIsSupported;
/// typedef for container of filenames to backup up before integrating or unintegrating.
typedef std::vector<std::string> FileToBackupType;
/// Files to back up before integrating or unintegrating.
FileToBackupType FileToBackup;
};
#endif

+ 115
- 0
SNF_CS_Developer_Package/SNFUtility/SNFServerConfig/main.cpp Voir le fichier

@@ -0,0 +1,115 @@
// 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 SNFServer.
//
// 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 "SNFServerConfig.hpp"
using namespace std;
//////////////////////////////////////////////////////////////////////////////////////////////////////////
// Configuration. ////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////
/// Version string.
const char* SNF_SERVERCONFIG_VERSION = "SNFServerConfig 0.0.1 Build: " __DATE__ " " __TIME__;
//////////////////////////////////////////////////////////////////////////////////////////////////////////
// End of configuration. /////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////
void RestoreFiles(SNFServerConfig *Config) {
try {
cerr << "Restoring all configuration files...";
Config->SaveFile.RestoreAllFilesFromBackup();
Config->SetOwnerPermissionsOfConfigFiles();
cerr << "done.\n\n"
<< "Configuration files that resulted in this error are saved with a suffix \""
<< Config->SaveFile.GetFailedFileName("") << "\".\n";
}
catch(exception& e) {
cerr << "SNFServerConfig::SaveFile Exception: " << e.what() << endl;
}
}
int main(int argc, char* argv[]) {
SNFServerConfig SnfServerConfig;
try { // Catch anything that breaks loose.
if (!SnfServerConfig.GetCommandLineInput(argc, argv) || // If our command line arguments
SnfServerConfig.Help()) { // don't look right, or if help is
// requested then display our help
SnfServerConfig.DisplayHelp(SNF_SERVERCONFIG_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_SERVERCONFIG_VERSION << endl; // watchers.
cout << "Debug Mode" << endl;
SnfServerConfig.SetDebug(true);
}
SnfServerConfig.ExecuteCommand();
} // That's all folks.
catch(exception& e) { // Report any normal exceptions.
cerr << "\n\nSNFServerConfig Exception: " << e.what() << endl << endl;
RestoreFiles(&SnfServerConfig);
return(-1);
}
catch (snfCFGmgr::LoadFailure) { // Error loading configuration file.
cerr << "\n\nsnfCFGmgr Exception: Unable to load the configuration file "
<< SnfServerConfig.GetConfigFileName() << endl << endl;
RestoreFiles(&SnfServerConfig);
return(-1);
}
catch(...) { // Report any unexpected exceptions.
cerr << "\n\nSNFServerConfig Panic! Unknown Exception!" << endl << endl;
RestoreFiles(&SnfServerConfig);
return(-1);
}
return 0; // Normally we return zero.
}

Chargement…
Annuler
Enregistrer