About FTP Auth TLS

Hello,

Xojo newbie in here, i am having problems adding FTP Explicit Secure/TLS/SSL (AUTH TLS) support into https://github.com/charonn0/RB-FTP project FTP Server.

The project used a ServerSocket which has AddSocket event handler as below

Dim client As New FTP.Server
client.Banner = "Welcome to BSFTPd!"
client.AllowWrite = True
client.TimeOutPeriod = val(TimeOut.Text)

FTP.TimeOut = val(TimeOut.Text)
client.NetworkInterface = Me.NetworkInterface
AddHandler client.FTPLog, WeakAddressOf LogHandler
AddHandler client.Connected, WeakAddressOf enableFTPS 'Custom
AddHandler client.UserLogon, WeakAddressOf UserLogonHandler
Return client

enableFTPS method :

Sender.ConnectionType = SSLSocket.TLSv12
Dim certificate as FolderItem
certificate=GetFolderItem( "C:\\Users\ameless\\Documents\\server.key" )

If certificate <> Nil then
  Sender.CertificateFile=certificate
  Sender.CertificatePassword = ""
end if
If Sender.IsAuthTLS = True Then
  Sender.Secure = True
ElseIf Sender.IsAuthTLS = False Then
  Sender.Secure = False
End If

And Listening button Action event handler :

If FTPServer.IsListening Then
  FTPServer.StopListening
  Me.Caption = "Listen"
Else
  Dim n As NetworkInterface
  If nic.ListIndex <> -1 Then
    n = nic.RowTag(nic.ListIndex)
  Else
    n = System.GetNetworkInterface(0)
  End If
  FTPServer.NetworkInterface = n
  FTPServer.Port = Val(port.Text)
  FTPServer.Listen()
  Me.Caption = "Listening..."
End If

And a Do_Verb_AUTH method to handle “AUTH TLS” and “AUTH SSL”

If Argument = "TLS" or Argument.Trim = "" Then
  
  Dim rand As New Random
  Dim port As Integer = Rand.InRange(1024, 65534)
  DoResponse(234, Banner)
  Me.IsAuthTLS = True
  
End If

The question is the shared property which defined on FTP.Connection class, doesn’t get updated thorough the whole program session as true after the Do_Verb_AUTH being called, also when IsAuthTLS boolean check being disabled on enableFTPS method, i am getting “Socket error 0: Socket not connected.” from the RB-FTP server log, and hang from flashfxp ftp client.

Why the RB-FTP server doing these?, the RFC for the AUTH TLS/SSL available here . From reading the RFC, both parties, client and server should negotiate :

Establishing a Protected Session

              Client                                 Server
     control          data                   data               control
   ====================================================================

                                                                socket()
                                                                bind()
     socket()
     connect()  ----------------------------------------------> accept()
               <----------------------------------------------  220
     AUTH TLS   ---------------------------------------------->
               <----------------------------------------------  234
     TLSneg()  <----------------------------------------------> TLSneg()
     PBSZ 0     ---------------------------------------------->
               <----------------------------------------------  200
     PROT P     ---------------------------------------------->
               <----------------------------------------------  200
     USER fred  ---------------------------------------------->
               <----------------------------------------------  331
     PASS pass  ---------------------------------------------->
               <----------------------------------------------  230

Here is the log from the FlashFXP FTP client :

From the OpenSSL client :

C:\\OpenSSL-Win64\\bin>openssl s_client -starttls ftp -verify 10 -connect 192.168.1.227:21
verify depth is 10
CONNECTED(00000138)
5732:error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol:.\\ssl\\s23_clnt.c:797:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 55 bytes and written 317 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : 0000
    Session-ID:
    Session-ID-ctx:
    Master-Key:
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1504815003
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
---

While proper reply from secure ftp socket should be looks like these :

C:\\OpenSSL-Win64\\bin>openssl s_client -starttls ftp -verify 10 -connect 192.168.1.227:21
verify depth is 10
CONNECTED(00000134)
depth=0 CN = *, C = ID, ST = Jawa Barat, L = Bandung, O = nameless, OU = Development, emailAddress = admin@localhost.com
verify error:num=18:self signed certificate
verify return:1
depth=0 CN = *, C = ID, ST = Jawa Barat, L = Bandung, O = nameless, OU = Development, emailAddress = admin@localhost.com
verify return:1
---
Certificate chain
 0 s:/CN=*/C=ID/ST=Jawa Barat/L=Bandung/O=nameless/OU=Development/emailAddress=admin@localhost.com
   i:/CN=*/C=ID/ST=Jawa Barat/L=Bandung/O=nameless/OU=Development/emailAddress=admin@localhost.com
---
Server certificate
-----BEGIN CERTIFICATE-----

-----END CERTIFICATE-----
subject=/CN=*/C=ID/ST=Jawa Barat/L=Bandung/O=nameless/OU=Development/emailAddress=admin@localhost.com
issuer=/CN=*/C=ID/ST=Jawa Barat/L=Bandung/O=nameless/OU=Development/emailAddress=admin@localhost.com
---
No client certificate CA names sent
Peer signing digest: SHA512
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 2535 bytes and written 443 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 4096 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
    Session-ID: ADC824D5C561DE48A64424C81C165009BFD204C551635894CD00C14B7E4C9161
    Session-ID-ctx:
    Master-Key: 83AFF8D82609C77C95374D58ED05AF9FCF81433103B320918F28B2A9DC924E0E855ECE3AFFFCB32333CE52CDB2D62044
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 2000000000 (seconds)
    TLS session ticket:
    0000 - 75 0d b2 c2 3f fc 2e 0a-c9 e9 07 0e 3a aa 74 81   u...?.......:.t.
    0010 - 48 47 d8 c2 da f2 fc 40-b1 7a 7a 84 48 7b 41 12   HG.....@.zz.H{A.
    0020 - 3f 5c 33 0c 9f b6 d5 3c-88 51 3b 4d c8 72 6a 8b   ?\\3....<.Q;M.rj.
    0030 - 6a 1a c8 4f 8d 18 b5 e1-2f c1 8a c4 97 83 9f 3f   j..O..../......?
    0040 - f1 12 d5 d2 73 cc b2 77-80 03 cf 1c c0 78 61 04   ....s..w.....xa.
    0050 - b3 d7 7a 0c 65 e0 19 b8-eb 88 cb a0 f4 f7 50 bd   ..z.e.........P.
    0060 - 37 f1 f0 e1 03 27 b7 f1-14 e6 3d 37 4a 7e 7a 00   7....'....=7J~z.
    0070 - 3c 00 9f d1 1c fe 14 66-7a ef 13 33 7b 74 66 84   <......fz..3{tf.
    0080 - 75 68 9a 27 38 c6 10 cd-06 3d 1c 0d f1 58 fc 20   uh.'8....=...X.
    0090 - 3e 92 d3 dc 48 5b 25 3f-49 a8 5b 1d 63 b6 ea b9   >...H[%?I.[.c...

    Start Time: 1504814923
    Timeout   : 300 (sec)
    Verify return code: 18 (self signed certificate)
---
220 Please visit https://filezilla-project.org/
421 Server is going offline
closed

It looks that during the TLS negotiation the xojo’s SSLSocket doesn’t send the certificate?.

I have already tipple make sure that the server certificate is exist and under the documented format :

-----BEGIN RSA PRIVATE KEY-----

-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----

-----END CERTIFICATE-----

Should i filling a bug report or feedback?

It should be possible assuming the Xojo SSLSocket can switch between secure and insecure mode without disconnecting. The docs imply that it can, but I’ve never tried before. I’ve started a feature branch of RB-FTP to work on this: https://github.com/charonn0/RB-FTP/tree/AUTH-TLS

Some notes and clarifications:

  • The server has to operate in plain text mode until/unless the client requests TLS. This means that switching into AUTH mode as soon as the connection is established will not work.
  • DoVerb_AUTH is where you should switch into AUTH mode. i.e. the code in enableFTPS should be in DoVerb_AUTH (and enableFTPS can be deleted.)
  • The DoVerb_* methods are called by the ParseVerb method. If you add a new DoVerb_* method then you have to modify the ParseVerb method appropriately.
  • ParseVerb will reject all commands other than USER and PASS if the user is not logged in yet. ParseVerb must be modified to also allow AUTH in this circumstance.
  • FTP.Server is a subclass of TCPSocket (though it looks like you already changed it to SSLSocket)

WOW, it’s good to see you in xojo forum!, a fan of RB-FTP, about the new branch, i am getting these from FlashFXP :

[04:46:28] [R] Connecting to 192.168.1.227 -> IP=192.168.1.227 PORT=21
[04:46:28] [R] Connected to 192.168.1.227
[04:46:28] [R] 220 Welcome to BSFTPd!
[04:46:28] [R] AUTH TLS
[04:46:28] [R] 234 AUTH TLS OK.
[04:46:29] [R] SSL error:141A10F4:SSL routines:ossl_statem_client_read_transition:unexpected message
[04:46:29] [R] Failed TLSv1.2 negotiation, disconnected
[04:46:29] [R] Connection failed (Connection closed by client)

and these error from ftprush :

[1] Connecting to 192.168.1.227:21
[1] 220 Welcome to BSFTPd!
[1] AUTH TLS
[1] 234 AUTH TLS OK.
[1] error:14092072:SSL routines:ssl3_get_server_hello:bad message type
[1] Network subsystem is unusable(10091)
[1] Retrying after 30 seconds for ftp://192.168.1.227

Already modified the connection type from the AUTH-TLS branch.

Which are the messages that i had from my own branch of RB-FTP

I have already modified the ParseVerb and others thing on my branch, you can download it from feedback #49500.

Already aware that before response 234, it needs to be in plain text.

This project has so much potential for a learner or a open source project, planned to contribute my fixes to the LIST and MLST command which you might be already seen from the feedback #49500 project files.

It would be awesome if it will have scripting supports (python/lua), just like on glftpd or ioftpd

I can’t seem to get passed these handshake errors. It certainly seems like the SSLSocket is trying to negotiate a TLS session, but for whatever reason the clients aren’t expecting it.

Your contributions would be welcome! Your fix to the MLST method has just been applied :slight_smile:

As for your changes to LIST I have only one objection: you changed the LIST format from EPLF to a more Unix-ish style. I prefer EPLF (obviously) so rather than replace it I’d keep both and make it user-selectable. That way if someone uses a client that doesn’t understand one format they can use the other.

That confused me too, it seems the server doesn’t ‘understand’ TLS negotiation process, hmm.

Cool, glad that my small noobish centric contribution is worth a look :-), i use windows mainly so i haven’t tested out FTP Client from mac or unixes.

Would be great if you think this SSLSocket.Secure also a ‘bugs’ and upvote my feedback #49500.

Cheers,

That confused me too, it seems the server doesn’t ‘understand’ TLS negotiation process, hmm.

Cool, glad that my small noobish centric contribution is worth a look :-), i use windows mainly so i haven’t tested out FTP Client from mac or unixes.

Would be great if you think this SSLSocket.Secure also a ‘bugs’ and upvote my feedback #49500.

Cheers,

What happens if you use mode SSLV23
See http://documentation.xojo.com/index.php/SSLSocket.ConnectionType
It will auto negotiate the most secure connection it can

Tried before all of ConnectionType on my branch, and re-confirmed with Andrew’s RB-FTP AUTH-TLS branch, all of ConnectionType also throwing the same error :-(, hmm.

Interesting discovery: the AUTH-TLS branch works if you don’t use the ServerSocket.

@Andrew Lambert
Could you please share the details?, why you don’t push the changes into the AUTH-TLS branch?

When I say it “works” I only mean that AUTH TLS negotiation doesn’t fail. I posted this simple example project on the feedback case that demonstrates this.

Cool, perhaps xojo need to add ServerSocket specifically only for SSLSocket, as ServerSocket’s AddSocket event is in TCPSocket type?

Do you think it’s possible to rewrite RB-FTP in ‘naked socket’?

[EDIT]
Managed to do simple ‘rewrite’, changed the FTPServer’s super into “FTP.Server” and delete FTP.Server’s AddSocket and Error, and added these into PushButton3’s Action :

Dim n As NetworkInterface
If nic.ListIndex <> -1 Then
  n = nic.RowTag(nic.ListIndex)
Else
  n = System.GetNetworkInterface(0)
End If
If Me.Caption = "Listen" Then
  FTPServer.Banner = "Welcome to BSFTPd!"
  FTPServer.AllowWrite = True
  FTPServer.TimeOutPeriod = 60000
  FTPServer.Port = Val(Port.Text)
  FTPServer.NetworkInterface = n
  FTPServer.CertificateFile = SpecialFolder.Documents.Child("server.key")
  FTPServer.CertificatePassword = "demo"
  FTPServer.Secure = False
  FTPServer.ConnectionType = SSLSocket.TLSv12
  FTPServer.Listen()
  AddHandler FTPServer.FTPLog, WeakAddressOf LogHandler
  AddHandler FTPServer.UserLogon, WeakAddressOf UserLogonHandler
  Me.Caption = "Stop"
Else
  FTPServer.Disconnect
  Me.Caption = "Listen"
End If

Now it succeed to pass the AUTH TLS process but stuck at PASV & MLSD/LIST negotiation error :

[07:15:30] [R] Connecting to 192.168.1.227 -> IP=192.168.1.227 PORT=21
[07:15:30] [R] Connected to 192.168.1.227
[07:15:30] [R] 220 Welcome to BSFTPd!
[07:15:30] [R] AUTH TLS
[07:15:30] [R] 234 AUTH TLS OK.
[07:15:31] [R] TLSv1.2 negotiation successful...
[07:15:31] [R] TLSv1.2 encrypted session using cipher AES256-GCM-SHA384 (256 bits)
[07:15:31] [R] PBSZ 0
[07:15:31] [R] 200 Command successful.
[07:15:31] [R] USER anonymous
[07:15:31] [R] 331 Username received. Proceed by sending the password.
[07:15:31] [R] PASS (hidden)
[07:15:31] [R] 230 User logged in successfully, proceed.
[07:15:31] [R] SYST
[07:15:31] [R] 215 UNIX Type: L8
[07:15:31] [R] FEAT
[07:15:31] [R] 211-Features:
[07:15:31] [R]  PASV
[07:15:31] [R]  UTF8
[07:15:31] [R]  MDTM
[07:15:31] [R]  SIZE
[07:15:31] [R]  REST STREAM
[07:15:31] [R]  TVFS
[07:15:31] [R]  MLST
[07:15:31] [R]  XPWD
[07:15:31] [R]  XCWD
[07:15:31] [R]  AUTH TLS
[07:15:31] [R]  PBSZ
[07:15:31] [R]  PROT
[07:15:31] [R] 211 End
[07:15:31] [R] OPTS UTF8 ON
[07:15:31] [R] 200 Command successful.
[07:15:31] [R] PWD
[07:15:31] [R] 257 "/"
[07:15:31] [R] CWD /
[07:15:31] [R] 250 The requested file action was successful.
[07:15:31] [R] PWD
[07:15:31] [R] 257 "/"
[07:15:31] [R] PROT P
[07:15:31] [R] 504 Data security not available.
[07:15:31] [R] PASV
[07:15:31] [R] 227 Entering Passive Mode (192,168,1,227,130,91).
[07:15:31] [R] Opening data connection IP: 192.168.1.227 PORT: 33371
[07:15:31] [R] MLSD
[07:15:31] [R] SSL handshake error: This server does not support/allow TLSv1.
[07:15:31] [R] Info: Change via the Site Manager > Select the site profile > Connection Type > SSL Protocol
[07:15:31] [R] Data Socket Error: Failed TLSv1.2 negotiation, disconnected
[07:15:31] [R] 150 Command acknowledged; about to open the data connection.
[07:15:31] [R] 226 The service has closed the data connection.
[07:15:31] [R] PASV
[07:15:31] [R] 227 Entering Passive Mode (192,168,1,227,196,16).
[07:15:31] [R] Opening data connection IP: 192.168.1.227 PORT: 50192
[07:15:31] [R] MLSD
[07:15:31] [R] SSL handshake error: This server does not support/allow TLSv1.
[07:15:31] [R] Info: Change via the Site Manager > Select the site profile > Connection Type > SSL Protocol
[07:15:31] [R] Data Socket Error: Failed TLSv1.2 negotiation, disconnected
[07:15:31] [R] 150 Command acknowledged; about to open the data connection.
[07:15:31] [R] 226 The service has closed the data connection.
[07:15:32] [R] List Error
[07:15:32] [R] PASV
[07:15:33] [R] 227 Entering Passive Mode (192,168,1,227,186,120).
[07:15:33] [R] Opening data connection IP: 192.168.1.227 PORT: 47736
[07:15:33] [R] MLSD
[07:15:33] [R] SSL handshake error: This server does not support/allow TLSv1.
[07:15:33] [R] Info: Change via the Site Manager > Select the site profile > Connection Type > SSL Protocol
[07:15:33] [R] Data Socket Error: Failed TLSv1.2 negotiation, disconnected
[07:15:35] [R] 150 Command acknowledged; about to open the data connection.
[07:15:35] [R] 226 The service has closed the data connection.
[07:15:35] [R] PASV
[07:15:35] [R] 227 Entering Passive Mode (192,168,1,227,236,223).
[07:15:35] [R] Opening data connection IP: 192.168.1.227 PORT: 60639
[07:15:35] [R] MLSD
[07:15:35] [R] SSL handshake error: This server does not support/allow TLSv1.
[07:15:35] [R] Info: Change via the Site Manager > Select the site profile > Connection Type > SSL Protocol
[07:15:35] [R] Data Socket Error: Failed TLSv1.2 negotiation, disconnected
[07:15:35] [R] 150 Command acknowledged; about to open the data connection.
[07:15:35] [R] 226 The service has closed the data connection.
[07:15:36] [R] List Error
[07:15:42] [R] Connection Lost: 192.168.1.227 (Duration: 12 seconds / Idle: 7 seconds)

That’s pretty much how the FTP.Server class works already. The “naked socket” I posted in the Feedback case is just a simplified version that hilights the problem.

e.g. put this in App.Open of the latest AUTH-TLS branch:

[code] Dim client As New FTP.Server
client.Banner = “Welcome to BSFTPd!”
client.NetworkInterface = System.GetNetworkInterface(0)
client.CertificateFile = SpecialFolder.Desktop.Child(“cert”) ’ replace with actual file
client.CertificatePassword = “demo” ’ replace with actual password
client.Port = 21
client.Anonymous = True
client.RootDirectory = SpecialFolder.Desktop

client.Listen()
’ wait for connection
Do
client.Poll
Loop Until client.IsConnected

’ wait for disconnect
Do
client.Poll
Loop Until Not client.IsConnected
Quit[/code]

SSLSocket is a subclass of TCPSocket, and as such can be used anywhere a TCPSocket is expected.

I’m pretty sure the problem has to do with enabling TLS after the connection is established. I’ve noticed that in the “naked” versions the SSLSocket.Connected event is raised once when the TCP connection is established, and again when AUTH TLS succeeds. This behavior is reasonable, but seems to be totally undocumented and I think the ServerSocket isn’t expecting it.

The problem is the PROT P command. It’s telling the server to "P"rotect the data connection, typically with SSL/TLS. The RFC is a little vague about whether the data connection should switch into TLS mode before or after the connection attempt. I get weird SSL handshake errors either way, so I’m pretty sure I’m missing some important detail.

Currently, the AUTH-TLS branch will respond with 504 Data security not available. to indicate that TLS over the data connection is not supported. This is not strictly the correct thing to do, and some clients (like yours) won’t accept it. In my tests, Filezilla will proceed without protecting the data connection but only for directory listings (not for files.) I think this is an intentional security measure, but I’m not sure.

@Andrew Lambert
Based on these , looks like we need (which is already implemented) 2 separate socket, first for handling the plaintext, tls authentication on port 21 and another additional socket for each connected client also for handling passive/active? plaintext,tls connection

CONNECT [     0] - Incoming connection request
CONNECT [     0] - FTP Connection request accepted
COMMAND [     0] - AUTH TLS
  REPLY [     0] - 234 Authentication method accepted

CONNECT [     0] - SSL connection using TLSv1/SSLv3 (RC4-MD5)
CONNECT [     0] - SSL connection established
COMMAND [     0] - USER test
  REPLY [     0] - 331 User test, password please

COMMAND [     0] - PASS ***********
CONNECT [     0] - Native user 'test' authenticated
  REPLY [     0] - 230 Password Ok, User logged in

COMMAND [     0] - PBSZ 0
  REPLY [     0] - 200 PBSZ=0

COMMAND [     0] - PROT P
  REPLY [     0] - 200 PROT P OK, data channel will be secured

COMMAND [     0] - PASV
  REPLY [     0] - 227 Entering Passive Mode (127,0,0,1,43,41)

COMMAND [     0] - STOR test.txt
  REPLY [     0] - 150 Opening data connection

CONNECT [     0] - SSL connection using TLSv1/SSLv3 (RC4-MD5)
CONNECT [     0] - SSL data connection established
 SYSTEM [     0] - Successfully stored file at 'c:\\ftp\\test.txt'
  REPLY [     0] - 226 Transfer complete

COMMAND [     0] - QUIT
CONNECT [     0] - Connection terminated

So the answer might be after client issuing PROT P, then proceed with plaintext? PASV, and then the next issued commands will send through plain text while reply is not?

Here is another question that showed that client’s issued command is send by plain text?

[Command]  PWD
[Response]  257 "/" is current directory.
[Command]  PWD
[Response]  257 "/" is current directory.
[Command]  TYPE A
[Response]  200 Type set to A
[Command]  PWD
[Response]  257 "/" is current directory.
[Command]  PASV
[Response]  227 Entering Passive Mode (10,0,0,19,195,113)
[Command]  LIST -aL
[Response]  521 PROT P required
[Command]  PWD
[Response]  257 "/" is current directory.
[Command]  PASV
[Response]  227 Entering Passive Mode (10,0,0,19,195,114)
[Command]  LIST -aL
[Response]  521 PROT P required
[Status] Failed::FTP protocol error. 521 PROT P required.

RFC #4217 also explained these
Login Process :

12.1.  Establishing a Protected Session

              Client                                 Server
     control          data                   data               control
   ====================================================================

                                                                socket()
                                                                bind()
     socket()
     connect()  ----------------------------------------------> accept()
               <----------------------------------------------  220
     AUTH TLS   ---------------------------------------------->
               <----------------------------------------------  234
     TLSneg()  <----------------------------------------------> TLSneg()
     PBSZ 0     ---------------------------------------------->
               <----------------------------------------------  200
     PROT P     ---------------------------------------------->
               <----------------------------------------------  200
     USER fred  ---------------------------------------------->
               <----------------------------------------------  331
     PASS pass  ---------------------------------------------->
               <----------------------------------------------  230

Further Client<—>Server interactions

12.7.  A Firewall-Friendly Data Transfer with Protection

              Client                                 Server
     control          data                   data               control
   ====================================================================

     PASV -------------------------------------------------------->
                                             socket()
                                             bind()
         <------------------------------------------ 227 (w,x,y,z,a,b)
                      socket()
     STOR file --------------------------------------------------->
                      connect()  ----------> accept()
         <-------------------------------------------------------- 150
                      TLSneg()   <---------> TLSneg()
                      TLSwrite()  ---------> TLSread()
                      TLSshutdown() -------> TLSshutdown()
                      close()     ---------> close()
         <-------------------------------------------------------- 226

No, the PROT P command is issued after the control socket has switched to TLS successfully. And once TLS is enabled then both ends of the connection have to use it until/unless its disabled.

[quote=349882:@Aditya Nugraha]RFC #4217 also explained these
Login Process :[/quote]

Hmm, the diagram says to send status code 150 but I’ve been sending 200. I’ll have to test out 150; maybe that’s what I was missing :slight_smile:

Yes, what i meant by login process was, after the PASS as per-12.1 diagram. Most of the FTP client or others who referring to RFC is pretty strict about it’s implementation. In which code does the response 200 get sent?, i found several or PBSZ and PROT.

So what do you think about re-implementing it on “naked socket” on master and auth-tls branch?, as xojo seems probably pretty long to wait for it to get implemented.

The FTP.Server class already works that way, no re-implementation is needed.

I cannot seems making it work passing the FTP Client and server TLS negotiation without deleting AddSocket, Error handler from ServerSocket and put it on Open’s Handler as your suggested example or doing it in naked socket.