1616using Zetian . Protocol ;
1717using Zetian . Relay . Abstractions ;
1818using Zetian . Relay . Models ;
19+ using Zetian . Relay . Services ;
1920
2021namespace Zetian . Relay . Client
2122{
@@ -62,13 +63,27 @@ public async Task ConnectAsync(CancellationToken cancellationToken = default)
6263 using CancellationTokenSource cts = CancellationTokenSource . CreateLinkedTokenSource ( cancellationToken ) ;
6364 cts . CancelAfter ( Timeout ) ;
6465
65- await _tcpClient . ConnectAsync ( Host , Port ) . ConfigureAwait ( false ) ;
66+ await _tcpClient . ConnectAsync ( Host , Port , cts . Token ) . ConfigureAwait ( false ) ;
6667
6768 _stream = _tcpClient . GetStream ( ) ;
6869
6970 if ( EnableSsl )
7071 {
71- await UpgradeToSslAsync ( cts . Token ) . ConfigureAwait ( false ) ;
72+ try
73+ {
74+ await UpgradeToSslAsync ( cts . Token ) . ConfigureAwait ( false ) ;
75+ }
76+ catch ( Exception )
77+ {
78+ _logger . LogInformation ( "Failed to connect as SMTPS on {Host}:{Port}" , Host , Port ) ;
79+
80+ _stream . Close ( ) ;
81+ await _stream . DisposeAsync ( ) ;
82+
83+ _tcpClient = new TcpClient ( ) ;
84+ await _tcpClient . ConnectAsync ( Host , Port , cts . Token ) . ConfigureAwait ( false ) ;
85+ _stream = _tcpClient . GetStream ( ) ;
86+ }
7287 }
7388
7489 _reader = new StreamReader ( _stream , Encoding . ASCII ) ;
@@ -84,6 +99,15 @@ public async Task ConnectAsync(CancellationToken cancellationToken = default)
8499 // Send EHLO
85100 await SendEhloAsync ( cts . Token ) . ConfigureAwait ( false ) ;
86101
102+ // Upgrade the connection to STARTTLS if allowed
103+ if ( EnableSsl && _stream is not SslStream && _serverCapabilities ? . ContainsKey ( "STARTTLS" ) == true )
104+ {
105+ await UpgradeToStartTlsAsync ( cts . Token ) . ConfigureAwait ( false ) ;
106+
107+ _reader = new StreamReader ( _stream , Encoding . ASCII ) ;
108+ _writer = new StreamWriter ( _stream , Encoding . ASCII ) { AutoFlush = true } ;
109+ }
110+
87111 _logger . LogInformation ( "Connected to {Host}:{Port}" , Host , Port ) ;
88112 }
89113 catch ( Exception ex )
@@ -398,6 +422,18 @@ await sslStream.AuthenticateAsClientAsync(
398422 _logger . LogDebug ( "SSL/TLS connection established" ) ;
399423 }
400424
425+ private async Task UpgradeToStartTlsAsync ( CancellationToken cancellationToken )
426+ {
427+ await SendCommandAsync ( "STARTTLS" , cancellationToken ) . ConfigureAwait ( false ) ;
428+
429+ SmtpResponse response = await ReadResponseAsync ( cancellationToken ) . ConfigureAwait ( false ) ;
430+
431+ if ( response . IsSuccess )
432+ {
433+ await UpgradeToSslAsync ( cancellationToken ) ;
434+ }
435+ }
436+
401437 private async Task AuthPlainAsync ( CancellationToken cancellationToken )
402438 {
403439 if ( Credentials == null )
0 commit comments