FluentFTP: Unhandled exception when OpenSSL fails to connect due to Authentication failed.
FTP Server OS: Unknown
FTP Server Type: Unknown
Client Computer OS: Debian
FluentFTP Version: 42.1.0
Framework: .NET 6
Just updated system from .netcore 3.1 to .net 6.0, and FluentFTP from 42.0.0 to 42.1.0, so I suspect this issue is triggered by the framework update rather than the FluentFTP update. However:
On trying to connect to the FTP server, OpenSSL is complaining that the SSL certificate is not trusted. This is actually correct, though it was working before.
However after failing to connect, it looks like an unhandled exception occurs (possibly in another thread or GC?), and this causes my process to be killed:
Logs :
I’ve not been able to get FluentFTP trace logs, however below is the exception that occurs.
[1 System.AggregateException: One or more errors occurred. (Authentication failed, see inner exception.)
[1 ---> System.Security.Authentication.AuthenticationException: Authentication failed, see inner exception.
[1 ---> Interop+OpenSsl+SslException: SSL Handshake failed with OpenSSL error - SSL_ERROR_SSL.
[1 ---> Interop+Crypto+OpenSslCryptographicException: error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure
[1 --- End of inner exception stack trace ---
[1 at Interop.OpenSsl.DoSslHandshake(SafeSslHandle context, ReadOnlySpan`1 input, Byte[]& sendBuf, Int32& sendCount)
[1 at System.Net.Security.SslStreamPal.HandshakeInternal(SafeFreeCredentials credential, SafeDeleteSslContext& context, ReadOnlySpan`1 inputBuffer, Byte[]& outputBuffer, SslAuthenticationOptions sslAuthenticationOptions)
[1 --- End of inner exception stack trace ---
[1 at System.Net.Security.SslStream.ForceAuthenticationAsync[TIOAdapter](TIOAdapter adapter, Boolean receiveFirst, Byte[] reAuthenticationData, Boolean isApm)
[1 --- End of inner exception stack trace ---
[1 at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
[1 at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
[1 at System.Threading.Tasks.Task.Wait()
[1 at FluentFTP.FtpSocketStream.ActivateEncryption(String targethost, X509CertificateCollection clientCerts, SslProtocols sslProtocols)
[1 at FluentFTP.FtpClient.Connect(Boolean reConnect)
[1 at FluentFTP.FtpClient.Connect()
Then a minute or two later:
[1 Unhandled exception. System.InvalidOperationException: This operation is only allowed using a successfully authenticated context.
[1 at System.Net.Security.SslStream.ThrowNotAuthenticated()
[1 at System.Net.Security.SslStream.ShutdownAsync()
[1 at FtpSslLib.FtpSslStream.Dispose(Boolean disposing)
[1 at System.Net.Security.SslStream.Finalize()
X.service: Main process exited, code=killed, status=6/ABRT
X.service: Failed with result 'signal'.
X.service: Service RestartSec=10s expired, scheduling restart.
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Comments: 50 (3 by maintainers)
Finally able to confirm that the process does not terminate now, just a regular exception instead. 👍
Oh dear, apologies I did not see a notification on this.
I could not get a log as my testcase program did not crash in the same way, and I couldn’t run the crashing code in production. However I will update to the new release and see what happens.
Sure
I’ll put it into master ASAP. AFAIK, @robinrodricks is planning a release very soon for a different issue and I will make sure it goes into that one.
We were getting a similar error connecting from Windows 10 dev machine to Unix FTP server:
I was using DownloadFile() on a test folder of about 5000 wav files. It always failed around the 1500 mark. I dropped in the updated FtpClient DLL per https://github.com/FanDjango/FluentFTP/tree/AuthExcept and the problem was fixed.
My question is, when will this fix be part of the downloadable Nuget package?
This is not entirely true. There are two use cases for this:
LeaveInnerStreamOpen=trueWhen the calling code owns the stream and/or stream is a buffered stream. In this case, before disposing, you need to flush the buffer. Here theSslStreamborrows the inner stream.LeaveInnerStreamOpen=falseWhen the calling code does not own the stream thenSslStreamowns the inner stream and onlySslStreamcan dispose inner stream since he is the only one who owns it.The global resource cleanup rule is who owns the resource cleans it
@robinrodricks
I already said that way upstairs.
Cannot fix is the one point, but I would still like to catch the failure correctly instead of having an unhandled exception.
Somehow all participants are hesitant to show a verbose log. Why? Especially since it is reproducible. Maybe all we need to do is modify our Dispose when the Authentication has not succeeded?
Hmmm. I’m not happy with that, yet.
Anyway:
SSL_ERROR_SSL A non-recoverable, fatal error in the SSL library occurred, usually a protocol error. The OpenSSL error queue contains more information on the error. If this error occurs then no further I/O operations should be performed on the connection and SSL_shutdown() must not be called.
Interop+OpenSsl+SslException: SSL Handshake failed with OpenSSL error - SSL_ERROR_SSL.
OpenSslCryptographicException: error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure
Googling gets hits, so it is not unknown: https://stackoverflow.com/questions/66885550/interop-crypto-opensslcryptographicexception-error14094410ssl-routinesssl3-r
This one looks interesting, too: https://github.com/dotnet/runtime/issues/47117