]> granicus.if.org Git - curl/commitdiff
curl_schannel.c: Reference count the credential/session handle
authorMarc Hoersken <info@marc-hoersken.de>
Sun, 9 Sep 2012 10:36:54 +0000 (12:36 +0200)
committerMarc Hoersken <info@marc-hoersken.de>
Sun, 9 Sep 2012 10:36:54 +0000 (12:36 +0200)
Reference counting the credential handle should avoid that such a
handle is freed while it is still required for connection shutdown

lib/curl_schannel.c
lib/urldata.h

index c050315c5f5e99f882feae7507e402e2244b089b..8ae1131df5917914cb51f5ba64a89f7645fd4161 100644 (file)
@@ -509,6 +509,13 @@ schannel_connect_step3(struct connectdata *conn, int sockindex)
     return CURLE_SSL_CONNECT_ERROR;
   }
 
+  /* increment the reference counter of the credential/session handle */
+  if(connssl->cred && connssl->ctxt) {
+    connssl->cred->refcount++;
+    infof(data, "schannel: incremented credential handle refcount = %d\n",
+          connssl->cred->refcount);
+  }
+
   /* save the current session data for possible re-use */
   incache = !(Curl_ssl_getsessionid(conn, (void**)&old_cred, NULL));
   if(incache) {
@@ -526,7 +533,7 @@ schannel_connect_step3(struct connectdata *conn, int sockindex)
       return retcode;
     }
     else {
-      infof(data, "schannel: stored crendential handle\n");
+      infof(data, "schannel: stored credential handle in session cache\n");
     }
   }
 
@@ -1063,7 +1070,7 @@ int Curl_schannel_shutdown(struct connectdata *conn, int sockindex)
   infof(data, "schannel: shutting down SSL/TLS connection with %s port %hu\n",
         conn->host.name, conn->remote_port);
 
-  if(connssl->ctxt) {
+  if(connssl->cred && connssl->ctxt) {
     SecBufferDesc BuffDesc;
     SecBuffer Buffer;
     SECURITY_STATUS sspi_status;
@@ -1125,6 +1132,13 @@ int Curl_schannel_shutdown(struct connectdata *conn, int sockindex)
       s_pSecFn->DeleteSecurityContext(&connssl->ctxt->ctxt_handle);
       Curl_safefree(connssl->ctxt);
     }
+
+    /* decrement the reference counter of the credential/session handle */
+    if(connssl->cred && connssl->cred->refcount > 0) {
+      connssl->cred->refcount--;
+      infof(data, "schannel: decremented credential handle refcount = %d\n",
+            connssl->cred->refcount);
+    }
   }
 
   /* free internal buffer for received encrypted data */
@@ -1148,7 +1162,7 @@ void Curl_schannel_session_free(void *ptr)
 {
   struct curl_schannel_cred *cred = ptr;
 
-  if(cred) {
+  if(cred && cred->refcount == 0) {
     s_pSecFn->FreeCredentialsHandle(&cred->cred_handle);
     Curl_safefree(cred);
   }
index fddfc0d055aaaa9adbf4612d67ef1e931ee95c62..5f893c92ee97c7294e542c43229a550501f00d4c 100644 (file)
@@ -234,6 +234,7 @@ enum protection_level {
 struct curl_schannel_cred {
   CredHandle cred_handle;
   TimeStamp time_stamp;
+  int refcount;
 };
 
 struct curl_schannel_ctxt {