From 2e2f8e899143ed549598290f607499c365167b86 Mon Sep 17 00:00:00 2001
From: Marc Hoersken <info@marc-hoersken.de>
Date: Sat, 4 May 2013 20:28:30 +0200
Subject: [PATCH] curl_schannel.c: Fixed invalid memory access during SSL
 shutdown

---
 lib/curl_schannel.c | 20 ++++++++------------
 lib/urldata.h       |  1 +
 2 files changed, 9 insertions(+), 12 deletions(-)

diff --git a/lib/curl_schannel.c b/lib/curl_schannel.c
index 863d471..db507fd 100644
--- a/lib/curl_schannel.c
+++ b/lib/curl_schannel.c
@@ -523,6 +523,7 @@ schannel_connect_step3(struct connectdata *conn, int sockindex)
     if(old_cred != connssl->cred) {
       infof(data, "schannel: old credential handle is stale, removing\n");
       Curl_ssl_delsessionid(conn, (void*)old_cred);
+      old_cred->cached = FALSE;
       incache = FALSE;
     }
   }
@@ -534,6 +535,7 @@ schannel_connect_step3(struct connectdata *conn, int sockindex)
       return retcode;
     }
     else {
+      connssl->cred->cached = TRUE;
       infof(data, "schannel: stored credential handle in session cache\n");
     }
   }
@@ -1141,17 +1143,11 @@ int Curl_schannel_shutdown(struct connectdata *conn, int sockindex)
               connssl->cred->refcount);
       }
 
-      /* if the handle refcount is zero, check if we have not cached it */
-      if(connssl->cred->refcount == 0) {
-        if(Curl_ssl_getsessionid(conn, (void**)&cached_cred, NULL)) {
-          cached_cred = NULL;
-        }
-        /* if the handle was not cached, it is stale to be freed */
-        if(connssl->cred != cached_cred) {
-          infof(data, "schannel: clear credential handle\n");
-          s_pSecFn->FreeCredentialsHandle(&connssl->cred->cred_handle);
-          Curl_safefree(connssl->cred);
-        }
+      /* if the handle was not cached and the refcount is zero */
+      if(!connssl->cred->cached && connssl->cred->refcount == 0) {
+        infof(data, "schannel: clear credential handle\n");
+        s_pSecFn->FreeCredentialsHandle(&connssl->cred->cred_handle);
+        Curl_safefree(connssl->cred);
       }
     }
   }
@@ -1177,7 +1173,7 @@ void Curl_schannel_session_free(void *ptr)
 {
   struct curl_schannel_cred *cred = ptr;
 
-  if(cred && cred->refcount == 0) {
+  if(cred && cred->cached && cred->refcount == 0) {
     s_pSecFn->FreeCredentialsHandle(&cred->cred_handle);
     Curl_safefree(cred);
   }
diff --git a/lib/urldata.h b/lib/urldata.h
index 55f4884..8d6c420 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -243,6 +243,7 @@ struct curl_schannel_cred {
   CredHandle cred_handle;
   TimeStamp time_stamp;
   int refcount;
+  bool cached;
 };
 
 struct curl_schannel_ctxt {
-- 
1.8.0.msysgit.0

