ruby - ¿EventMachine emite close_notify en close_connection si se ejecutó tls_start?
ssl ftps (2)
Estoy intentando programar un servidor FTPS simple basado en EventMachine.
El zócalo de control funciona correctamente. Cuando se usa el socket de datos para la transferencia de datos, parece que todo funciona bien (el protocolo de enlace TLS se completa con éxito y se reciben los datos), pero luego aparece un mensaje de error. Esto es lo que obtengo en Filezilla:
Command: LIST
Response: 150 Opening ASCII mode data connection for file list
Trace: CFtpControlSocket::TransferParseResponse()
Trace: code = 1
Trace: state = 4
Trace: CFtpControlSocket::SendNextCommand()
Trace: CFtpControlSocket::TransferSend()
Trace: state = 5
Trace: CTransferSocket::OnConnect
Trace: CTlsSocket::Handshake()
Trace: gnutls_session_get_data on primary socket failed: -51
Trace: CTlsSocket::ContinueHandshake()
Trace: CTlsSocket::OnSend()
Trace: CTlsSocket::OnSend()
Trace: CTlsSocket::OnRead()
Trace: CTlsSocket::ContinueHandshake()
Trace: CTlsSocket::OnRead()
Trace: CTlsSocket::ContinueHandshake()
Trace: Handshake successful
Trace: Cipher: AES-256-CBC, MAC: SHA1
Trace: CTlsSocket::OnRead()
Trace: CTransferSocket::OnConnect
Trace: CTransferSocket::OnReceive(), m_transferMode=0
Listing: -rwxrwxrwx 1 owner group 1011 Dec 12 23:05 a.tmp
Trace: CTlsSocket::Failure(-9, 0)
Error: GnuTLS error -9: A TLS packet with unexpected length was received.
Status: Server did not properly shut down TLS connection
Error: Could not read from transfer socket: ECONNABORTED - Connection aborted
Trace: CTransferSocket::TransferEnd(3)
Trace: CFtpControlSocket::OnReceive()
Response: 226 Closing data connection, sent 70 bytes
Trace: CFtpControlSocket::TransferParseResponse()
Trace: code = 2
Trace: state = 5
Trace: CFtpControlSocket::SendNextCommand()
Trace: CFtpControlSocket::TransferSend()
Trace: state = 8
Trace: CFtpControlSocket::TransferEnd()
Trace: CFtpControlSocket::ResetOperation(2)
Trace: CControlSocket::ResetOperation(2)
Trace: CFtpControlSocket::ParseSubcommandResult(2)
Trace: CFtpControlSocket::ListSubcommandResult()
Trace: state = 3
Trace: CFtpControlSocket::ResetOperation(2)
Trace: CControlSocket::ResetOperation(2)
Error: Failed to retrieve directory listing
Trace: CFileZillaEnginePrivate::ResetOperation(2)
ftp-ssl también emite un error aunque algo diferente
--> LIST
150 Opening ASCII mode data connection for file list
===>START SSL connect on DATA
ftp: SSL_connect DATA error 0 - error:00000000:lib(0):func(0):reason(0)
226 Closing data connection, sent 70 bytes
421 Service not available, remote server has closed connection
Por lo que encontré en la web, sospecho que este comportamiento se debe a que close_notify no se emite al final de la conexión. Si es así, ¿existe alguna solución conocida basada en Ruby para eso (por ejemplo, usar OpenSSL :: SSL :: SSLSocket)?
Encontré que SSL "vuelve a abrir" una conexión después de leer el certificado, por lo que la solución es:
def receive_data bitOfData
if (self.class isSomeSortOfTLSreadingClass && bitOfData.length == 1) then
@headBuff << bitOfData
return
end
# TLS connection closes on first byte, then re-opens.
end
La respuesta es bastante corta: no, EventMachine no emite close_notify en close_connection si se ejecutó tls_start.