123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300 |
- // /file PostfixMilterConf.cpp
- //
- // Copyright (C) 2011, ARM Research Labs, LLC.
- // See www.armresearch.com for the copyright terms.
- //
- // This file contains the functions for PostfixMilterConf.
- //
- // $Id$
- //
- ///////////////////////////////////////////////////////////////////////////////////////////////////
-
- #include <exception>
- #include <stdexcept>
- #include <sstream>
-
- #include "Utility.hpp"
- #include "PostfixMilterConf.hpp"
-
- //////////////////////////////////////////////////////////////////////////////////////////////////////////
- // Configuration. ////////////////////////////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- /// SNFMilter socket specification.
- const std::string SnfMilterSocketSpec("unix:/var/snf-milter/socket");
-
- /// Milter keyword in the postfix main.cf file.
- const std::string SmtpdMilterKeyword("smtpd_milters");
-
- const std::string Whitespace(", \t");
-
- //////////////////////////////////////////////////////////////////////////////////////////////////////////
- // End of configuration. /////////////////////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- void
- PostfixMilterConf::ConfLine(std::string Line) {
-
- ConfigurationLine = Utility::Trim(Line); // Remove leading and trailing whitespace.
-
- }
-
- bool
- PostfixMilterConf::IsIntegrated() {
-
- return (IsMilterLine() && ContainsSnfMilterSocketSpec());
-
- }
-
- void
- PostfixMilterConf::AddIntegration() {
-
- if (IsIntegrated()) {
-
- return;
-
- }
-
- if (IsMilterLine()) { // Add to existing milter line.
-
- std::string NewConfLine;
-
- NewConfLine = SmtpdMilterKeyword + " =";
-
- // Skip to "=" in configuration line.
- std::string::size_type NextIndex;
-
- NextIndex = ConfigurationLine.find("=");
-
- if (std::string::npos == NextIndex) { // Check format.
-
- std::ostringstream Temp;
-
- Temp << "Error processing postfix main.cf file smtpd_milters line: '"
- << ConfigurationLine << "'";
-
- throw std::runtime_error(Temp.str());
-
- }
-
- std::string ExistingMilters;
-
- ExistingMilters = Utility::Trim(ConfigurationLine.substr(NextIndex + 1)); // Should contain existing milters.
-
- while (std::string::npos != NextIndex) {
-
- NewConfLine += " ";
-
- std::string NextMilter;
-
- NextIndex = ExistingMilters.find_first_of(Whitespace);
- NextMilter = Utility::Trim(ExistingMilters.substr(0, NextIndex));
- ExistingMilters = Utility::Trim(ExistingMilters.substr(NextIndex + 1));
-
- if (NextMilter == "") {
-
- std::ostringstream Temp;
-
- Temp << "Error processing postfix main.cf file smtpd_milters line: '"
- << ConfigurationLine << "'";
-
- throw std::runtime_error(Temp.str());
-
- }
-
- NewConfLine += NextMilter;
-
- }
-
- ConfigurationLine = NewConfLine + " ";
- ConfigurationLine += SnfMilterSocketSpec;
-
- } else if (ConfigurationLine == "") { // Empty configuration line.
-
- ConfigurationLine = SmtpdMilterKeyword + " = ";
- ConfigurationLine += SnfMilterSocketSpec;
-
- } else { // Unexpected non-empty line.
-
- std::ostringstream Temp;
-
- Temp << "Internal error: Attempted to modify a line in main.cf that does not begin with '"
- << SmtpdMilterKeyword << "'";
-
- throw std::runtime_error(Temp.str());
-
- }
-
- }
-
- void
- PostfixMilterConf::RemoveIntegration() {
-
- if (!IsIntegrated()) {
-
- return;
-
- }
-
- if (IsMilterLine()) { // Remove from an existing milter line.
-
- std::string NewConfLine;
-
- NewConfLine = SmtpdMilterKeyword + " =";
-
- // Skip to "=" in configuration line.
- std::string::size_type NextIndex;
-
- NextIndex = ConfigurationLine.find("=");
-
- if (std::string::npos == NextIndex) { // Check format.
-
- std::ostringstream Temp;
-
- Temp << "Error processing postfix main.cf file smtpd_milters line: '"
- << ConfigurationLine << "'";
-
- throw std::runtime_error(Temp.str());
-
- }
-
- std::string ExistingMilters;
- bool AddedMilter = false;
-
- ExistingMilters = Utility::Trim(ConfigurationLine.substr(NextIndex + 1)); // Should contain existing milters.
-
- while (ExistingMilters != "") {
-
- NewConfLine += " ";
-
- std::string NextMilter;
-
- NextIndex = ExistingMilters.find_first_of(" ,");
-
- if (std::string::npos == NextIndex) {
-
- NextMilter = ExistingMilters;
- ExistingMilters = "";
-
- } else {
-
- NextMilter = Utility::Trim(ExistingMilters.substr(0, NextIndex));
- ExistingMilters = Utility::Trim(ExistingMilters.substr(NextIndex + 1));
-
- }
-
- if (NextMilter == "") {
-
- std::ostringstream Temp;
-
- Temp << "Error processing postfix main.cf file smtpd_milters line: '"
- << ConfigurationLine << "'";
-
- throw std::runtime_error(Temp.str());
-
- }
-
- if (NextMilter != SnfMilterSocketSpec) { // Copy if not for SNFMilter.
-
- NewConfLine += NextMilter;
- AddedMilter = true;
-
- }
-
- }
-
- if (AddedMilter) {
-
- ConfigurationLine = NewConfLine;
-
- } else {
-
- ConfigurationLine = "";
-
- }
-
- } else { // Unexpected non-empty line.
-
- std::ostringstream Temp;
-
- Temp << "Internal error: Attempted to modify a line in main.cf that does not begin with '"
- << SmtpdMilterKeyword << "'";
-
- throw std::runtime_error(Temp.str());
-
- }
-
- }
-
- std::string
- PostfixMilterConf::ConfLine() {
-
- return ConfigurationLine;
-
- }
-
- bool
- PostfixMilterConf::IsMilterLine() {
-
- bool StartsWithKeyword;
- bool KeywordEndsCorrectly;
- char NextChar;
-
- StartsWithKeyword = (ConfigurationLine.find(SmtpdMilterKeyword) == 0);
-
- NextChar = ConfigurationLine[SmtpdMilterKeyword.length()];
-
- KeywordEndsCorrectly =
- (' ' == NextChar) ||
- ('\t' == NextChar) ||
- ('=' == NextChar);
-
- return (StartsWithKeyword && KeywordEndsCorrectly);
-
- }
-
- bool
- PostfixMilterConf::ContainsSnfMilterSocketSpec() {
-
- std::string::size_type SpecIndex;
-
- SpecIndex = ConfigurationLine.find("=");
-
- if (std::string::npos == SpecIndex) {
-
- return false;
-
- }
-
- SpecIndex++;
-
- while (SpecIndex < ConfigurationLine.length()) {
-
- SpecIndex = ConfigurationLine.find_first_not_of(Whitespace, SpecIndex); // Find next specification.
-
- if (ConfigurationLine.substr(SpecIndex, SnfMilterSocketSpec.length()) == SnfMilterSocketSpec) {
-
- SpecIndex += SnfMilterSocketSpec.length(); // Skip to after the specification.
- if (SpecIndex >= ConfigurationLine.length()) {
-
- return true; // No characters after the specification.
-
- }
-
- if ( (ConfigurationLine[SpecIndex] == ' ') ||
- (ConfigurationLine[SpecIndex] == '\t') ||
- (ConfigurationLine[SpecIndex] == ',') ) {
-
- return true; // Found specification.
-
- }
-
- }
-
- SpecIndex = ConfigurationLine.find_first_of(Whitespace, SpecIndex); // Find next specification.
-
- }
-
- return false;
-
- }
|