private void Init(Stream source) { if (source == null) { throw new ArgumentNullException(nameof(source)); } _current = new RedirectableStream(_source = source); _variableReader = new VariableStreamReader(_current); State = SecurableConnectionState.Open; }
public void Dispose() { _variableReader?.Dispose(); _variableReader = null; _encrypted?.Dispose(); _encrypted = null; _source?.Dispose(); _source = null; _current = null; _tcp?.Dispose(); _tcp = null; }
public async Task <IReadOnlyList <IMailReference> > TrySendMailsToStream( string target, IReadOnlyList <IMailReference> mails, Stream mxStream, CancellationToken token) { var unsent = new List <IMailReference>(); using (var stream = new RedirectableStream(mxStream)) using (var reader = new StreamReader(stream)) using (var writer = new StreamWriter(stream)) { SmtpResponse response = await ExecuteRemoteCommandAsync(writer, reader, $"EHLO {_settings.Value.DomainName}"); var startTls = false; if (response.Code == SmtpReplyCode.Greeting) { startTls = response.Lines.Contains("STARTTLS", StringComparer.OrdinalIgnoreCase); } else { response = await ExecuteRemoteCommandAsync(writer, reader, $"HELO {_settings.Value.DomainName}"); } if (response.Code != SmtpReplyCode.Greeting) { _log.Warning("Failed to HELO/EHLO, aborting"); return(mails); } if (startTls) { response = await ExecuteRemoteCommandAsync(writer, reader, "STARTTLS"); if (response.Code != SmtpReplyCode.Okay) { _log.Warning("Failed to STARTTLS, aborting"); return(mails); } var sslStream = new SslStream(mxStream, true, RemoteCertificateValidationCallback); try { await sslStream.AuthenticateAsClientAsync(target); } catch (Exception e) { _log.Warning($"Failed TLS negotiations: {e}"); return(mails); } stream.ChangeSteam(sslStream); } var allSuccess = true; foreach (IMailReference mail in mails) { if (!IsReadyToSend(mail)) { unsent.Add(mail); continue; } if (await TrySendSingleMailAsync(mail, writer, reader, token)) { _failures.RemoveFailure(mail.Id); continue; } unsent.Add(mail); allSuccess = false; } if (!allSuccess) { _log.Warning("Failed to send at least one mail"); return(unsent); } await SendCommandAsync(writer, "QUIT"); } return(unsent); }