Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

PostfixMilterConf.cpp 6.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. // /file PostfixMilterConf.cpp
  2. //
  3. // Copyright (C) 2011, ARM Research Labs, LLC.
  4. // See www.armresearch.com for the copyright terms.
  5. //
  6. // This file contains the functions for PostfixMilterConf.
  7. //
  8. // $Id$
  9. //
  10. ///////////////////////////////////////////////////////////////////////////////////////////////////
  11. #include <exception>
  12. #include <stdexcept>
  13. #include <sstream>
  14. #include "Utility.hpp"
  15. #include "PostfixMilterConf.hpp"
  16. //////////////////////////////////////////////////////////////////////////////////////////////////////////
  17. // Configuration. ////////////////////////////////////////////////////////////////////////////////////////
  18. //////////////////////////////////////////////////////////////////////////////////////////////////////////
  19. /// SNFMilter socket specification.
  20. const std::string SnfMilterSocketSpec("unix:/var/snf-milter/socket");
  21. /// Milter keyword in the postfix main.cf file.
  22. const std::string SmtpdMilterKeyword("smtpd_milters");
  23. //////////////////////////////////////////////////////////////////////////////////////////////////////////
  24. // End of configuration. /////////////////////////////////////////////////////////////////////////////////
  25. //////////////////////////////////////////////////////////////////////////////////////////////////////////
  26. void
  27. PostfixMilterConf::ConfLine(std::string Line) {
  28. ConfigurationLine = Utility::Trim(Line); // Remove leading and trailing whitespace.
  29. }
  30. bool
  31. PostfixMilterConf::IsIntegrated() {
  32. return (IsMilterLine() && ContainsSnfMilterSocketSpec());
  33. }
  34. void
  35. PostfixMilterConf::AddIntegration() {
  36. if (IsIntegrated()) {
  37. return;
  38. }
  39. if (IsMilterLine()) { // Add to existing milter line.
  40. std::string NewConfLine;
  41. NewConfLine = SmtpdMilterKeyword + " =";
  42. // Skip to "=" in configuration line.
  43. std::string::size_type NextIndex;
  44. NextIndex = ConfigurationLine.find("=");
  45. if (std::string::npos == NextIndex) { // Check format.
  46. std::ostringstream Temp;
  47. Temp << "Error processing postfix main.cf file smtpd_milters line: '"
  48. << ConfigurationLine << "'";
  49. throw std::runtime_error(Temp.str());
  50. }
  51. std::string ExistingMilters;
  52. ExistingMilters = Utility::Trim(ConfigurationLine.substr(NextIndex + 1)); // Should contain existing milters.
  53. while (ExistingMilters != "") {
  54. NewConfLine += " ";
  55. std::string NextMilter;
  56. NextIndex = ExistingMilters.find_first_of(" ,");
  57. NextMilter = Utility::Trim(ExistingMilters.substr(0, NextIndex));
  58. ExistingMilters = Utility::Trim(ExistingMilters.substr(NextIndex + 1));
  59. if (NextMilter == "") {
  60. std::ostringstream Temp;
  61. Temp << "Error processing postfix main.cf file smtpd_milters line: '"
  62. << ConfigurationLine << "'";
  63. throw std::runtime_error(Temp.str());
  64. }
  65. NewConfLine += NextMilter;
  66. }
  67. ConfigurationLine = NewConfLine + " ";
  68. ConfigurationLine += SnfMilterSocketSpec;
  69. } else if (ConfigurationLine == "") { // Empty configuration line.
  70. ConfigurationLine = SmtpdMilterKeyword + " = ";
  71. ConfigurationLine += SnfMilterSocketSpec;
  72. } else { // Unexpected non-empty line.
  73. std::ostringstream Temp;
  74. Temp << "Internal error: Attempted to modify a line in main.cf that does not begin with '"
  75. << SmtpdMilterKeyword << "'";
  76. throw std::runtime_error(Temp.str());
  77. }
  78. }
  79. void
  80. PostfixMilterConf::RemoveIntegration() {
  81. if (!IsIntegrated()) {
  82. return;
  83. }
  84. if (IsMilterLine()) { // Remove from an existing milter line.
  85. std::string NewConfLine;
  86. NewConfLine = SmtpdMilterKeyword + " =";
  87. // Skip to "=" in configuration line.
  88. std::string::size_type NextIndex;
  89. NextIndex = ConfigurationLine.find("=");
  90. if (std::string::npos == NextIndex) { // Check format.
  91. std::ostringstream Temp;
  92. Temp << "Error processing postfix main.cf file smtpd_milters line: '"
  93. << ConfigurationLine << "'";
  94. throw std::runtime_error(Temp.str());
  95. }
  96. std::string ExistingMilters;
  97. bool AddedMilter = false;
  98. ExistingMilters = Utility::Trim(ConfigurationLine.substr(NextIndex + 1)); // Should contain existing milters.
  99. while (ExistingMilters != "") {
  100. NewConfLine += " ";
  101. std::string NextMilter;
  102. NextIndex = ExistingMilters.find_first_of(" ,");
  103. if (std::string::npos == NextIndex) {
  104. NextMilter = ExistingMilters;
  105. ExistingMilters = "";
  106. } else {
  107. NextMilter = Utility::Trim(ExistingMilters.substr(0, NextIndex));
  108. ExistingMilters = Utility::Trim(ExistingMilters.substr(NextIndex + 1));
  109. }
  110. if (NextMilter == "") {
  111. std::ostringstream Temp;
  112. Temp << "Error processing postfix main.cf file smtpd_milters line: '"
  113. << ConfigurationLine << "'";
  114. throw std::runtime_error(Temp.str());
  115. }
  116. if (NextMilter != SnfMilterSocketSpec) { // Copy if not for SNFMilter.
  117. NewConfLine += NextMilter;
  118. AddedMilter = true;
  119. }
  120. }
  121. if (AddedMilter) {
  122. ConfigurationLine = NewConfLine;
  123. } else {
  124. ConfigurationLine = "";
  125. }
  126. } else { // Unexpected non-empty line.
  127. std::ostringstream Temp;
  128. Temp << "Internal error: Attempted to modify a line in main.cf that does not begin with '"
  129. << SmtpdMilterKeyword << "'";
  130. throw std::runtime_error(Temp.str());
  131. }
  132. }
  133. std::string
  134. PostfixMilterConf::ConfLine() {
  135. return ConfigurationLine;
  136. }
  137. bool
  138. PostfixMilterConf::IsMilterLine() {
  139. return (ConfigurationLine.find(SmtpdMilterKeyword) == 0);
  140. }
  141. bool
  142. PostfixMilterConf::ContainsSnfMilterSocketSpec() {
  143. return (ConfigurationLine.find(SnfMilterSocketSpec) != std::string::npos);
  144. }