|
|
@@ -1,6 +1,6 @@ |
|
|
|
// /file SendmailIntegrate.cpp
|
|
|
|
//
|
|
|
|
// Copyright (C) 2011, ARM Research Labs, LLC.
|
|
|
|
// Copyright (C) 2012, ARM Research Labs, LLC.
|
|
|
|
// See www.armresearch.com for the copyright terms.
|
|
|
|
//
|
|
|
|
// This file contains the functions for SendmailIntegrate.
|
|
|
@@ -25,10 +25,6 @@ |
|
|
|
// 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: '");
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
@@ -38,6 +34,8 @@ const std::string MtaIsRunningCommand("ps axl | grep -v grep | grep -q ' sendmai |
|
|
|
void
|
|
|
|
SendmailIntegrate::SetOperatingSystem(std::string OperatingSystemType) {
|
|
|
|
|
|
|
|
ProcmailRcFileName = "/etc/procmailrc";
|
|
|
|
|
|
|
|
if ("OpenBSD" == OperatingSystemType) {
|
|
|
|
|
|
|
|
IntegrationIsSupported = false;
|
|
|
@@ -51,6 +49,11 @@ SendmailIntegrate::SetOperatingSystem(std::string OperatingSystemType) { |
|
|
|
IntegrationIsSupported = true;
|
|
|
|
SendmailSendmailMcPath = "/etc/mail/sendmail.mc";
|
|
|
|
SendmailSendmailCfPath = "/etc/mail/sendmail.cf";
|
|
|
|
|
|
|
|
SnfSnifferDirName = "/var/spool/postfix/snf-server";
|
|
|
|
SnfSnifferFileName = SnfSnifferDirName + "/snfSnifferFilter";
|
|
|
|
SnfSnifferSampleFileName = "/usr/sbin/snfSnifferFilter.sample";
|
|
|
|
|
|
|
|
BuildInstallSendmailCfFile = "(cd /etc/mail && make)";
|
|
|
|
ReloadMtaCommand = "/etc/init.d/sendmail reload";
|
|
|
|
|
|
|
@@ -62,6 +65,11 @@ SendmailIntegrate::SetOperatingSystem(std::string OperatingSystemType) { |
|
|
|
IntegrationIsSupported = true;
|
|
|
|
SendmailSendmailMcPath = "/etc/mail/sendmail.mc";
|
|
|
|
SendmailSendmailCfPath = "/etc/mail/sendmail.cf";
|
|
|
|
|
|
|
|
SnfSnifferDirName = "/usr/sbin";
|
|
|
|
SnfSnifferFileName = SnfSnifferDirName + "/snfSnifferFilter";
|
|
|
|
SnfSnifferSampleFileName = SnfSnifferDirName + "/snfSnifferFilter.sample";
|
|
|
|
|
|
|
|
BuildInstallSendmailCfFile = "(cd /etc/mail && make)";
|
|
|
|
ReloadMtaCommand = "/etc/init.d/sendmail reload";
|
|
|
|
|
|
|
@@ -73,6 +81,11 @@ SendmailIntegrate::SetOperatingSystem(std::string OperatingSystemType) { |
|
|
|
IntegrationIsSupported = true;
|
|
|
|
SendmailSendmailMcPath = "/etc/mail/linux.mc";
|
|
|
|
SendmailSendmailCfPath = "/etc/mail/sendmail.cf";
|
|
|
|
|
|
|
|
SnfSnifferDirName = "/usr/sbin";
|
|
|
|
SnfSnifferFileName = SnfSnifferDirName + "/snfSnifferFilter";
|
|
|
|
SnfSnifferSampleFileName = SnfSnifferDirName + "/snfSnifferFilter.sample";
|
|
|
|
|
|
|
|
BuildInstallSendmailCfFile = "(cd /etc/mail && rm -f sendmail.cf && m4 /etc/mail/linux.mc > sendmail.cf)";
|
|
|
|
ReloadMtaCommand = "/etc/init.d/sendmail reload";
|
|
|
|
|
|
|
@@ -90,6 +103,9 @@ SendmailIntegrate::SetOperatingSystem(std::string OperatingSystemType) { |
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
ProcmailRcSnifferIntegration = ":0 fw\n| " + SnfSnifferFileName;
|
|
|
|
ProcmailRcSnifferIntegration += "\n";
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
@@ -109,38 +125,102 @@ SendmailIntegrate::Integrate(FileBackup *SaveFile) { |
|
|
|
|
|
|
|
if (Verbose()) {
|
|
|
|
|
|
|
|
std::cout << "Add to sendmail file " << SendmailSendmailMcPath << ": '"
|
|
|
|
<< SnfMilterSendmailMcIntegrationString << "' and generate new "
|
|
|
|
<< SendmailSendmailCfPath << " file with the command '"
|
|
|
|
<< BuildInstallSendmailCfFile << "'...";
|
|
|
|
std::cout << "Create " << SnfSnifferFileName << " if it doesn't exist...";
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!Explain()) {
|
|
|
|
|
|
|
|
if (!FileExists(SnfSnifferFileName)) { // Create SnfSnifferFilter script
|
|
|
|
// if it doesn't exist.
|
|
|
|
|
|
|
|
SaveFile->CreateBackupFile(SnfSnifferFileName);
|
|
|
|
|
|
|
|
if (!FileExists(SnfSnifferDirName)) {
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
OutputVerboseEnd();
|
|
|
|
|
|
|
|
if (Verbose()) {
|
|
|
|
|
|
|
|
std::cout << "Add\n\n" << ProcmailRcSnifferIntegration << "\n\nto " << ProcmailRcFileName << "...";
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string ProcmailRcFileContent;
|
|
|
|
|
|
|
|
if (!Explain()) {
|
|
|
|
|
|
|
|
for (FileToBackupType::iterator iFile = FileToBackup.begin(); iFile != FileToBackup.end(); iFile++) {
|
|
|
|
if (FileExists(ProcmailRcFileName)) { // Read any existing procmail configuration.
|
|
|
|
|
|
|
|
SaveFile->CreateBackupFile(*iFile); // Save any existing file.
|
|
|
|
std::ifstream Input;
|
|
|
|
|
|
|
|
Input.open(ProcmailRcFileName.c_str());
|
|
|
|
if (!Input) {
|
|
|
|
std::string Temp;
|
|
|
|
|
|
|
|
Temp = "Error opening the procmail configuration file " + ProcmailRcFileName;
|
|
|
|
Temp += " for reading: ";
|
|
|
|
Temp += strerror(errno);
|
|
|
|
throw std::runtime_error(Temp);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!Input.eof()) {
|
|
|
|
|
|
|
|
std::ostringstream Buffer;
|
|
|
|
|
|
|
|
Buffer << Input.rdbuf();
|
|
|
|
ProcmailRcFileContent = Buffer.str();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
Input.close();
|
|
|
|
if (!Input) {
|
|
|
|
std::string Temp;
|
|
|
|
|
|
|
|
Temp = "Error closing the procmail configuration file " + ProcmailRcFileName;
|
|
|
|
Temp += " after reading: ";
|
|
|
|
Temp += strerror(errno);
|
|
|
|
throw std::runtime_error(Temp);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
std::ofstream Output; // Append the configuration.
|
|
|
|
ProcmailRcFileContent = ProcmailRcSnifferIntegration + ProcmailRcFileContent;
|
|
|
|
|
|
|
|
SaveFile->CreateBackupFile(ProcmailRcFileName);
|
|
|
|
|
|
|
|
Output.open(SendmailSendmailMcPath.c_str(), std::ios::app);
|
|
|
|
std::ofstream Output; // Write the updated contents.
|
|
|
|
|
|
|
|
Output.open(ProcmailRcFileName.c_str(), std::ios::trunc);
|
|
|
|
if (!Output) {
|
|
|
|
std::string Temp;
|
|
|
|
|
|
|
|
Temp = "Error opening the sendmail configuration file " + SendmailSendmailMcPath;
|
|
|
|
Temp = "Error opening the procmail configuration file " + ProcmailRcFileName;
|
|
|
|
Temp += " for writing: ";
|
|
|
|
Temp += strerror(errno);
|
|
|
|
throw std::runtime_error(Temp);
|
|
|
|
}
|
|
|
|
|
|
|
|
Output << SnfMilterSendmailMcIntegrationString << "\n";
|
|
|
|
Output << ProcmailRcFileContent;
|
|
|
|
if (!Output) {
|
|
|
|
std::string Temp;
|
|
|
|
|
|
|
|
Temp = "Error appending to the sendmail configuration file " + SendmailSendmailMcPath;
|
|
|
|
Temp = "Error writing the procmail configuration file " + ProcmailRcFileName;
|
|
|
|
Temp += ": ";
|
|
|
|
Temp += strerror(errno);
|
|
|
|
throw std::runtime_error(Temp);
|
|
|
@@ -150,20 +230,10 @@ SendmailIntegrate::Integrate(FileBackup *SaveFile) { |
|
|
|
if (!Output) {
|
|
|
|
std::string Temp;
|
|
|
|
|
|
|
|
Temp = "Error closing the sendmail configuration file " + SendmailSendmailMcPath;
|
|
|
|
Temp += " after appending: ";
|
|
|
|
Temp = "Error closing the procmail configuration file " + ProcmailRcFileName;
|
|
|
|
Temp += " after writing: ";
|
|
|
|
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);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
@@ -173,7 +243,7 @@ SendmailIntegrate::Integrate(FileBackup *SaveFile) { |
|
|
|
if (!ReloadMta()) {
|
|
|
|
|
|
|
|
std::cerr << "Unable to reload the sendmail configuration. Please reload "
|
|
|
|
<< " the sendmail configuration for the integration with SNFMilter to take effect.";
|
|
|
|
<< " the sendmail configuration for the integration with SNFServer to take effect.";
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
@@ -198,76 +268,64 @@ SendmailIntegrate::Unintegrate(FileBackup *SaveFile) { |
|
|
|
|
|
|
|
if (Verbose()) {
|
|
|
|
|
|
|
|
std::cout << "Remove integration in sendmail file " << SendmailSendmailMcPath
|
|
|
|
<< " and generate new " << SendmailSendmailCfPath << " file with the command '"
|
|
|
|
<< BuildInstallSendmailCfFile << "'--\n";
|
|
|
|
std::cout << "Remove integration in procmail file " << ProcmailRcFileName << "--\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.
|
|
|
|
Input.open(ProcmailRcFileName.c_str());
|
|
|
|
if (!Input) {
|
|
|
|
std::string Temp;
|
|
|
|
|
|
|
|
Temp = "Error opening the sendmail configuration file " + SendmailSendmailMcPath;
|
|
|
|
Temp = "Error opening the procmail configuration file " + ProcmailRcFileName;
|
|
|
|
Temp += " for reading: ";
|
|
|
|
Temp += strerror(errno);
|
|
|
|
throw std::runtime_error(Temp);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string Content;
|
|
|
|
std::string Line;
|
|
|
|
std::ostringstream ContentStream;
|
|
|
|
|
|
|
|
while (getline(Input, Line)) {
|
|
|
|
ContentStream << Input.rdbuf();
|
|
|
|
|
|
|
|
if (std::string::npos != Line.find(SnfMilterSendmailMcSearchString)) { // Check for integration line.
|
|
|
|
Input.close();
|
|
|
|
if (!Input) {
|
|
|
|
std::string Temp;
|
|
|
|
|
|
|
|
if (Verbose()) {
|
|
|
|
Temp = "Error closing the procmail configuration file " + ProcmailRcFileName;
|
|
|
|
Temp += ": ";
|
|
|
|
Temp += strerror(errno);
|
|
|
|
throw std::runtime_error(Temp);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::cout << " Remove '" << Line << "'...\n";
|
|
|
|
std::string Content;
|
|
|
|
|
|
|
|
}
|
|
|
|
continue; // Do not copy this line.
|
|
|
|
Content = ContentStream.str();
|
|
|
|
|
|
|
|
}
|
|
|
|
if (Verbose()) {
|
|
|
|
|
|
|
|
Content += Line + "\n"; // Copy this line.
|
|
|
|
std::cout << " Remove all occurances of\n\n" << ProcmailRcSnifferIntegration << "\n\n"
|
|
|
|
<< " from" << ProcmailRcFileName << "...\n";
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!Input.eof()) { // Should be at end-of-file.
|
|
|
|
std::string Temp;
|
|
|
|
std::string::size_type IntegrationBegin = std::string::npos;
|
|
|
|
|
|
|
|
Temp = "Error reading the sendmail configuration file " + SendmailSendmailMcPath;
|
|
|
|
Temp += ": ";
|
|
|
|
Temp += strerror(errno);
|
|
|
|
throw std::runtime_error(Temp);
|
|
|
|
}
|
|
|
|
while ((IntegrationBegin = Content.find(ProcmailRcSnifferIntegration)) != std::string::npos) {
|
|
|
|
|
|
|
|
Input.close();
|
|
|
|
if (Input.bad()) {
|
|
|
|
std::string Temp;
|
|
|
|
Content.erase(IntegrationBegin, ProcmailRcSnifferIntegration.length());
|
|
|
|
|
|
|
|
Temp = "Error closing the sendmail configuration file " + SendmailSendmailMcPath;
|
|
|
|
Temp += " after reading: ";
|
|
|
|
Temp += strerror(errno);
|
|
|
|
throw std::runtime_error(Temp);
|
|
|
|
}
|
|
|
|
|
|
|
|
SaveFile->CreateBackupFile(ProcmailRcFileName);
|
|
|
|
|
|
|
|
std::ofstream Output; // Write the updated contents.
|
|
|
|
|
|
|
|
Output.open(SendmailSendmailMcPath.c_str(), std::ios::trunc);
|
|
|
|
Output.open(ProcmailRcFileName.c_str(), std::ios::trunc);
|
|
|
|
if (!Output) {
|
|
|
|
std::string Temp;
|
|
|
|
|
|
|
|
Temp = "Error opening the sendmail configuration file " + SendmailSendmailMcPath;
|
|
|
|
Temp = "Error opening the procmail configuration file " + ProcmailRcFileName;
|
|
|
|
Temp += " for writing: ";
|
|
|
|
Temp += strerror(errno);
|
|
|
|
throw std::runtime_error(Temp);
|
|
|
@@ -277,7 +335,7 @@ SendmailIntegrate::Unintegrate(FileBackup *SaveFile) { |
|
|
|
if (!Output) {
|
|
|
|
std::string Temp;
|
|
|
|
|
|
|
|
Temp = "Error writing the sendmail configuration file " + SendmailSendmailMcPath;
|
|
|
|
Temp = "Error writing the procmail configuration file " + ProcmailRcFileName;
|
|
|
|
Temp += ": ";
|
|
|
|
Temp += strerror(errno);
|
|
|
|
throw std::runtime_error(Temp);
|
|
|
@@ -287,21 +345,12 @@ SendmailIntegrate::Unintegrate(FileBackup *SaveFile) { |
|
|
|
if (!Output) {
|
|
|
|
std::string Temp;
|
|
|
|
|
|
|
|
Temp = "Error closing the sendmail configuration file " + SendmailSendmailMcPath;
|
|
|
|
Temp = "Error closing the procmail configuration file " + ProcmailRcFileName;
|
|
|
|
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();
|
|
|
@@ -309,7 +358,7 @@ SendmailIntegrate::Unintegrate(FileBackup *SaveFile) { |
|
|
|
if (!ReloadMta()) {
|
|
|
|
|
|
|
|
std::cerr << "Unable to reload the sendmail configuration. Please run "
|
|
|
|
<< "'sendmail reload' for the integration with SNFMilter to take effect.";
|
|
|
|
<< "'sendmail reload' for the integration with SNFServer to take effect.";
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
@@ -382,11 +431,11 @@ SendmailIntegrate::IsIntegrated() { |
|
|
|
|
|
|
|
if (Verbose()) {
|
|
|
|
|
|
|
|
std::cout << "Checking for any SNFMilter integration in the sendmail file " << SendmailSendmailMcPath << "...";
|
|
|
|
std::cout << "Checking for any SNFServer integration in the procmail file " << ProcmailRcFileName << "...";
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!FileExists(SendmailSendmailMcPath)) {
|
|
|
|
if (!FileExists(ProcmailRcFileName)) {
|
|
|
|
|
|
|
|
if (Verbose()) {
|
|
|
|
|
|
|
@@ -404,45 +453,45 @@ SendmailIntegrate::IsIntegrated() { |
|
|
|
|
|
|
|
std::ifstream Input;
|
|
|
|
|
|
|
|
Input.open(SendmailSendmailMcPath.c_str()); // Read the contents.
|
|
|
|
Input.open(ProcmailRcFileName.c_str()); // Read the contents.
|
|
|
|
if (!Input) {
|
|
|
|
std::string Temp;
|
|
|
|
|
|
|
|
Temp = "Error opening the sendmail configuration file " + SendmailSendmailMcPath;
|
|
|
|
Temp = "Error opening the procmail configuration file " + ProcmailRcFileName;
|
|
|
|
Temp += " for reading: ";
|
|
|
|
Temp += strerror(errno);
|
|
|
|
throw std::runtime_error(Temp);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string Line;
|
|
|
|
|
|
|
|
while (getline(Input, Line)) {
|
|
|
|
std::string ProcmailRcFileContent;
|
|
|
|
|
|
|
|
if (std::string::npos != Line.find(SnfMilterSendmailMcSearchString)) { // Check for integration line.
|
|
|
|
if (!Input.eof()) {
|
|
|
|
|
|
|
|
Integrated = true; // Found it.
|
|
|
|
std::ostringstream Buffer;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
Buffer << Input.rdbuf();
|
|
|
|
ProcmailRcFileContent = Buffer.str();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
Input.close();
|
|
|
|
if (Input.bad()) {
|
|
|
|
if (!Input) {
|
|
|
|
std::string Temp;
|
|
|
|
|
|
|
|
Temp = "Error closing the sendmail configuration file " + SendmailSendmailMcPath;
|
|
|
|
Temp = "Error closing the procmail configuration file " + ProcmailRcFileName;
|
|
|
|
Temp += " after reading: ";
|
|
|
|
Temp += strerror(errno);
|
|
|
|
throw std::runtime_error(Temp);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
Integrated = (ProcmailRcFileContent.find(ProcmailRcSnifferIntegration) != std::string::npos);
|
|
|
|
|
|
|
|
if (Verbose()) {
|
|
|
|
|
|
|
|
if (Integrated) {
|
|
|
|
|
|
|
|
std::cout << "found '" << Line << "'...";
|
|
|
|
std::cout << "found\n\n" << ProcmailRcSnifferIntegration << "\n\n...";
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|