Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SQL Server pre-login handshake failed Android 5,6,8.1 #6990

Closed
Eilon opened this issue May 9, 2022 · 18 comments
Closed

SQL Server pre-login handshake failed Android 5,6,8.1 #6990

Eilon opened this issue May 9, 2022 · 18 comments
Assignees
Labels
Area: Mono Runtime Mono-related issues: BCL bugs, AOT issues, etc.

Comments

@Eilon
Copy link
Member

Eilon commented May 9, 2022


Issue moved from dotnet/maui#6859


From @janseris on Thursday, May 5, 2022 12:39:34 PM

Description

SQL Server - the connection was established but pre-login handshake failed when calling database via Entity Framework

**Microsoft.Data.SqlClient.SqlException:** 'A connection was successfully established with the server, but then an error occurred during the pre-login handshake. (provider: TCP Provider, error: 35 - An internal exception was caught)'

What does not help:

  • Encrypt=false in connection string
  • Encrypt=true in connection string
  • Encrypt=false;TrustServerCertificate=true; in connection string

The same works without any issue on Android 9 and up (both emulator and real device).
Tested: works on Android 9 for all TLS settings: Native TLS 1.2+ and Managed TLS 1.0 and also for "no option".

image

The issue is in Debug (and thus probably also in Release) configuration.

Output for Android 5 (API 21):
Microsoft.Data.SqlClient.SqlException: 'A connection was successfully established with the server, but then an error occurred during the pre-login handshake. (provider: TCP Provider, error: 35 - An internal exception was caught)'

Output for Android 8, for all TLS configuration options: Native TLS 1.2+ and Managed TLS 1.0 and also for "no option".

[System.err] java.lang.IllegalStateException: Handshake has already been started
[System.err] 	at com.android.org.conscrypt.OpenSSLEngineImpl.beginHandshakeInternal(OpenSSLEngineImpl.java:335)
[System.err] 	at com.android.org.conscrypt.OpenSSLEngineImpl.beginHandshake(OpenSSLEngineImpl.java:325)
[System.err] 	at crc640ec207abc449b2ca.ShellSectionRenderer.n_onCreateView(Native Method)
[System.err] 	at crc640ec207abc449b2ca.ShellSectionRenderer.onCreateView(ShellSectionRenderer.java:42)
[System.err] 	at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2995)
[System.err] 	at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:523)
[System.err] 	at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:261)
[System.err] 	at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1840)
[System.err] 	at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1764)
[System.err] 	at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1701)
[System.err] 	at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2849)
[System.err] 	at androidx.fragment.app.FragmentManager.dispatchViewCreated(FragmentManager.java:2777)
[System.err] 	at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:3020)
[System.err] 	at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:551)
[System.err] 	at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:261)
[System.err] 	at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1840)
[System.err] 	at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1764)
[System.err] 	at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1701)
[System.err] 	at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:2849)
[System.err] 	at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:2784)
[System.err] 	at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:262)
[System.err] 	at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:478)
[System.err] 	at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:246)
[System.err] 	at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1333)
[System.err] 	at android.app.Activity.performStart(Activity.java:6992)
[System.err] 	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2780)
[System.err] 	at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)
[System.err] 	at android.app.ActivityThread.-wrap11(Unknown Source:0)
[System.err] 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)
[System.err] 	at android.os.Handler.dispatchMessage(Handler.java:105)
[System.err] 	at android.os.Looper.loop(Looper.java:164)
[System.err] 	at android.app.ActivityThread.main(ActivityThread.java:6541)
[System.err] 	at java.lang.reflect.Method.invoke(Native Method)
[System.err] 	at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
[System.err] 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
**Microsoft.Data.SqlClient.SqlException:** 'A connection was successfully established with the server, but then an error occurred during the pre-login handshake. (provider: TCP Provider, error: 35 - An internal exception was caught)'

Similar issues:
dotnet/maui#3522

Steps to Reproduce

call database in a MAUI app with Android 8.1 or lower

Version with bug

Release Candidate 2 (current)

Last version that worked well

Unknown/Other

Affected platforms

Android

Affected platform versions

Android 8.1 and below

Did you find any workaround?

no

Relevant log output

No response

@Eilon
Copy link
Member Author

Eilon commented May 9, 2022


Issue moved from dotnet/maui#6859


From @Redth on Thursday, May 5, 2022 1:25:46 PM

Generally best practice would be to not connect directly to a database from a mobile application where you'll risk the server credentials being discoverable.

Aside from that, @jonpryor any ideas?

@Eilon
Copy link
Member Author

Eilon commented May 9, 2022


Issue moved from dotnet/maui#6859


From @drasticactions on Thursday, May 5, 2022 2:37:53 PM

This won't be MAUI specific in any case, right? Like with that other issue linked, this stack is entirely Android and that would point to it being a net6-android issue (or at least something you need to change at a project level).

@Eilon
Copy link
Member Author

Eilon commented May 9, 2022


Issue moved from dotnet/maui#6859


From @Eilon on Thursday, May 5, 2022 5:17:18 PM

Should we move this to the xamarin-android repo?

@Eilon
Copy link
Member Author

Eilon commented May 9, 2022


Issue moved from dotnet/maui#6859


From @Redth on Thursday, May 5, 2022 8:19:42 PM

I'll let @jonpryor handle moving and closing as necessary. Unfortunately we can't move issues across orgs with GitHub, it has to be 'manually' moved.

@Eilon
Copy link
Member Author

Eilon commented May 9, 2022


Issue moved from dotnet/maui#6859


From @Eilon on Thursday, May 5, 2022 9:39:45 PM

I have magic tools that can do this (it just automates the manual steps using APIs).

@janseris
Copy link

janseris commented May 24, 2022

@Eilon Hi, please, is there any update on this or anyone assigned to solve this issue or anything I can do to help?
I tried MAUI GA today and the issue still persists - this happens for every DB call.

Repro project:
MauiApp1.zip

Note: a connection string needs to be provided into the DbContext (both in MauiApp1 project and DAL project).

Debug Android 8.0:

[System.err] java.lang.IllegalStateException: Handshake has already been started
[System.err] 	at com.android.org.conscrypt.OpenSSLEngineImpl.beginHandshakeInternal(OpenSSLEngineImpl.java:335)
[System.err] 	at com.android.org.conscrypt.OpenSSLEngineImpl.beginHandshake(OpenSSLEngineImpl.java:325)
[System.err] 	at mono.java.lang.RunnableImplementor.n_run(Native Method)
[System.err] 	at mono.java.lang.RunnableImplementor.run(RunnableImplementor.java:30)
[System.err] 	at android.os.Handler.handleCallback(Handler.java:789)
[System.err] 	at android.os.Handler.dispatchMessage(Handler.java:98)
[System.err] 	at android.os.Looper.loop(Looper.java:164)
[System.err] 	at android.app.ActivityThread.main(ActivityThread.java:6541)
[System.err] 	at java.lang.reflect.Method.invoke(Native Method)
[System.err] 	at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
[System.err] 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

image

Release Android 8.0:
image

@Eilon
Copy link
Member Author

Eilon commented May 26, 2022

@janseris sorry this is not an area I'm familiar with at all.

@jonathanpeppers - do you know who could look at this or what milestone it might get slotted into for investigation?

@jonathanpeppers
Copy link
Member

jonathanpeppers commented May 27, 2022

@janseris I am not getting the same error using the sample project above. Does this app talk directly to a database? I wouldn't recommend doing this in a mobile app -- security best practice would be to put a web service in between.

To look into this further, I think we need adb logcat output of the full exception. Depending on what is wrong, we might need someone from the Mono runtime team to look into this. Thanks!

@jonathanpeppers jonathanpeppers added the need-info Issues that need more information from the author. label May 27, 2022
@jonathanpeppers jonathanpeppers self-assigned this May 27, 2022
@jonathanpeppers jonathanpeppers added this to the Under Consideration milestone May 27, 2022
@jonathanpeppers jonathanpeppers added the Area: Mono Runtime Mono-related issues: BCL bugs, AOT issues, etc. label May 27, 2022
@jonathanpeppers
Copy link
Member

@steveisok there is a partial stack trace above, should Microsoft.Data.SqlClient work on Android?

@janseris
Copy link

janseris commented May 27, 2022

@janseris I am not getting the same error using the sample project above. Does this app talk directly to a database? I wouldn't recommend doing this in a mobile app -- security best practice would be to put a web service in between.

To look into this further, I think we need adb logcat output of the full exception. Depending on what is wrong, we might need someone from the Mono runtime team to look into this. Thanks!

Thanks. I get the error in every MAUI app talking to external sql server on Android 8.1 and lower for me. There is no specific code needed. Yes the situation is db call from Android to SQL Server.
Our use case is old apps with SQL Server Stored Procedures API on SQL Server with DB logins with access rights limited to these stored procedures. And also serverless mobile apps using EF Core on Android for simple tasks like items evidence.

The db communication works well on Android 9 and higher. BTW make sure there is a connection string to a valid SQL server to reproduce the issue. Otherwise invalid host name SqlException is received instead.
As for safety yes I know and another possible use case might be running an Android server (thanks to MAUI single project this server can be run on any platform) or a microservice running on Android which talks to a db.

I tried to capture the whole stack trace which is not my code. Is there any important part missing which I should add?

My SQL Server version is 2012. Do you think that might be the issue? But it communicates with any Windows PC without any issues.

I will try get output from adb logcat tomorrow.

@jonathanpeppers
Copy link
Member

BTW make sure there is a connection string to a valid SQL server to reproduce the issue.

Yes, since I do not have a SQL Server to interact with, I just ran the sample as-is.

@janseris
Copy link

janseris commented May 28, 2022

I read here netty/netty#4718 that the issue might be that different implementations of SSL communication is used in different version of Android. Some of them tolerate multiple handshakes started and the one here throws an exception in that situation.
They did basically a fix where if a handshake was initiated, another one cannot be initiated:

netty/netty@446f7fd
netty/netty#4764

I however don't know what to do about it.
Btw I can see that the TLS/SSL version switch in .csproj properties for Android had disappeared since last time (RC 2). But it seem to have influenced only HTTP calls (was probably some test code for HttpClient, right?). SQL Server uses TDS protocol on port 1433

image

To look into this further, I think we need adb logcat output of the full exception. Depending on what is wrong, we might need someone from the Mono runtime team to look into this. Thanks!

log.txt Android 8 emulator

Comment on the content of the log:

  • in the last execution of the app, I am repeatedly calling a test DB call which selects a dummy column from users
    It seems like the log doesn't contain much more than I posted in the exception stack trace.

The log is long because I don't know how to cut old info. When I run adb logcat -d > log.txt, log is always appended to the old content.
I used adb shell setprop debug.mono.log default,timing,assembly,mono_log_level=debug,mono_log_mask=all

And I think that the reason that specifying Encrypt=false in the connection string doesn't help is because it only turns on/off the encryption of the transported data.
However the issue occurs in the pre-login handshake which uses SSL to prevent plaintext transport of login credentials to the SQL Server even if no encryption for data is used.

@ghost
Copy link

ghost commented Jun 6, 2022

Hi @Eilon. Due to inactivity, we will be closing this issue. Please feel free to re-open this issue if the issue persists. For enhanced visibility, if over 7 days have passed, please open a new issue and link this issue there. Thank you.

@ghost ghost closed this as completed Jun 6, 2022
@janseris
Copy link

janseris commented Jun 6, 2022

@Eilon @jonathanpeppers I provided required info.

@jonathanpeppers jonathanpeppers removed the need-info Issues that need more information from the author. label Jun 6, 2022
@Eilon
Copy link
Member Author

Eilon commented Jun 6, 2022

@janseris sorry about that. I think the MsftBot got confused because in this bug I am the original opener (I copied the bug from the other repo), so even though you did reply, the bot saw that I didn't respond after a few days of the need-info label, so it thought I was ignoring it and closed the issue.

@janseris
Copy link

janseris commented Jun 21, 2022

Hi @jonathanpeppers, is there any news on this issue, please?
Is there anything I can do to help as well?
This issue has high priority for our company.
It is fatal because we are porting old apps to C# as is, with the legacy infrastructure and systems.
We are limited by the client's infrastructure - central database only, older outdoor phones.

(older Android phones used periodically for technical inspections of appliances and facilities in industry - engine rooms, health care - engine rooms etc. and construciton sites)

Developers in the repo I linked to - "netty" - did just a small and effective fix to solve this - they essentially put an if condition so that if handshake is already ongoing (in progress), do not start a new handshake.
In the internal Java code though.

Thank you.

@steveisok
Copy link
Member

@jonathanpeppers I feel like this issue might belong over in https://github.com/dotnet/SqlClient. At least to start.

@jonathanpeppers
Copy link
Member

Closing in favor of: dotnet/SqlClient#1656

I wish we could have just moved this issue around until we got it at the right place. Thanks!

@ghost ghost locked as resolved and limited conversation to collaborators Jul 22, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Area: Mono Runtime Mono-related issues: BCL bugs, AOT issues, etc.
Projects
None yet
Development

No branches or pull requests

4 participants