[PATCH] secur32: Ignore spurious callbacks on macOS.

Hans Leidekker hans at codeweavers.com
Fri Feb 1 04:09:50 CST 2019


For unknown reasons Mojave will sometimes call the schan_push_adapter callback during an SSLRead call.
This confuses our code which is only prepared to handle schan_pull_adapter callbacks in this context.

Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
 dlls/secur32/schannel_macosx.c | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/dlls/secur32/schannel_macosx.c b/dlls/secur32/schannel_macosx.c
index bd080dcb41..29d2f65172 100644
--- a/dlls/secur32/schannel_macosx.c
+++ b/dlls/secur32/schannel_macosx.c
@@ -181,10 +181,17 @@ enum {
 };
 #endif
 
+enum schan_mode {
+    schan_mode_NONE,
+    schan_mode_READ,
+    schan_mode_WRITE,
+    schan_mode_HANDSHAKE,
+};
 
 struct mac_session {
     SSLContextRef context;
     struct schan_transport *transport;
+    enum schan_mode mode;
     CRITICAL_SECTION cs;
 };
 
@@ -634,6 +641,12 @@ static OSStatus schan_pull_adapter(SSLConnectionRef transport, void *buff,
 
     TRACE("(%p/%p, %p, %p/%lu)\n", s, s->transport, buff, buff_len, *buff_len);
 
+    if (s->mode != schan_mode_READ && s->mode != schan_mode_HANDSHAKE)
+    {
+        WARN("called in mode %u\n", s->mode);
+        return noErr;
+    }
+
     status = schan_pull(s->transport, buff, buff_len);
     if (status == 0)
     {
@@ -693,6 +706,12 @@ static OSStatus schan_push_adapter(SSLConnectionRef transport, const void *buff,
 
     TRACE("(%p/%p, %p, %p/%lu)\n", s, s->transport, buff, buff_len, *buff_len);
 
+    if (s->mode != schan_mode_WRITE && s->mode != schan_mode_HANDSHAKE)
+    {
+        WARN("called in mode %u\n", s->mode);
+        return noErr;
+    }
+
     status = schan_push(s->transport, buff, buff_len);
     if (status == 0)
     {
@@ -787,6 +806,8 @@ BOOL schan_imp_create_session(schan_imp_session *session, schan_credentials *cre
         goto fail;
     }
 
+    s->mode = schan_mode_NONE;
+
     TRACE("    -> %p/%p\n", s, s->context);
 
     *session = (schan_imp_session)s;
@@ -837,7 +858,10 @@ SECURITY_STATUS schan_imp_handshake(schan_imp_session session)
 
     TRACE("(%p/%p)\n", s, s->context);
 
+    s->mode = schan_mode_HANDSHAKE;
     status = SSLHandshake(s->context);
+    s->mode = schan_mode_NONE;
+
     if (status == noErr)
     {
         TRACE("Handshake completed\n");
@@ -1096,8 +1120,13 @@ SECURITY_STATUS schan_imp_send(schan_imp_session session, const void *buffer,
     TRACE("(%p/%p, %p, %p/%lu)\n", s, s->context, buffer, length, *length);
 
     EnterCriticalSection(&s->cs);
+    s->mode = schan_mode_WRITE;
+
     status = SSLWrite(s->context, buffer, *length, length);
+
+    s->mode = schan_mode_NONE;
     LeaveCriticalSection(&s->cs);
+
     if (status == noErr)
         TRACE("Wrote %lu bytes\n", *length);
     else if (status == errSSLWouldBlock)
@@ -1128,8 +1157,13 @@ SECURITY_STATUS schan_imp_recv(schan_imp_session session, void *buffer,
     TRACE("(%p/%p, %p, %p/%lu)\n", s, s->context, buffer, length, *length);
 
     EnterCriticalSection(&s->cs);
+    s->mode = schan_mode_READ;
+
     status = SSLRead(s->context, buffer, *length, length);
+
+    s->mode = schan_mode_NONE;
     LeaveCriticalSection(&s->cs);
+
     if (status == noErr || status == errSSLClosedGraceful)
         TRACE("Read %lu bytes\n", *length);
     else if (status == errSSLWouldBlock)
-- 
2.11.0




More information about the wine-devel mailing list