Browse Source

Implemented SNFMilter integration with sendmail, completed test

SENDMAIL-01 (on ubuntu).


git-svn-id: https://svn.microneil.com/svn/SNFUtility/trunk@35 aa37657e-1934-4a5f-aa6d-2d8eab27ff7c
master
adeniz 12 years ago
parent
commit
4efc49b531

+ 2
- 1
Common/Utility.cpp View File

if (!Explain()) { if (!Explain()) {
errno = 0;
SNFPasswd = getpwnam(SNFUserName.c_str()); SNFPasswd = getpwnam(SNFUserName.c_str());
if (SNFPasswd == 0) { if (SNFPasswd == 0) {
string Temp; string Temp;
Temp = "Error getting info for Sniffer user " + SNFUserName; Temp = "Error getting info for Sniffer user " + SNFUserName;
Temp += ": "; Temp += ": ";
Temp += strerror(errno);
Temp += ((errno == 0) ? "No such user; create the user and try again." : strerror(errno));
throw runtime_error(Temp); throw runtime_error(Temp);
} }
SNFUid = SNFPasswd->pw_uid; SNFUid = SNFPasswd->pw_uid;

+ 4
- 2
SNFMilterConfig/Makefile.am View File

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


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


EXTRA_DIST = \ EXTRA_DIST = \
Makefile.am \ Makefile.am \

+ 8
- 7
SNFMilterConfig/SNFMilterConfig.cpp View File

<< " " << DefaultConfigFile << "\n\n" << " " << DefaultConfigFile << "\n\n"
<< "If the above file doesn't exist, then it is copied from the following file:\n\n" << "If the above file doesn't exist, then it is copied from the following file:\n\n"
<< " " << SampleConfigFile << "\n\n" << " " << SampleConfigFile << "\n\n"
<< "If integration with an MTA is specified, that MTA is started if it isn't running,\n"
<< "or the MTA's configuration is reloaded if it is running.\n\n";
<< "If integration with an MTA is specified, the MTA's configuration is reloaded "
<< "if the MTA is running.\n\n";
}; };
Postfix.SetVerbose(Verbose()); Postfix.SetVerbose(Verbose());
Postfix.SetExplain(Explain()); Postfix.SetExplain(Explain());
#if 0
Sendmail.SetOperatingSystem(GetOperatingSystemType()); Sendmail.SetOperatingSystem(GetOperatingSystemType());
Sendmail.SetVerbose(Verbose()); Sendmail.SetVerbose(Verbose());
Sendmail.SetExplain(Explain()); Sendmail.SetExplain(Explain());
#endif
SetConfigFileName(DefaultConfigFile); SetConfigFileName(DefaultConfigFile);
case IntegrateWithSendmailCommand: case IntegrateWithSendmailCommand:
UnintegrateWithAllExcept("sendmail");
Sendmail.Integrate(&SaveFile);
break; break;
case IntegrateWithNoneCommand: case IntegrateWithNoneCommand:
case IntegrateWithSendmailCommand: case IntegrateWithSendmailCommand:
UnintegrateWithAllExcept("sendmail"); UnintegrateWithAllExcept("sendmail");
// Sendmail.Integrate(&SaveFile);
Sendmail.Integrate(&SaveFile);
break; break;
default: default:
Postfix.Unintegrate(&SaveFile); Postfix.Unintegrate(&SaveFile);
} }
#if 0
if (Except != "sendmail") { if (Except != "sendmail") {
Sendmail.Unintegrate(&SaveFile); Sendmail.Unintegrate(&SaveFile);
} }
#endif
} }

+ 3
- 0
SNFMilterConfig/SNFMilterConfig.hpp View File

#include "UtilityConfig.hpp" #include "UtilityConfig.hpp"
#include "PostfixIntegrate.hpp" #include "PostfixIntegrate.hpp"
#include "SendmailIntegrate.hpp"
/// Class to manage the SNFMilter configuration. /// Class to manage the SNFMilter configuration.
// //
PostfixIntegrate Postfix; ///< Postfix integration object. PostfixIntegrate Postfix; ///< Postfix integration object.
SendmailIntegrate Sendmail; ///< Sendmail integration object.
/// Unintegrate with MTAs. /// Unintegrate with MTAs.
// //
// Unintegrate with all MTAs except the specified MTA. // Unintegrate with all MTAs except the specified MTA.

+ 142
- 0
SNFMilterConfig/SNFMilterConfigTests.txt View File

POSTFIX-11: Repeat POSTFIX-01 and POSTFIX-04 on FreeBSD. POSTFIX-11: Repeat POSTFIX-01 and POSTFIX-04 on FreeBSD.


Result: Pass. Result: Pass.

Integration with sendmail
------------------------

SENDMAIL-01: On Ubuntu, set up the environment as follows:

1) Default configuration files for SNFMilter.

2) SNFMilter stopped.

3) Default configuration files for sendmail.

4) sendmail stopped.

Do the following:

1) Run SNFMilterConfig with "-with=sendmail -v" and verify that the
sendmail configuration files are updated to be integrated with
SNFMilter. Verify also that both sendmail and SNFMilter are
stopped.

2) Run SNFMilterConfig with "-with=sendmail -v" and verify that the
sendmail configuration files are not updated, and that both
sendmail and SNFMilter are stopped.

3) Run SNFMilterConfig with "-with=none -v" and verify that the
sendmail configuration files are updated such that the integration
with SNFMilter is removed. Verify also that both sendmail and
SNFMilter are stopped.

4) Run SNFMilterConfig with "-with=none -v" and verify that the
sendmail configuration files are not updated, and that both
sendmail and SNFMilter are stopped.

Result: Pass.

SENDMAIL-02: Repeat SENDMAIL-01 but without "-v".

Result:

SENDMAIL-03: Configure as for SENDMAIL-01, and do the following:

1) Run SNFMilterConfig with "-with=sendmail -explain". Verify
correct output, and that SNFMilterConfig doesn't update the
sendmail configuration files or reload any MTA.

2) Run SNFMilterConfig with "-with=none -explain". Verify correct
output, and that SNFMilterConfig doesn't update the sendmail
configuration files or reload any MTA.

3) Run SNFMilterConfig with "-with=sendmail". Verify correct output,
and that SNFMilterConfig updates the sendmail configuration files.

4) Run SNFMilterConfig with "-with=sendmail -explain". Verify
correct output, and that SNFMilterConfig doesn't update the
sendmail configuration files or reload any MTA.

5) Run SNFMilterConfig with "-with=none -explain". Verify correct
output, and that SNFMilterConfig doesn't update the sendmail
configuration files or reload any MTA.

Result:

SENDMAIL-04: On Ubuntu, set up the environment as follows:

1) Default configuration files for SNFMilter.

2) SNFMilter stopped.

3) Default configuration files for sendmail.

4) sendmail running.

Do the following:

1) Run SNFMilterConfig with "-with=sendmail -v" and verify that the
sendmail configuration files are updated to be integrated with
SNFMilter. Verify also that SNFMilter is not running and that
sendmail is running and was reloaded.

2) Run SNFMilterConfig with "-with=sendmail -v" and verify that the
sendmail configuration files are not updated, that SNFMilter is
not running, and that sendmail is running and was not reloaded.

3) Run SNFMilterConfig with "-with=none -v" and verify that the
sendmail configuration files are updated such that the integration
with SNFMilter is removed. Verify also that SNFMilter is not
running, and that sendmail is running and was not reloaded.

4) Run SNFMilterConfig with "-with=none -v" and verify that the
sendmail configuration files are not updated, and that SNFMilter
is not running and that sendmail is running and was not reloaded.

Result:

SENDMAIL-05: Repeat SENDMAIL-04 but without "-v".

Result:

SENDMAIL-06: Configure as for SENDMAIL-04, and do the following:

1) Run SNFMilterConfig with "-with=sendmail -explain". Verify
correct output, and that SNFMilterConfig doesn't update the
sendmail configuration files or reload any MTA.

2) Run SNFMilterConfig with "-with=none -explain". Verify correct
output, and that SNFMilterConfig doesn't update the sendmail
configuration files or reload any MTA.

3) Run SNFMilterConfig with "-with=sendmail". Verify correct output,
and that SNFMilterConfig updates the sendmail configuration files
and reloads the MTA.

4) Run SNFMilterConfig with "-with=sendmail -explain". Verify
correct output, and that SNFMilterConfig doesn't update the
sendmail configuration files or reload any MTA.

5) Run SNFMilterConfig with "-with=none -explain". Verify correct
output, and that SNFMilterConfig doesn't update the sendmail
configuration files or reload any MTA.

Result:

SENDMAIL-07: Repeat SENDMAIL-01 and SENDMAIL-04 on Fedora.

Result:

SENDMAIL-08: Repeat SENDMAIL-01 and SENDMAIL-04 on OpenSuse.

Result:

SENDMAIL-09: Repeat SENDMAIL-01 and SENDMAIL-04 on CentOS.

Result:

SENDMAIL-10: Repeat SENDMAIL-01 and SENDMAIL-04 on OpenBSD.

Result:

SENDMAIL-11: Repeat SENDMAIL-01 and SENDMAIL-04 on FreeBSD.

Result:

+ 450
- 0
SNFMilterConfig/SendmailIntegrate.cpp View File

// /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: MTA:'");
//////////////////////////////////////////////////////////////////////////////////////////////////////////
// End of configuration. /////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////
void
SendmailIntegrate::SetOperatingSystem(std::string OperatingSystemType) {
if ("OpenBSD" == OperatingSystemType) {
SendmailSendmailMcPath = "/etc/mail/sendmail.mc";
SendmailSendmailCfPath = "/etc/mail/sendmail.cf";
ReloadMtaCommand = "/usr/local/sbin/postfix reload";
FileToBackup.push_back(SendmailSendmailMcPath);
FileToBackup.push_back(SendmailSendmailCfPath);
} else if ("FreeBSD" == OperatingSystemType) {
SendmailSendmailMcPath = "/etc/mail/sendmail.mc";
SendmailSendmailCfPath = "/etc/mail/sendmail.cf";
ReloadMtaCommand = "/usr/local/sbin/postfix reload";
FileToBackup.push_back(SendmailSendmailMcPath);
FileToBackup.push_back(SendmailSendmailCfPath);
} else if ("Ubuntu" == OperatingSystemType) {
SendmailSendmailMcPath = "/etc/mail/sendmail.mc";
SendmailSendmailCfPath = "/etc/mail/sendmail.cf";
BuildInstallSendmailCfFile = "(cd /etc/mail; make)";
ReloadMtaCommand = "/usr/sbin/service sendmail reload";
FileToBackup.push_back(SendmailSendmailMcPath);
FileToBackup.push_back(SendmailSendmailCfPath);
} else if ("RedHat" == OperatingSystemType) {
SendmailSendmailMcPath = "/etc/mail/sendmail.mc";
SendmailSendmailCfPath = "/etc/mail/sendmail.cf";
BuildInstallSendmailCfFile = "(cd /etc/mail; make)";
ReloadMtaCommand = "/usr/sbin/postfix reload";
FileToBackup.push_back(SendmailSendmailMcPath);
FileToBackup.push_back(SendmailSendmailCfPath);
} else if ("Suse" == OperatingSystemType) {
SendmailSendmailMcPath = "/etc/mail/linux.mc";
SendmailSendmailCfPath = "/etc/mail/sendmail.cf";
BuildInstallSendmailCfFile = "(cd /etc/mail; rm sendmail.cf; m4 /etc/mail/linux.mc > sendmail.cf)";
ReloadMtaCommand = "/usr/sbin/postfix 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 (IsIntegrated()) {
return;
}
if (Verbose()) {
std::cout << "Add to sendmail file " << SendmailSendmailMcPath << ": '"
<< SnfMilterSendmailMcIntegrationString << "' and generate new "
<< SendmailSendmailCfPath << " file...";
}
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 (!IsIntegrated()) {
return;
}
std::ifstream Input;
if (Verbose()) {
std::cout << "Remove integration in sendmail file " << SendmailSendmailMcPath << "--\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...\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;
}

+ 62
- 0
SNFMilterConfig/SendmailIntegrate.hpp View File

// \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;
/// 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

Loading…
Cancel
Save