PageRenderTime 23ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/Rnwood.Smtp4dev/ServerBehaviour.cs

https://bitbucket.org/fernandofig/smtp4dev
C# | 272 lines | 199 code | 52 blank | 21 comment | 30 complexity | 24cd3940625533e18768e7133dfc1575 MD5 | raw file
  1. #region
  2. using System;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using System.Net;
  6. using System.Security.Cryptography.X509Certificates;
  7. using System.Text;
  8. using Rnwood.Smtp4dev.Properties;
  9. using Rnwood.SmtpServer;
  10. using Rnwood.SmtpServer.Extensions;
  11. using Rnwood.SmtpServer.Extensions.Auth;
  12. #endregion
  13. namespace Rnwood.Smtp4dev
  14. {
  15. public class ServerBehaviour : IServerBehaviour
  16. {
  17. private readonly AuthExtension _authExtension = new AuthExtension();
  18. private readonly EightBitMimeExtension _eightBitMimeExtension = new EightBitMimeExtension();
  19. private readonly SizeExtension _sizeExtension = new SizeExtension();
  20. private readonly StartTlsExtension _startTLSExtension = new StartTlsExtension();
  21. #region IServerBehaviour Members
  22. public IEditableSession OnCreateNewSession(IConnection connection, IPAddress clientAddress, DateTime startDate)
  23. {
  24. if (!Settings.Default.MessageFolder.Exists)
  25. {
  26. Settings.Default.MessageFolder.Create();
  27. }
  28. FileInfo filename = null;
  29. while (filename == null || filename.Exists)
  30. {
  31. filename = new FileInfo(Path.Combine(Settings.Default.MessageFolder.FullName, "Session" +
  32. DateTime.Now.ToString("yyyy-MM-dd_HHmmss-ffff") + ".txt"));
  33. }
  34. return new FileSession(clientAddress, startDate, filename, false);
  35. }
  36. public Encoding GetDefaultEncoding(IConnection connection)
  37. {
  38. if (Settings.Default.DefaultTo8Bit)
  39. {
  40. return Encoding.Default;
  41. }
  42. return new ASCIISevenBitTruncatingEncoding();
  43. }
  44. public void OnMessageCompleted(IConnection connection)
  45. {
  46. if (Settings.Default.RejectMessages)
  47. {
  48. throw new SmtpServerException(
  49. new SmtpResponse(StandardSmtpResponseCode.TransactionFailed,
  50. "Message rejected - transaction failed"));
  51. }
  52. }
  53. public void OnMessageReceived(IConnection connection, IMessage message)
  54. {
  55. if (MessageReceived != null)
  56. {
  57. MessageReceived(this, new MessageEventArgs(message));
  58. }
  59. }
  60. public void OnMessageRecipientAdding(IConnection connection, IMessage message, string recipient)
  61. {
  62. if (Settings.Default.RejectRecipients)
  63. {
  64. throw new SmtpServerException(new SmtpResponse(StandardSmtpResponseCode.RecipientRejected,
  65. "Recipient rejected - mailbox unavailable"));
  66. }
  67. }
  68. public void OnSessionStarted(IConnection connection, ISession session)
  69. {
  70. }
  71. public void OnCommandReceived(IConnection connection, SmtpCommand command)
  72. {
  73. if (Settings.Default.CauseTimeout)
  74. {
  75. connection.ReadLine();
  76. }
  77. }
  78. public string DomainName
  79. {
  80. get { return Settings.Default.DomainName; }
  81. }
  82. public IPAddress IpAddress
  83. {
  84. get { return IPAddress.Parse(Settings.Default.IPAddress); }
  85. }
  86. public int PortNumber
  87. {
  88. get { return Settings.Default.PortNumber; }
  89. }
  90. public bool IsSSLEnabled(IConnection connection)
  91. {
  92. return Settings.Default.EnableSSL;
  93. }
  94. public int MaximumNumberOfSequentialBadCommands
  95. {
  96. get { return 10; }
  97. }
  98. public bool IsSessionLoggingEnabled(IConnection connection)
  99. {
  100. return true;
  101. }
  102. public X509Certificate GetSSLCertificate(IConnection connection)
  103. {
  104. if (string.IsNullOrEmpty(Settings.Default.SSLCertificatePath))
  105. {
  106. //RegistryKey key = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Microsoft SDKs\\Windows", false);
  107. //string sdkPath = (string)key.GetValue("CurrentInstallFolder", null);
  108. //if (sdkPath != null)
  109. //{
  110. // string makeCertPath = sdkPath + "\\bin\\makecert.exe";
  111. // string makeCertArgs =
  112. // "-r -pe -n CN=\"{0}\" -e {1} -eku 1.3.6.1.5.5.7.3.1 -sky exchange -ss my -sp \"Microsoft RSA SChannel Cryptographic Provider\" -sy 12";
  113. // if (Directory.Exists(sdkPath))
  114. // {
  115. // ProcessStartInfo psi = new ProcessStartInfo(makeCertPath, string.Format(makeCertArgs, DomainName, DateTime.Today.AddYears(1).ToString("MM/dd/yyyy"))) { CreateNoWindow = true, UseShellExecute = false };
  116. // Process process = Process.Start(psi);
  117. // process.Start();
  118. // process.WaitForExit();
  119. // if (process.ExitCode == 0)
  120. // {
  121. // X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
  122. // store.Open(OpenFlags.ReadOnly);
  123. // return store.Certificates.Find(X509FindType.FindBySubjectName, DomainName, false)[0];
  124. // }
  125. // }
  126. //}
  127. return null;
  128. }
  129. if (string.IsNullOrEmpty(Settings.Default.SSLCertificatePassword))
  130. {
  131. return new X509Certificate(Settings.Default.SSLCertificatePath);
  132. }
  133. return new X509Certificate(Settings.Default.SSLCertificatePath, Settings.Default.SSLCertificatePassword);
  134. }
  135. public IEnumerable<IExtension> GetExtensions(IConnection connection)
  136. {
  137. List<IExtension> extensions = new List<IExtension>();
  138. if (Settings.Default.Enable8BITMIME)
  139. {
  140. extensions.Add(_eightBitMimeExtension);
  141. }
  142. if (Settings.Default.EnableSTARTTLS)
  143. {
  144. extensions.Add(_startTLSExtension);
  145. }
  146. if (Settings.Default.EnableAUTH)
  147. {
  148. extensions.Add(_authExtension);
  149. }
  150. if (Settings.Default.EnableSIZE)
  151. {
  152. extensions.Add(_sizeExtension);
  153. }
  154. return extensions;
  155. }
  156. public long? GetMaximumMessageSize(IConnection connection)
  157. {
  158. long value = Settings.Default.MaximumMessageSize;
  159. return value != 0 ? value : (long?)null;
  160. }
  161. public void OnSessionCompleted(IConnection connection, ISession Session)
  162. {
  163. if (SessionCompleted != null)
  164. {
  165. SessionCompleted(this, new SessionEventArgs(Session));
  166. }
  167. }
  168. public int GetReceiveTimeout(IConnection connection)
  169. {
  170. return Settings.Default.ReceiveTimeout;
  171. }
  172. public AuthenticationResult ValidateAuthenticationCredentials(IConnection connection,
  173. IAuthenticationCredentials authenticationRequest)
  174. {
  175. if (Settings.Default.FailAuthentication)
  176. {
  177. return AuthenticationResult.Failure;
  178. }
  179. return AuthenticationResult.Success;
  180. }
  181. public void OnMessageStart(IConnection connection, string from)
  182. {
  183. if (Settings.Default.RequireAuthentication && !connection.Session.Authenticated)
  184. {
  185. throw new SmtpServerException(new SmtpResponse(StandardSmtpResponseCode.AuthenticationRequired,
  186. "Must authenticate before sending mail"));
  187. }
  188. if (Settings.Default.RequireSecureConnection && !connection.Session.SecureConnection)
  189. {
  190. throw new SmtpServerException(new SmtpResponse(StandardSmtpResponseCode.BadSequenceOfCommands,
  191. "Mail must be sent over secure connection"));
  192. }
  193. }
  194. public bool IsAuthMechanismEnabled(IConnection connection, IAuthMechanism authMechanism)
  195. {
  196. if (Settings.Default.OnlyAllowClearTextAuthOverSecureConnection)
  197. {
  198. return (!authMechanism.IsPlainText) || connection.Session.SecureConnection;
  199. }
  200. return true;
  201. }
  202. public IEditableMessage OnCreateNewMessage(IConnection connection)
  203. {
  204. if (!Settings.Default.MessageFolder.Exists)
  205. {
  206. Settings.Default.MessageFolder.Create();
  207. }
  208. FileInfo filename = null;
  209. while (filename == null || filename.Exists)
  210. {
  211. filename = new FileInfo(Path.Combine(Settings.Default.MessageFolder.FullName,
  212. DateTime.Now.ToString("yyyy-MM-dd_HHmmss-ffff") + ".eml"));
  213. }
  214. return new FileMessage(connection.Session, filename, false);
  215. }
  216. #endregion
  217. public event EventHandler<MessageEventArgs> MessageReceived;
  218. public event EventHandler<SessionEventArgs> SessionCompleted;
  219. }
  220. }