[CONC-418] Use FormatMessage to get error string for unknown Schannel error codes Created: 2019-06-04  Updated: 2019-11-15  Resolved: 2019-09-21

Status: Closed
Project: MariaDB Connector/C
Component/s: None
Affects Version/s: 3.0.8, 3.1.0
Fix Version/s: 3.1.5

Type: Task Priority: Major
Reporter: Geoff Montee (Inactive) Assignee: Georg Richter
Resolution: Fixed Votes: 1
Labels: None

Issue Links:
Problem/Incident
causes CONC-446 For Schannel errors, provide the hex ... Closed
Relates
relates to CONC-391 Unknown SSL error - MariaDB Closed
relates to CONC-417 Windows clients using Schannel often ... Closed
relates to MDEV-13492 main.ssl_connect failed with 2026: U... Closed
relates to MDEV-13726 main.ssl_timeout, main.ssl_7937 fai... Closed

 Description   

If MariaDB Connector/C encounters an unknown Schannel error, then it currently prints a message like this:

Unknown SSL error (0x80090308)

It does this here:

https://github.com/MariaDB/mariadb-connector-c/blob/v3.1.0/libmariadb/secure/ma_schannel.c#L80

This is not very user friendly. It would probably be better if it could print the textual error message instead.

The windows API has the FormatMessage function that can be used to get the textual error message from the error code.

https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-formatmessage

For an example, see this:

https://stackoverflow.com/questions/1387064/how-to-get-the-error-message-from-the-error-code-returned-by-getlasterror



 Comments   
Comment by Vladislav Vaintroub [ 2019-06-04 ]

I think it is good that it outputs a code in hex. If it outputs a Japanese message, on localized version of Windows, it would be much harder to make it actionable. 0x80090308 is about as user-friendly as "invalid token" to the end user, the end user cannot make anything out of the message. But 0x80090308 can gbe easily googled.
A programmer friendliest messages would probably contain hexadecimal code, name of the constant (e.g SEC_E_INVALID_TOKEN), and English text, and location (which function causes the error). The most friendly code could dump content of local variables, and cherry on top is callstack leading to the error.

0x80090308 SEC_E_INVALID_TOKEN - The function encountered an invalid token ,in AcquireSecurityContext()

More often than not, when client gets this message, it might mean that server sent an error packet "08S1 Bad handshake", while client is trying to parse this as part TLS handshake (ServerHello, or anything like that)

Comment by Geoff Montee (Inactive) [ 2019-06-05 ]

Hi wlad,

A programmer friendliest messages would probably contain hexadecimal code, name of the constant (e.g SEC_E_INVALID_TOKEN), and English text, and location (which function causes the error). The most friendly code could dump content of local variables, and cherry on top is callstack leading to the error.

0x80090308 SEC_E_INVALID_TOKEN - The function encountered an invalid token ,in AcquireSecurityContext()

I agree with all of that.

If we want to ensure that we get English error messages even on localized versions of Windows, it actually looks like the FormatMessage function accepts a dwLanguageId parameter that can be used to choose the desired language.

dwLanguageId

The language identifier for the requested message. This parameter is ignored if dwFlags includes FORMAT_MESSAGE_FROM_STRING.

If you pass a specific LANGID in this parameter, FormatMessage will return a message for that LANGID only. If the function cannot find a message for that LANGID, it sets Last-Error to ERROR_RESOURCE_LANG_NOT_FOUND. If you pass in zero, FormatMessage looks for a message for LANGIDs in the following order:

1.) Language neutral
2.) Thread LANGID, based on the thread's locale value
3.) User default LANGID, based on the user's default locale value
4.) System default LANGID, based on the system default locale value
5.) US English

https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-formatmessage

It looks like the LANGID of English is LANG_ENGLISH (0x09). It looks like the LANGID of US English specifically is SUBLANG_ENGLISH_US (0x0409).

https://docs.microsoft.com/en-us/windows/desktop/Intl/language-identifiers

https://docs.microsoft.com/en-us/windows/desktop/Intl/language-identifier-constants-and-strings

If we did also want to get a callstack, then it looks like we may be able to use the CaptureStackBackTrace function.

https://docs.microsoft.com/en-us/windows/desktop/debug/capturestackbacktrace

Comment by Vladislav Vaintroub [ 2019-06-05 ]

I remember to have struggled to produce English system messages, on localized Windows, even with passing 0x09/0x0409. I think English MUI needs to be installed for that to succeed. Hardcoded on the other hand, is guaranteed to be English , but yes there should be a fallback.

Comment by Georg Richter [ 2019-09-21 ]

rev. 9ba8e32f6d0fe449114d8eb369cf29303257b460

Comment by Geoff Montee (Inactive) [ 2019-11-15 ]

See also: CONC-446.

Generated at Thu Feb 08 03:05:11 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.