Files
Open_Ultra_SAST/benchmarks/pairs/vfc/curl-cve-2022-27782-gtls_shutdown/fixed.c
T

89 lines
2.6 KiB
C
Raw Normal View History

/* Provenance: curl/curl gtls_shutdown (fixed).
* repo: curl/curl
* commit: f18af4f874cecab82a9797e8c7541e0990c7a64c
* parent: 7e92d12b4e6911f424678a133b19de670e183a59
* commit_url: https://github.com/curl/curl/commit/f18af4f874cecab82a9797e8c7541e0990c7a64c
* cve: CVE-2022-27782
* license: curl
* function: gtls_shutdown
* relpath: lib/vtls/gtls.c
* provenance: human
* mechanism: other
*/
static int gtls_shutdown(struct Curl_easy *data, struct connectdata *conn,
int sockindex)
{
struct ssl_connect_data *connssl = &conn->ssl[sockindex];
struct ssl_backend_data *backend = connssl->backend;
int retval = 0;
DEBUGASSERT(backend);
#ifndef CURL_DISABLE_FTP
/* 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(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE)
gnutls_bye(backend->session, GNUTLS_SHUT_WR);
#endif
if(backend->session) {
ssize_t result;
bool done = FALSE;
char buf[120];
while(!done) {
int what = SOCKET_READABLE(conn->sock[sockindex],
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(backend->session,
buf, sizeof(buf));
switch(result) {
case 0:
/* This is the expected response. There was no data but only
the close notify alert */
done = TRUE;
break;
case GNUTLS_E_AGAIN:
case GNUTLS_E_INTERRUPTED:
infof(data, "GNUTLS_E_AGAIN || GNUTLS_E_INTERRUPTED");
break;
default:
retval = -1;
done = TRUE;
break;
}
}
else if(0 == what) {
/* timeout */
failf(data, "SSL shutdown timeout");
done = TRUE;
}
else {
/* anything that gets here is fatally bad */
failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
retval = -1;
done = TRUE;
}
}
gnutls_deinit(backend->session);
}
gnutls_certificate_free_credentials(backend->cred);
#ifdef USE_GNUTLS_SRP
if(SSL_SET_OPTION(primary.authtype) == CURL_TLSAUTH_SRP
&& SSL_SET_OPTION(primary.username) != NULL)
gnutls_srp_free_client_credentials(backend->srp_client_cred);
#endif
backend->cred = NULL;
backend->session = NULL;
return retval;
}