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

Unexpected EOF when connecting to server from Ubuntu LTS 20.04 #336

Closed
jeffkirk1 opened this issue Apr 28, 2020 · 20 comments
Closed

Unexpected EOF when connecting to server from Ubuntu LTS 20.04 #336

jeffkirk1 opened this issue Apr 28, 2020 · 20 comments

Comments

@jeffkirk1
Copy link

jeffkirk1 commented Apr 28, 2020

I compiled both the current stable and nightly release (as of April 28, 2020) versions of FreeTDS successfully. I attempted to login to a Microsoft SQL Server with the following command line (real IP addresses and credentials replaced with variables) and got an error:

ubuntu_lts_20_04 $ tsql -H $SERVER_IP -p 2001 -U $USERNAME -P $PASSWORD -D $CLIENT_NAME
locale is "en_US.UTF-8"
locale charset is "UTF-8"
using default charset "UTF-8"
Setting $CLIENT_NAME as default database in login packet
Error 20017 (severity 9):
Unexpected EOF from the server
Error 20002 (severity 9):
Adaptive Server connection failed
Error 20002 (severity 9):
Adaptive Server connection failed
There was a problem connecting to the server

There is no routing issue to the host; I was able to see four packets replying from the SQL server to my Ubuntu LTS 20.04 machine. Perhaps significantly, three had zero-length payloads; the second of the four had a payload of 43 bytes. Hex dump of this packet wasn't revealing (presumably it was encrypted or binary in nature).

An Ubuntu LTS 18.04.3 server on the same network using the stable version of FreeTDS was able to connect without errors using the same credentials. Happy to provide whatever other details I can to resolve this issue.

Same result with freetds-1.1.33 and freetds-dev.1.1.62.

@freddy77
Copy link
Contributor

One issue can be the encryption. Linux tends to increase the security levels faster than Windows. Sometimes so fast than when they try to find a common ground they cannot.

Which SQL server version are you using? Which Windows version?

You could try with something like

TDSVER=7.0 tsql -H $SERVER_IP -p 2001 -U $USERNAME -P $PASSWORD -D $CLIENT_NAME

(it uses a very old TDS protocol version which does not have encryption, I won't recommend for production! Just to try if it connects)

@kafran
Copy link

kafran commented Apr 28, 2020

It is probably related to this issue: #299 (comment), probably related to newer version of openssl. Try the workaround found by @r313pp. I compiled it with GnuTLS and it also worked. @freddy77 do you know if there is any advise about using GnuTLS?

@jeffkirk1
Copy link
Author

@freddy77: Overriding the TDS version to 7.0 does work around the problem. Thank you!
@kafran: I will investigate compiling with GnuTLS and report back.

@jeffkirk1
Copy link
Author

The workaround by @r313pp might not work; the /etc/ssl/openssl.cnf file on Ubuntu 20.04 LTS doesn't define either MinProtocol or CipherString.

@jeffkirk1
Copy link
Author

I was able to connect to the upstream server using tsql compiled with gnutls. To install GnuTLS, I compiled libgmp from source and ran the following command to install the other prerequisites:

sudo apt install nettle-dev libtasn1-6-dev libunistring-dev libunbound-dev libp11-kit-dev

This is to an Ubuntu 20.04 LTS headless server install, with the ubuntu-desktop tasksel package added after the fact.

FYI, on Ubuntu 20.04 LTS, fourteen of the "make check" unit tests fail without GnuTLS and thirteen with.

@kafran
Copy link

kafran commented Apr 29, 2020

The workaround by @r313pp might not work; the /etc/ssl/openssl.cnf file on Ubuntu 20.04 LTS doesn't define either MinProtocol or CipherString.

I don't know about Ubuntu. I'm trying to compile into a Debian Buster Docker.

@freddy77: Overriding the TDS version to 7.0 does work around the problem. Thank you!

Apparently TDS 7.0 don't use encryption, that's why it works. I think this is not recommended for production.

@freddy77
Copy link
Contributor

No, TDS 7.0 is surely not recommended. You could try setting encryption to off (http://www.freetds.org/userguide/freetdsconf.htm). Not that usually only the login part is encrypted, if you are in a safe LAN it could be sensible. Not sure if is possible,despite global system settings to force OpenSSL to use some not so insecure ciphers (recently Linux configurations are pretty strict about it).

Should I keep this issue open? I think it would be nice to have in the FAQ, which I think don't get updated since years.

@mckaygerhard
Copy link

i followed the usage of GnuTLS cos openssl are a mess !

Apparently TDS 7.0 don't use encryption, that's why it works. I think this is not recommended for production.

@kafran quite funny ... any M$ are not recommended in general! 😄

Should I keep this issue open? I think it would be nice to have in the FAQ, which I think don't get updated since years.

@freddy77 added to faq and close the issue.. as i pointed M$ products are not so easy to "complain", maybe in future when openssl become less complicated and does not cause a mess on every upgrade, may we have to merge issues with #299 and use GnuTLS that seems worked!

@rgyu
Copy link

rgyu commented May 20, 2021

We experience the similar issue. FreeTDS 7.4 connecting to SQL Server encounters the error: Adaptive Server connection failed. We thought it might be related to the MaxTokenSize setting on server side, but seems not.

We downgrade TDS to 7.0 and now can connect to SQL Server. Later, We identified that network security has a change. They add a security policy, and the network packet was dropped/altered by the policy. Once they remove the policy, FreeTDS connecting to SQL Server is OK.

So if you experience the similar issue, you can also ask network security team whether they have any change.

@mckaygerhard
Copy link

.. We identified that network security has a change.
They add a security policy, and the network packet was dropped/altered by the policy.
Once they remove the policy, FreeTDS connecting to SQL Server is OK.
So if you experience the similar issue, you can also ask network security team whether they have any change.

can you documented exactly what kind of change for freetds project ? please @yurongga !

@fziglio
Copy link

fziglio commented May 20, 2021

I think the issue here is that new Debian based distros has pretty high standards about TLS. Mostly the minimum required by the system are higher than what Windows system (and so the server) can accept.

TDS 7.0 did NOT support TLS so maybe this is the reason but be advised you are using a pretty old protocol which could lead to minor data corruption.

@rgyu
Copy link

rgyu commented May 21, 2021

we use pymssql in our project running on CentOS. Below is our code:

pymssql.connect(server=dns, port=port, database=dbname, user=uid, password=pwd,
charset="UTF-8",timeout=timeout, login_timeout=connect_timeout)

which runs fine. Suddently, it continues to throws error: "Adaptive Server connection failed". We have another working client that can connect to sql server successfully. We compared the TDS sending packet for both failed and successful clients. and the TDS sending packet are exactly the same. at that time, we have no idea, and found this discussion thread. our workaround is to specify TDS version to 7.0 like below:

pymssql.connect(server=dns, port=port, database=dbname, user=uid, password=pwd,
charset="UTF-8",timeout=timeout, login_timeout=connect_timeout,
tds_version="7.0")

the final solution is to ask network security team to remove the security policy. looks like AC policy related, but I don't know the security policy detail.

.. We identified that network security has a change.
They add a security policy, and the network packet was dropped/altered by the policy.
Once they remove the policy, FreeTDS connecting to SQL Server is OK.
So if you experience the similar issue, you can also ask network security team whether they have any change.

can you documented exactly what kind of change for freetds project ? please @yurongga !

@komba
Copy link

komba commented Apr 27, 2022

FreeTSD 1.3.10, TDS 7.4 with GnuTLS worked well. Specifying 7.0 at the configure step won't work as it's insecure.

It's also possible to set encryption = off in freetds.conf

@kstarsinic
Copy link

I'm having a similar issue (only recently) on Mac OS. No matter how far I turn down the TDS version in freetds.conf, freetds sends a "prelogin" packet to the server on initial connection, which produces the premature EOF. I have to set "encryption = off" to stop the error. This is painful, because there's no way to turn off encryption without modifying freetds.conf, which doesn't play nicely with my application deployment (I can change TDS version with an environment variable, which suits me nicely).

freetds: 1.3.18_1 (via homebrew)
Mac OS: Ventura 13.4.1
MS SQL Server: Microsoft SQL Server 2014 (SP3-GDR) (KB5021037) - 12.0.6174.8 (X64)

I'm more than happy to provide a more detailed bug report on request. Having just identified the bug and workaround, I'm scrambling to test and push out a new build for my app.

@freddy77
Copy link
Contributor

freddy77 commented Jul 4, 2023

Microsoft introduced encryption and prelogin with SQL Server 2000, you should configure and use FreeTDS with encryption, not trying to use a protocol version more than 20 years old. What says tsql -C (see https://www.freetds.org/userguide/ConfirmInstall.html#tsql)? To use less secure options with OpenSSL (if needed) you could see https://www.openssl.org/docs/man3.1/man5/config.html.

@kstarsinic
Copy link

I'm offering a patch, hoping for some feedback on what the proper fix is (or, of course, on how I'm misstating the problem).

Thanks for the advice, @freddy77. I'm not seeking to use an older protocol version--I was only trying that to see if it would circumvent my pre-login issue.1 I'm connecting to SQL Server 2014, which (for my current deployment, at least) returns a well-formed pre-login response2. I'm not yet sure which side is closing the connection.

I am saying that the freetds bug is any or all of:

  • freetds is failing to interpret the pre-login response appropriately and continue the session, or
  • freetds is not providing informative diagnostics on the disconnection, or
  • freetds is not (optionally) attempting to reconnect without the pre-login phase

It's certainly the case that users should be upgrading insecure deployments. However, in my current example, I'm using a reasonably modern, encryption-capable database, and my client is failing with no useful diagnostics only after a freetds upgrade. None of the relevant software is giving me the information I require to know what's wrong or how to fix it.

$ tsql -C
Compile-time settings (established with the "configure" script)
                            Version: freetds v1.3.18
             freetds.conf directory: /usr/local/etc
     MS db-lib source compatibility: no
        Sybase binary compatibility: yes
                      Thread safety: yes
                      iconv library: yes
                        TDS version: 7.3
                              iODBC: no
                           unixodbc: yes
              SSPI "trusted" logins: no
                           Kerberos: yes
                            OpenSSL: yes
                             GnuTLS: no
                               MARS: yes

1 I've since discovered that, if I back off all the way to TDS 7.0 (as per #336 (comment), thanks @jeffkirk1), the client will skip the pre-login, which is a better workaround for me than deploying a custom freetds.conf. This issue only triggers with a diagnostic client, not with my customer-facing app (which uses jtds, not freetds).

2 Pre-login response packet:

11:20:24.453466 11728 (packet.c:410):Received packet
0000 04 01 00 25 00 00 01 00-00 00 15 00 06 01 00 1b |...%.... ........|
0010 00 01 02 00 1c 00 01 03-00 1d 00 00 ff 0c 00 18 |........ ....ÿ...|
0020 1e 00 00 00 00         -                        |.....|

Decoded:

Packet Header
04                  Type    Pre-Login Response
01                  Status  End of Message
00 25               Length  37
00 00               SPID
01                  PacketID
00                  Window

Packet Data from Microsoft SQL Server 2014 (SP3-GDR) (KB5021037) - 12.0.6174.8 (X64)
00 00 15 00 06      VERSION     21  6   US_BUILD 12, VER_SQL_MINOR 6174, VER_SQL_MAJOR 0
01 00 1b 00 01      ENCRYPTION  27  1   00
02 00 1c 00 01      INSTOPT     28  1   00
03 00 1d 00 00      THREADID    29  0
ff                  TERMINATOR
0c 00 18 1e 00 00   VERSION token data
00                  ENCRYPTION token data
00                  INSTOPT token data

@freddy77
Copy link
Contributor

freddy77 commented Jul 6, 2023

I'm offering a patch, hoping for some feedback on what the proper fix is (or, of course, on how I'm misstating the problem).

Thanks for the advice, @freddy77. I'm not seeking to use an older protocol version--I was only trying that to see if it would circumvent my pre-login issue.1 I'm connecting to SQL Server 2014, which (for my current deployment, at least) returns a well-formed pre-login response2. I'm not yet sure which side is closing the connection.

I would bet the server. If you use a network capture software you can see clearly which end post the first packet with FIN flag.

I am saying that the freetds bug is any or all of:

* freetds is failing to interpret the pre-login response appropriately and continue the session, or

Tried with the data you sent, no, no problem decoding

* freetds is not providing informative diagnostics on the disconnection, or

I would bet server is silently closing the connection due to failure in TLS handshaking. Not sending detailed errors is common with many server to avoid giving informations to attackers.

* freetds is not (optionally) attempting to reconnect without the pre-login phase

What's the point to connect again? If the error is due to configuration you need to update the configuration.

It's certainly the case that users should be upgrading insecure deployments. However, in my current example, I'm using a reasonably modern, encryption-capable database, and my client is failing with no useful diagnostics only after a freetds upgrade. None of the relevant software is giving me the information I require to know what's wrong or how to fix it.

Which version of Windows (server) are you using?

$ tsql -C
Compile-time settings (established with the "configure" script)
                            Version: freetds v1.3.18
             freetds.conf directory: /usr/local/etc
     MS db-lib source compatibility: no
        Sybase binary compatibility: yes
                      Thread safety: yes
                      iconv library: yes
                        TDS version: 7.3

it's recommended to leave to auto, unless you are using Sybase.

                          iODBC: no
                       unixodbc: yes
          SSPI "trusted" logins: no
                       Kerberos: yes
                        OpenSSL: yes

nice!

                         GnuTLS: no
                           MARS: yes

Try something like

TDSDUMP=stderr tsql -H server -p 1433

Getting something like

log.c:187:Starting log file for FreeTDS 1.4.dev.20230706
	on 2023-07-06 09:27:46 with debug flags 0x4fff.
locale is "en_GB.UTF-8"
locale charset is "UTF-8"
using default charset "UTF-8"
iconv.c:362:tds_iconv_open(0x2112880, UTF-8)
iconv.c:198:local name for ISO-8859-1 is ISO-8859-1
iconv.c:198:local name for UTF-8 is UTF-8
iconv.c:198:local name for UCS-2LE is UCS-2LE
iconv.c:198:local name for UCS-2BE is UCS-2BE
iconv.c:384:setting up conversions for client charset "UTF-8"
iconv.c:386:preparing iconv for "UTF-8" <-> "UCS-2LE" conversion
iconv.c:425:tds_iconv_open: done
net.c:391:Connecting with protocol version 7.4
net.c:318:Connecting to 127.0.0.1 port 12345
net.c:340:tds_setup_socket: connect(2) returned "Operation now in progress"
net.c:528:tds_open_socket() succeeded
packet.c:852:Sending packet
0000 12 01 00 3a 00 00 00 00-00 00 1a 00 06 01 00 20 |...:.... ....... |
0010 00 01 02 00 21 00 0c 03-00 2d 00 04 04 00 31 00 |....!... .-....1.|
0020 01 ff 09 00 00 00 00 00-00 4d 53 53 51 4c 53 65 |........ .MSSQLSe|
0030 72 76 65 72 00 4a 84 00-00 00                   |rver.J.. ..|

packet.c:410:Received packet
0000 04 01 00 25 00 00 01 00-00 00 15 00 06 01 00 1b |...%.... ........|
0010 00 01 02 00 1c 00 01 03-00 1d 00 00 ff 0c 00 18 |........ ........|
0020 1e 00 00 00 00         -                        |.....|

login.c:1387:detected crypt flag 0
tls.c:1023:setting default openssl cipher to:HIGH:!SSLv2:!aNULL:-DH
tls.c:147:in tds_push_func_login
tls.c:117:in tds_pull_func_login
packet.c:852:Sending packet
0000 12 01 01 45 00 00 00 00-16 03 01 01 38 01 00 01 |...E.... ....8...|
0010 34 03 03 a5 80 6c 54 2d-12 b0 9c 21 40 06 f4 85 |4....lT- ...!@...|
0020 00 c8 3d db ce 0c a9 41-e5 c0 34 fd 28 e7 d0 e8 |..=....A ..4.(...|
0030 e6 2d c2 20 02 75 61 61-ae 92 b7 29 56 19 92 a2 |.-. .uaa ...)V...|
0040 29 57 b9 21 fb d7 3f 86-53 5d b3 03 d1 7f 4d ca |)W.!..?. S]....M.|
0050 2a a8 ac e1 00 5e 13 02-13 03 13 01 13 04 c0 2c |*....^.. .......,|
0060 c0 30 cc a9 cc a8 c0 af-c0 ad c0 5d c0 61 c0 2b |.0...... ...].a.+|
0070 c0 2f c0 ae c0 ac c0 5c-c0 60 c0 24 c0 28 c0 73 |./.....\ .`.$.(.s|
0080 c0 77 c0 23 c0 27 c0 72-c0 76 c0 0a c0 14 c0 09 |.w.#.'.r .v......|
0090 c0 13 00 9d c0 a1 c0 9d-c0 51 00 9c c0 a0 c0 9c |........ .Q......|

note that crypt flag is detected and program start initializing TLS (I was trying to reproduce parsing your prelogin).

@kstarsinic
Copy link

Confirmed that the server is closing the connection.

Server OS: Windows Server 2008 R2 Standard
freetds.conf says "tds version = auto", and I've confirmed that freetds accepts an explicit version number I specify there; I don't know why tsql -C reports 7.3.

% TSDUMP=stderr sql -H MYHOSTNAME -p MYPORT
locale is "C/en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/en_US.UTF-8"
locale charset is "UTF-8"
using default charset "UTF-8"
Error 20017 (severity 9):
	Unexpected EOF from the server
Error 20002 (severity 9):
	Adaptive Server connection failed
Error 20002 (severity 9):
	Adaptive Server connection failed
There was a problem connecting to the server

Contents of /tmp/freetds.log:

17:53:56.960018 56905 (log.c:187):Starting log file for FreeTDS 1.3.18
  on 2023-07-06 17:53:56 with debug flags 0xffff.
17:53:56.960129 56905 (iconv.c:367):tds_iconv_open(0x7fae7d104400, UTF-8)
17:53:56.960144 56905 (iconv.c:198):local name for ISO-8859-1 is ISO-8859-1
17:53:56.960149 56905 (iconv.c:198):local name for UTF-8 is UTF-8
17:53:56.960154 56905 (iconv.c:198):local name for UCS-2LE is UCS-2LE
17:53:56.960159 56905 (iconv.c:198):local name for UCS-2BE is UCS-2BE
17:53:56.960167 56905 (iconv.c:389):setting up conversions for client charset "UTF-8"
17:53:56.960172 56905 (iconv.c:391):preparing iconv for "UTF-8" <-> "UCS-2LE" conversion
17:53:56.960177 56905 (iconv.c:430):tds_iconv_open: done
17:53:56.960184 56905 (net.c:391):Connecting with protocol version 7.4
17:53:56.960276 56905 (net.c:318):Connecting to 98.115.43.162 port 8081
17:53:56.960517 56905 (net.c:340):tds_setup_socket: connect(2) returned "Operation now in progress"
17:53:56.975431 56905 (net.c:528):tds_open_socket() succeeded
17:53:56.975524 56905 (packet.c:852):Sending packet
0000 12 01 00 3a 00 00 00 00-00 00 1a 00 06 01 00 20 |...:.... ....... |
0010 00 01 02 00 21 00 0c 03-00 2d 00 04 04 00 31 00 |....!... .-....1.|
0020 01 ff 09 00 00 00 00 00-00 4d 53 53 51 4c 53 65 |.ÿ...... .MSSQLSe|
0030 72 76 65 72 00 49 de 00-00 00                   |rver.IÞ. ..|

17:53:56.996195 56905 (packet.c:410):Received packet
0000 04 01 00 2b 00 00 01 00-00 00 1a 00 06 01 00 20 |...+.... ....... |
0010 00 01 02 00 21 00 01 03-00 22 00 00 04 00 22 00 |....!... ."....".|
0020 01 ff 0c 00 18 1e 00 00-00 00 00                |.ÿ...... ...|

17:53:56.996243 56905 (login.c:1343):detected crypt flag 0
17:53:56.999043 56905 (tls.c:1023):setting default openssl cipher to:HIGH:!SSLv2:!aNULL:-DH
17:53:56.999240 56905 (tls.c:147):in tds_push_func_login
17:53:56.999252 56905 (tls.c:117):in tds_pull_func_login
17:53:56.999264 56905 (packet.c:852):Sending packet
0000 12 01 01 4b 00 00 00 00-16 03 01 01 3e 01 00 01 |...K.... ....>...|
0010 3a 03 03 19 37 33 15 2d-6d 1c 8b 2a 4a 56 c3 18 |:...73.- m..*JVÃ.|
0020 19 0e 67 dd a9 a1 2f 74-66 d6 d1 a3 ac 38 95 2d |..gÝ©¡/t fÖÑ£¬8.-|
0030 ec 33 0a 20 ef 94 0b 47-0b 9a 0a 28 40 90 15 60 |ì3. ï..G ...(@..`|
0040 db 83 89 fa ce 51 63 fe-67 56 ce c5 ea a1 b4 dc |Û..úÎQcþ gVÎÅê¡´Ü|
0050 29 4e c0 0c 00 5c 13 02-13 03 13 01 c0 2c c0 30 |)NÀ..\.. ....À,À0|
0060 cc a9 cc a8 c0 af c0 ad-c0 5d c0 61 c0 2b c0 2f |̨̩À¯À  À]ÀaÀ+À/|
0070 c0 ae c0 ac c0 5c c0 60-c0 24 c0 28 c0 73 c0 77 |À®À¬À\À` À$À(ÀsÀw|
0080 c0 23 c0 27 c0 72 c0 76-c0 0a c0 14 c0 09 c0 13 |À#À'ÀrÀv À.À.À.À.|
0090 00 9d c0 a1 c0 9d c0 51-00 9c c0 a0 c0 9c c0 50 |..À¡À.ÀQ ..À À.ÀP|
00a0 00 3d 00 c0 00 3c 00 ba-00 35 00 84 00 2f 00 41 |.=.À.<.º .5.../.A|
00b0 00 ff 01 00 00 95 00 0b-00 04 03 00 01 02 00 0a |.ÿ...... ........|
00c0 00 16 00 14 00 1d 00 17-00 1e 00 19 00 18 01 00 |........ ........|
00d0 01 01 01 02 01 03 01 04-00 23 00 00 00 16 00 00 |........ .#......|
00e0 00 17 00 00 00 0d 00 2a-00 28 04 03 05 03 06 03 |.......* .(......|
00f0 08 07 08 08 08 09 08 0a-08 0b 08 04 08 05 08 06 |........ ........|
0100 04 01 05 01 06 01 03 03-03 01 03 02 04 02 05 02 |........ ........|
0110 06 02 00 2b 00 05 04 03-04 03 03 00 2d 00 02 01 |...+.... ....-...|
0120 01 00 33 00 26 00 24 00-1d 00 20 d7 16 84 eb 28 |..3.&.$. .. ×..ë(|
0130 56 aa 31 05 12 8f 22 87-4c 4b c4 11 38 fa 82 a5 |Vª1...". LKÄ.8ú.¥|
0140 09 3b 00 7a 84 c2 c5 d3-02 5d 24                |.;.z.ÂÅÓ .]$|

17:53:57.026387 56905 (util.c:179):Changed query state from IDLE to DEAD
17:53:57.026423 56905 (util.c:333):tdserror(0x7ff7b7c61440, 0x7fae7d104750, 20017, 0)
17:53:57.026435 56905 (util.c:363):tdserror: client library returned TDS_INT_CANCEL(2)
17:53:57.026442 56905 (util.c:386):tdserror: returning TDS_INT_CANCEL(2)
17:53:57.026450 56905 (packet.c:539):Read attempt when state is TDS_DEAD
17:53:57.026462 56905 (tls.c:1039):handshake failed with -1 12 5
17:53:57.026512 56905 (tls.c:1083):handshake failed
17:53:57.026522 56905 (login.c:600):login packet rejected
17:53:57.026529 56905 (util.c:333):tdserror(0x7ff7b7c61440, 0x7fae7d104750, 20002, 0)
17:53:57.026553 56905 (util.c:363):tdserror: client library returned TDS_INT_CANCEL(2)
17:53:57.026559 56905 (util.c:386):tdserror: returning TDS_INT_CANCEL(2)
17:53:57.026577 56905 (util.c:333):tdserror(0x600003594060, 0x7fae7d104750, 20002, 0)
17:53:57.026586 56905 (util.c:363):tdserror: client library returned TDS_INT_CANCEL(2)
17:53:57.026592 56905 (util.c:386):tdserror: returning TDS_INT_CANCEL(2)
17:53:57.026598 56905 (mem.c:656):tds_free_all_results()

So to update, I am asserting that:

freetds is not providing informative diagnostics on the disconnection. For example, logging that the server closed the connection after returning a well-formed pre-login response would tell me that I probably shouldn't start my investigation with a call to network ops.

freetds is not (optionally) attempting to reconnect without the pre-login phase. By this, I mean that it would be nice if there were a (perhaps configurable) way to get freetds to try again without sending the pre-login message. I understand that you're not enthused by this, @freddy77, but if I know what I'm doing and I've been living without connection encryption all this time (in my case, in an environment in which encrypted connections would provide no additional security), I don't see it as a net positive that I I have no encryption and I don't get to use bigint, varchar(max), varbinary(max), or MARS.

@freddy77
Copy link
Contributor

freddy77 commented Jul 7, 2023

Confirmed that the server is closing the connection.

Server OS: Windows Server 2008 R2 Standard freetds.conf says "tds version = auto", and I've confirmed that freetds accepts an explicit version number I specify there; I don't know why tsql -C reports 7.3.

Microsoft ended support for such system 3 years ago. tsql -C reports the compiled in version. Possibly --with-tdsver=7.3 was passed during package configuration.

% TSDUMP=stderr sql -H MYHOSTNAME -p MYPORT
locale is "C/en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/en_US.UTF-8"
locale charset is "UTF-8"
using default charset "UTF-8"
Error 20017 (severity 9):
	Unexpected EOF from the server
Error 20002 (severity 9):
	Adaptive Server connection failed
Error 20002 (severity 9):
	Adaptive Server connection failed
There was a problem connecting to the server

Contents of /tmp/freetds.log:

17:53:56.960018 56905 (log.c:187):Starting log file for FreeTDS 1.3.18
  on 2023-07-06 17:53:56 with debug flags 0xffff.
17:53:56.960129 56905 (iconv.c:367):tds_iconv_open(0x7fae7d104400, UTF-8)
17:53:56.960144 56905 (iconv.c:198):local name for ISO-8859-1 is ISO-8859-1
17:53:56.960149 56905 (iconv.c:198):local name for UTF-8 is UTF-8
17:53:56.960154 56905 (iconv.c:198):local name for UCS-2LE is UCS-2LE
17:53:56.960159 56905 (iconv.c:198):local name for UCS-2BE is UCS-2BE
17:53:56.960167 56905 (iconv.c:389):setting up conversions for client charset "UTF-8"
17:53:56.960172 56905 (iconv.c:391):preparing iconv for "UTF-8" <-> "UCS-2LE" conversion
17:53:56.960177 56905 (iconv.c:430):tds_iconv_open: done
17:53:56.960184 56905 (net.c:391):Connecting with protocol version 7.4
17:53:56.960276 56905 (net.c:318):Connecting to 98.115.43.162 port 8081
17:53:56.960517 56905 (net.c:340):tds_setup_socket: connect(2) returned "Operation now in progress"
17:53:56.975431 56905 (net.c:528):tds_open_socket() succeeded
17:53:56.975524 56905 (packet.c:852):Sending packet
0000 12 01 00 3a 00 00 00 00-00 00 1a 00 06 01 00 20 |...:.... ....... |
0010 00 01 02 00 21 00 0c 03-00 2d 00 04 04 00 31 00 |....!... .-....1.|
0020 01 ff 09 00 00 00 00 00-00 4d 53 53 51 4c 53 65 |.ÿ...... .MSSQLSe|
0030 72 76 65 72 00 49 de 00-00 00                   |rver.IÞ. ..|

17:53:56.996195 56905 (packet.c:410):Received packet
0000 04 01 00 2b 00 00 01 00-00 00 1a 00 06 01 00 20 |...+.... ....... |
0010 00 01 02 00 21 00 01 03-00 22 00 00 04 00 22 00 |....!... ."....".|
0020 01 ff 0c 00 18 1e 00 00-00 00 00                |.ÿ...... ...|

17:53:56.996243 56905 (login.c:1343):detected crypt flag 0
17:53:56.999043 56905 (tls.c:1023):setting default openssl cipher to:HIGH:!SSLv2:!aNULL:-DH
17:53:56.999240 56905 (tls.c:147):in tds_push_func_login
17:53:56.999252 56905 (tls.c:117):in tds_pull_func_login
17:53:56.999264 56905 (packet.c:852):Sending packet
0000 12 01 01 4b 00 00 00 00-16 03 01 01 3e 01 00 01 |...K.... ....>...|
0010 3a 03 03 19 37 33 15 2d-6d 1c 8b 2a 4a 56 c3 18 |:...73.- m..*JVÃ.|
0020 19 0e 67 dd a9 a1 2f 74-66 d6 d1 a3 ac 38 95 2d |..gÝ©¡/t fÖÑ£¬8.-|
0030 ec 33 0a 20 ef 94 0b 47-0b 9a 0a 28 40 90 15 60 |ì3. ï..G ...(@..`|
0040 db 83 89 fa ce 51 63 fe-67 56 ce c5 ea a1 b4 dc |Û..úÎQcþ gVÎÅê¡´Ü|
0050 29 4e c0 0c 00 5c 13 02-13 03 13 01 c0 2c c0 30 |)NÀ..\.. ....À,À0|
0060 cc a9 cc a8 c0 af c0 ad-c0 5d c0 61 c0 2b c0 2f |̨̩À¯À  À]ÀaÀ+À/|
0070 c0 ae c0 ac c0 5c c0 60-c0 24 c0 28 c0 73 c0 77 |À®À¬À\À` À$À(ÀsÀw|
0080 c0 23 c0 27 c0 72 c0 76-c0 0a c0 14 c0 09 c0 13 |À#À'ÀrÀv À.À.À.À.|
0090 00 9d c0 a1 c0 9d c0 51-00 9c c0 a0 c0 9c c0 50 |..À¡À.ÀQ ..À À.ÀP|
00a0 00 3d 00 c0 00 3c 00 ba-00 35 00 84 00 2f 00 41 |.=.À.<.º .5.../.A|
00b0 00 ff 01 00 00 95 00 0b-00 04 03 00 01 02 00 0a |.ÿ...... ........|
00c0 00 16 00 14 00 1d 00 17-00 1e 00 19 00 18 01 00 |........ ........|
00d0 01 01 01 02 01 03 01 04-00 23 00 00 00 16 00 00 |........ .#......|
00e0 00 17 00 00 00 0d 00 2a-00 28 04 03 05 03 06 03 |.......* .(......|
00f0 08 07 08 08 08 09 08 0a-08 0b 08 04 08 05 08 06 |........ ........|
0100 04 01 05 01 06 01 03 03-03 01 03 02 04 02 05 02 |........ ........|
0110 06 02 00 2b 00 05 04 03-04 03 03 00 2d 00 02 01 |...+.... ....-...|
0120 01 00 33 00 26 00 24 00-1d 00 20 d7 16 84 eb 28 |..3.&.$. .. ×..ë(|
0130 56 aa 31 05 12 8f 22 87-4c 4b c4 11 38 fa 82 a5 |Vª1...". LKÄ.8ú.¥|
0140 09 3b 00 7a 84 c2 c5 d3-02 5d 24                |.;.z.ÂÅÓ .]$|

17:53:57.026387 56905 (util.c:179):Changed query state from IDLE to DEAD
17:53:57.026423 56905 (util.c:333):tdserror(0x7ff7b7c61440, 0x7fae7d104750, 20017, 0)
17:53:57.026435 56905 (util.c:363):tdserror: client library returned TDS_INT_CANCEL(2)
17:53:57.026442 56905 (util.c:386):tdserror: returning TDS_INT_CANCEL(2)
17:53:57.026450 56905 (packet.c:539):Read attempt when state is TDS_DEAD
17:53:57.026462 56905 (tls.c:1039):handshake failed with -1 12 5
17:53:57.026512 56905 (tls.c:1083):handshake failed
17:53:57.026522 56905 (login.c:600):login packet rejected
17:53:57.026529 56905 (util.c:333):tdserror(0x7ff7b7c61440, 0x7fae7d104750, 20002, 0)
17:53:57.026553 56905 (util.c:363):tdserror: client library returned TDS_INT_CANCEL(2)
17:53:57.026559 56905 (util.c:386):tdserror: returning TDS_INT_CANCEL(2)
17:53:57.026577 56905 (util.c:333):tdserror(0x600003594060, 0x7fae7d104750, 20002, 0)
17:53:57.026586 56905 (util.c:363):tdserror: client library returned TDS_INT_CANCEL(2)
17:53:57.026592 56905 (util.c:386):tdserror: returning TDS_INT_CANCEL(2)
17:53:57.026598 56905 (mem.c:656):tds_free_all_results()

So to update, I am asserting that:

freetds is not providing informative diagnostics on the disconnection. For example, logging that the server closed the connection after returning a well-formed pre-login response would tell me that I probably shouldn't start my investigation with a call to network ops.

The log was enough to tell you that. I don't see much a mistake in the general "error connecting" and the more detail are returned in the logs. On the log is also clear that the prelogin phase was successful and the client sent the initial TLS but the server closed the connection. This is probably due to the server not accepting the two restricted (because more secure) client settings. This confirm that you need to relax your client security configuration in order to connect.

freetds is not (optionally) attempting to reconnect without the pre-login phase. By this, I mean that it would be nice if there were a (perhaps configurable) way to get freetds to try again without sending the pre-login message. I understand that you're not enthused by this, @freddy77, but if I know what I'm doing and I've been living without connection encryption all this time (in my case, in an environment in which encrypted connections would provide no additional security), I don't see it as a net positive that I I have no encryption and I don't get to use bigint, varchar(max), varbinary(max), or MARS.

No, that is insecure. Recently Microsoft clients also check the server certificate so in some way is even more strict. Note that you can still attempt to use a former protocol but this is intentionally not make easy so you need to use freetds.conf. There's an environment to override freetds.conf location if needed. Using a protocol version so old lead to loose different feature and can potentially corrupt character values due to wrong encoding.

I understand your environment is closed so this prevents attacks that need encryption however I still recommend to lower the client security setting and use proper TDS protocol. See for instance https://stackoverflow.com/questions/57265913/error-tcp-provider-error-code-0x2746-during-the-sql-setup-in-linux-through-te (as you can see same issue but with Microsoft client).

@mckaygerhard
Copy link

@freddy77 you closed but you can paste commit referes so can helps mantainers work of distros?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants