Menu

#1382 curl with NSS can't work well when sent a LIST/NLST command via FTPS to remote server(VSFTP)

closed-invalid
NSS SSL (1)
5
2014-07-20
2014-06-18
Spec
No

OS type: Fedora
curl version: 7.32.0
libcurl version: 7.32.0
NSS version: 3.15.2
SSL version: should be SSLv3

The remote FTPS server is built via VSFTP(very secure FTP, built with OpenSSL).When I use curl (built with NSS) to login the server and send a LIST/NLST command(curl -k ftps://xxx:yyy@10.111.76.xxx/), the curl is blocked on the shell, unless the Ctrl C.It means the files' list on the remote server has been already downloaded and showed on the client's shell but the curl seems to continue waiting for something and do not stop.(Sorry for that I don't have the enviroment now.It's in the lab in my company and it's insulated with Internet)

I find that if the curl is rebuilt with OpenSSL then everything will be fine(no blocking).Or if I try to modify the code of VSFTP--Comment the second call of SSL_shutdown in ssl_data_close() and it's correlative code(see below) and it will be OK too.

int ssl_data_close(struct vsf_session* p_sess)
{
  int success = 1;
  SSL* p_ssl = p_sess->p_data_ssl;
  if (p_ssl)
  {
    int ret;
    maybe_log_shutdown_state(p_sess);
    /* This is a mess. Ideally, when we're the sender, we'd like to get to the
     * SSL_RECEIVED_SHUTDOWN state to get a cryptographic guarantee that the
     * peer received all the data and shut the connection down cleanly. It
     * doesn't matter hugely apart from logging, but it's a nagging detail.
     * Unfortunately, no FTP client I found was able to get sends into that
     * state, so the best we can do is issue SSL_shutdown but not check the
     * errors / returns. At least this enables the receiver to be sure of the
     * integrity of the send in terms of unwanted truncation.
     */
    ret = SSL_shutdown(p_ssl);
    maybe_log_shutdown_state(p_sess);
    if (ret == 0)
    {
      **#if 0                               // add for bug avoiding**
      ret = SSL_shutdown(p_ssl);
      maybe_log_shutdown_state(p_sess);
      if (ret != 1)
      {
        if (tunable_strict_ssl_write_shutdown)
        {
          success = 0;
        }
        maybe_log_shutdown_state(p_sess);
        maybe_log_ssl_error_state(p_sess, ret);
      }
      **#endif                              // add for bug avoiding**
    }
    else if (ret < 0)
    {
      if (tunable_strict_ssl_write_shutdown)
      {
        success = 0;
      }
      maybe_log_ssl_error_state(p_sess, ret);
    }
    SSL_free(p_ssl);
    p_sess->p_data_ssl = NULL;
  }
  return success;
}

I think the problem is in the function nss_recv().It calls PR_Recv() and doesn't deal with the return value nread correctly(Or the PR_Recv has wrong behavior when received a SSL_SENT_SHUTDOWN(in ssl3_shutdown) flag and return the wrong value).

When I followed the call stack during the blocking, I found the PR_GetError()'s return value will always be PR_WOULD_BLOCK_ERROR(the fd should be nonblock and the buffer for reading is already empty actually).Then the Curl_read will return CURLE_AGAIN.And the KEEP_RECV flag will never be reset.The FSM state will stay in CURLM_STATE_PERFORM forever and can't transform to CURLM_STATE_DONE finally.

Is it a bug??

P.S. The RETR command(curl -k ftps://xxx:yyy@10.111.76.xxx/1, 1 is an exist file on the remote server) doesn't have this problem.I think the reason is that the SIZE command get the actual size the curl will and have to receive.When it is reached, the connection will be closed naturally.

Sorry for my poor English, hope that you can understand my words:D thx!!

Discussion

  • Daniel Stenberg

    Daniel Stenberg - 2014-06-21
    • assigned_to: Daniel Stenberg
     
  • Daniel Stenberg

    Daniel Stenberg - 2014-06-21

    You say you think it doesn't deal with the return code correctly in nss_recv(). Can you be more specific then and tell us exactly how you think it should handle the return code - the way you think is correct?

    To me this seems like NSS returns "would block" and what else can libcurl do then than to trust what it says?

     
  • Daniel Stenberg

    Daniel Stenberg - 2014-06-27
    • status: open --> pending-needsinfo
     
  • Daniel Stenberg

    Daniel Stenberg - 2014-07-20
    • status: pending-needsinfo --> closed-invalid
     
  • Daniel Stenberg

    Daniel Stenberg - 2014-07-20

    No further info, closing