robinrodricks / FluentFTP.GnuTLS

Premiere .NET wrapper for GnuTLS along with integration into FluentFTP
GNU Lesser General Public License v2.1
4 stars 5 forks source link

Not working on Linux - [Update: now fixed] #40

Closed acorchia closed 1 year ago

acorchia commented 1 year ago

FluentFTP.GnuTLS is great but do not load when using .Net6 project under Linux:

FTPS Authentication failed, lib = FluentFTP.GnuTLS.GnuTlsStream : FluentFTP.GnuTLS.GnuTlsException: GnuTLS .dll load/call validation error ---> System.DllNotFoundException: Unable to load shared library 'libgnutls-30.dll' or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable: liblibgnutls-30.dll: cannot open shared object file: No such file or directory

Actually, on linux libgnutls-30 exist as /usr/lib64/libgnutls.so.30 Is there a chance to have a updated package that also support Linux ?

FanDjango commented 1 year ago

Actually, on linux libgnutls-30 exist as /usr/lib64/libgnutls.so.30 Is there a chance to have a updated package that also support Linux ?

Yes. core\gnutls.cs needs a complete duplicate with other names in the DllImport(...)', testing, different packaging etc. etc. Also, a build-chain for making the dll's from source (although under Linux the stock ones might work ok).

If you are prepared to compile/build yourself, it should be easiest for now.

FanDjango commented 1 year ago

Cross platform coding this is easier for newest releases but still a rocky topic. DllImport appends a .so under linux, appends a .dll under windows, but will not respect the difference between libgnutls30.dll and libgnutls.so.30, for example.

Dllmap is a possible solution, but only introduced in the latest .NET Cores.

So to be really functional at lower levels, it still needs crazy duplication.

I am still investigating this.

acorchia commented 1 year ago

Hi I have write a update to your source. I duplicate the module with import of. So and call windows or Linux api depending of the os detected at stattup It compile and still running on windows but I unfortunately didn't have time to test it on linux I can send you the source if you want

Regards Alain Corchia


From: FanDjango @.> Sent: Friday, April 28, 2023 10:45:56 PM To: robinrodricks/FluentFTP.GnuTLS @.> Cc: acorchia @.>; Author @.> Subject: Re: [robinrodricks/FluentFTP.GnuTLS] Not working on Linux (Issue #40)

Cross platform coding this is easier for newest releases but still a rocky topic. DllImport appends a .so under linux, appends a .dll under windows, but will not respect the difference between libgnutls30.dll and libgnutls.so.30, for example.

Dllmap is a possible solution, but only introduced in the latest .NET Cores.

So to be really functional at lower levels, it still needs crazy duplication.

I am still investigating this.

— Reply to this email directly, view it on GitHubhttps://github.com/robinrodricks/FluentFTP.GnuTLS/issues/40#issuecomment-1528074839, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AC6RTYH4TH5ALVLQHSYWUFLXDQUAJANCNFSM6AAAAAAXGTLKBA. You are receiving this because you authored the thread.Message ID: @.***>

FanDjango commented 1 year ago

I understand.

Even the detection of the OS (Windows, Linux etc.) using the recommended method is problematic:

To detect the current operating system, the current official recommendation is to use suchlike:

                 if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) {
                        Console.WriteLine("We're on Linux!");
                  }

                  if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) {
                        Console.WriteLine("We're on Windows!");
                  }

This needs:

using System.Runtime.InteropServices;

which in turn requires a reference to and distribution of

System.Runtime.InteropServices.RuntimeInformation.dll

Well, this works but introduces a dependancy on this .dll which then needs to be distributed. I hate that.

I have found some other (inofficial) ways to determine the OS we are running under. Is this then to be preferred?

I duplicate the module with import of

That was my approach also. If you have done it, you can send it or PR it, let's have a look.

I unfortunately didn't have time to test it on linux

I am working on that to have a test environment to do that, but the speed at which I can do that right now is not very high.

FanDjango commented 1 year ago

@acorchia

42 closed, superseded by #43 - thanks for this.

Now the linux part needs to be tested, I will be doing that in the coming week or so. Maybe some other users will also have a look see using the current master. Will be a release only after confirm it works under linux.

Perhaps you also can test it.

Please note: The "free" problem, if it does not work correctly: This will not cause an immediate failure / or / it will cause a access violation exception. We will see...

FanDjango commented 1 year ago

I've now got a test environment and a test program under linux.

Ok, using your code and some additional things, we are moving forward. Looks really good already. One detail: Under linux we need to be more lenient concerning the libgnutls version number (Debian Bullseye (11) provides 3.7.1, for example), so I needed to change that logic which checks the version number.

@acorchia Look:

Status:   FluentFTP 46.0.2.0
Status:   Connecting to IP #1= ***:21
Status:   Waiting for a response
Response: 220 ProFTPD Server (Debian) [::ffff:192.168.1.109] [738639.868d]
Status:   Detected FTP server: ProFTPD
Command:  AUTH TLS
Status:   Waiting for response to: AUTH TLS
Response: 234 AUTH TLS successful [1ms]
Status:   GnuTLS: 0   FluentFTP.GnuTLS 1.0.8.0(Unix/.NET 6.0) / GnuTLS 3.7.1
Status:   GnuTLS: 2   Internal: added 6 protocols, 29 ciphersuites, 19 sig algos and 10 groups into priority list
Status:   GnuTLS: 2   Internal: EXT[0x55cb2409ad70]: client generated SECP256R1 shared key
Error:    FTPS Authentication failed, lib = FluentFTP.GnuTLS.GnuTlsStream
Error:    Unable to load shared library 'libgnutls-30.dll' or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable: liblibgnutls-30.dll: cannot open shared object file: No such file or directory

So there is somewhere still a branch to the Windows side. I will debug tomorrow.

FanDjango commented 1 year ago

Ok, needed to fix the free issue, and there was a bug in GnuTlsAlpnSetProtocols(...) setting an incorrect length.

Command:  AUTH TLS
Status:   Waiting for response to: AUTH TLS
Response: 234 AUTH TLS successful [<1ms]
Status:   GnuTLS: 0   FluentFTP.GnuTLS 1.0.8.0(Unix/.NET 6.0) / GnuTLS 3.7.1
Status:   GnuTLS: 2   Internal: added 6 protocols, 29 ciphersuites, 19 sig algos and 10 groups into priority list
Status:   GnuTLS: 2   Internal: EXT[0x5590f838ad90]: client generated SECP256R1 shared key
Status:   FTPS authentication successful, lib = FluentFTP.GnuTLS.GnuTlsStream, cipher suite = (TLS1.3)-(ECDHE-SECP256R1)-(RSA-PSS-RSAE-SHA256)-(AES-256-GCM) [33ms]

So, FluentFTP.GnuTls now works under linux.

@acorchia You can try the current master, I have merged all the changes and after letting this cool down for some feedback, I will cut a new release.

FanDjango commented 1 year ago

Ok, I can finally close this - it is working for me under linux. In my case, Debian 11 Bullseye with GnuTLS :

FluentFTP.GnuTLS 1.0.8.0(Unix/.NET 6.0) / GnuTLS 3.7.1

Cutting a release soon (1.0.9.0).