From 4750e6f3c5fd42e19998242ddb63d7d5506b9fd9 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 5 Jan 2007 23:11:14 +0000 Subject: - Linus Nielsen Feltzing introduced the --ftp-ssl-ccc command line option to curl that uses the new CURLOPT_FTP_SSL_CCC option in libcurl. If enabled, it will make libcurl shutdown SSL/TLS after the authentication is done on a FTP-SSL operation. --- lib/gtls.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) (limited to 'lib/gtls.c') diff --git a/lib/gtls.c b/lib/gtls.c index bbd87161d..250ecada4 100644 --- a/lib/gtls.c +++ b/lib/gtls.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2006, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2007, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -516,6 +516,72 @@ void Curl_gtls_close(struct connectdata *conn) close_one(conn, 1); } +/* + * This function is called to shut down the SSL layer but keep the + * socket open (CCC - Clear Command Channel) + */ +int Curl_gtls_shutdown(struct connectdata *conn, int sockindex) +{ + int result; + int retval = 0; + struct SessionHandle *data = conn->data; + int done = 0; + ssize_t nread; + char buf[120]; + + /* This has only been tested on the proftpd server, and the mod_tls code + sends a close notify alert without waiting for a close notify alert in + response. Thus we wait for a close notify alert from the server, but + we do not send one. Let's hope other servers do the same... */ + + if(conn->ssl[sockindex].session) { + while(!done) { + int what = Curl_select(conn->sock[sockindex], + CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT); + if(what > 0) { + /* Something to read, let's do it and hope that it is the close + notify alert from the server */ + result = gnutls_record_recv(conn->ssl[sockindex].session, + buf, sizeof(buf)); + switch(result) { + case 0: + /* This is the expected response. There was no data but only + the close notify alert */ + done = 1; + break; + case GNUTLS_E_AGAIN: + case GNUTLS_E_INTERRUPTED: + infof(data, "GNUTLS_E_AGAIN || GNUTLS_E_INTERRUPTED\n"); + break; + default: + retval = -1; + done = 1; + break; + } + } + else if(0 == what) { + /* timeout */ + failf(data, "SSL shutdown timeout"); + done = 1; + break; + } + else { + /* anything that gets here is fatally bad */ + failf(data, "select on SSL socket, errno: %d", Curl_sockerrno()); + retval = -1; + done = 1; + } + } + gnutls_deinit(conn->ssl[sockindex].session); + } + gnutls_certificate_free_credentials(conn->ssl[sockindex].cred); + + conn->ssl[sockindex].session = NULL; + conn->ssl[sockindex].use = FALSE; + + return retval; +} + /* * If the read would block we return -1 and set 'wouldblock' to TRUE. * Otherwise we return the amount of data read. Other errors should return -1 -- cgit v1.2.3