[Spice-devel] [PATCH spice-server v6 8/9] red-stream: Unify start and step passes

Frediano Ziglio fziglio at redhat.com
Tue Jan 9 07:45:07 UTC 2018


Most of these function are identical.
Only difference were basically debugging message but now
with a proper tests are less important.
The mechname field is used to differentiate between first step and
following ones.

Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
---
 server/red-stream.c | 156 +++++++++++-----------------------------------------
 1 file changed, 32 insertions(+), 124 deletions(-)

diff --git a/server/red-stream.c b/server/red-stream.c
index 5c2c2739..242e552c 100644
--- a/server/red-stream.c
+++ b/server/red-stream.c
@@ -782,111 +782,6 @@ static void red_sasl_error(void *opaque, int err)
 
 static void red_sasl_handle_auth_steplen(void *opaque);
 
-static void red_sasl_handle_auth_step(void *opaque)
-{
-    RedStream *stream = ((RedSASLAuth *)opaque)->stream;
-    const char *serverout;
-    unsigned int serveroutlen;
-    int err;
-    char *clientdata = NULL;
-    RedSASL *sasl = &stream->priv->sasl;
-    uint32_t datalen = sasl->len;
-
-    /* NB, distinction of NULL vs "" is *critical* in SASL */
-    if (datalen) {
-        clientdata = sasl->data;
-        clientdata[datalen - 1] = '\0'; /* Wire includes '\0', but make sure */
-        datalen--; /* Don't count NULL byte when passing to _start() */
-    }
-
-    spice_debug("Step using SASL Data %p (%d bytes)",
-               clientdata, datalen);
-    err = sasl_server_step(sasl->conn,
-                           clientdata,
-                           datalen,
-                           &serverout,
-                           &serveroutlen);
-    if (err != SASL_OK &&
-        err != SASL_CONTINUE) {
-        spice_warning("sasl step failed %d (%s)",
-                      err, sasl_errdetail(sasl->conn));
-        return red_sasl_async_result(opaque, RED_SASL_ERROR_GENERIC);
-    }
-
-    if (serveroutlen > SASL_DATA_MAX_LEN) {
-        spice_warning("sasl step reply data too long %d",
-                      serveroutlen);
-        return red_sasl_async_result(opaque, RED_SASL_ERROR_GENERIC);
-    }
-
-    spice_debug("SASL return data %d bytes, %p", serveroutlen, serverout);
-
-    if (serveroutlen) {
-        serveroutlen += 1;
-        red_stream_write_u32_le(stream, serveroutlen);
-        red_stream_write_all(stream, serverout, serveroutlen);
-    } else {
-        red_stream_write_u32_le(stream, serveroutlen);
-    }
-
-    /* Whether auth is complete */
-    red_stream_write_u8(stream, err == SASL_CONTINUE ? 0 : 1);
-
-    if (err == SASL_CONTINUE) {
-        spice_debug("%s", "Authentication must continue (step)");
-        /* Wait for step length */
-        red_stream_async_read(stream, (uint8_t *)&sasl->len, sizeof(uint32_t),
-                              red_sasl_handle_auth_steplen, opaque);
-        return;
-    } else {
-        int ssf;
-
-        if (auth_sasl_check_ssf(sasl, &ssf) == 0) {
-            spice_warning("Authentication rejected for weak SSF");
-            goto authreject;
-        }
-
-        spice_debug("Authentication successful");
-        red_stream_write_u32_le(stream, SPICE_LINK_ERR_OK); /* Accept auth */
-
-        /*
-         * Delay writing in SSF encoded until now
-         */
-        sasl->runSSF = ssf;
-        red_stream_disable_writev(stream); /* make sure writev isn't called directly anymore */
-
-        return red_sasl_async_result(opaque, RED_SASL_ERROR_OK);
-    }
-
-authreject:
-    red_stream_write_u32_le(stream, 1); /* Reject auth */
-    red_stream_write_u32_le(stream, sizeof("Authentication failed"));
-    red_stream_write_all(stream, "Authentication failed", sizeof("Authentication failed"));
-
-    red_sasl_async_result(opaque, RED_SASL_ERROR_AUTH_FAILED);
-}
-
-static void red_sasl_handle_auth_steplen(void *opaque)
-{
-    RedStream *stream = ((RedSASLAuth *)opaque)->stream;
-    RedSASL *sasl = &stream->priv->sasl;
-
-    sasl->len = GUINT32_FROM_LE(sasl->len);
-    spice_debug("Got steplen %d", sasl->len);
-    if (sasl->len > SASL_DATA_MAX_LEN) {
-        spice_warning("Too much SASL data %d", sasl->len);
-        return red_sasl_async_result(opaque, RED_SASL_ERROR_GENERIC);
-    }
-
-    if (sasl->len == 0) {
-        red_sasl_handle_auth_step(opaque);
-    } else {
-        sasl->data = g_realloc(sasl->data, sasl->len);
-        red_stream_async_read(stream, (uint8_t *)sasl->data, sasl->len,
-                              red_sasl_handle_auth_step, opaque);
-    }
-}
-
 /*
  * Start Msg
  *
@@ -902,7 +797,7 @@ static void red_sasl_handle_auth_steplen(void *opaque)
  * u8 continue
  */
 
-static void red_sasl_handle_auth_start(void *opaque)
+static void red_sasl_handle_auth_step(void *opaque)
 {
     RedStream *stream = ((RedSASLAuth *)opaque)->stream;
     const char *serverout;
@@ -915,27 +810,38 @@ static void red_sasl_handle_auth_start(void *opaque)
     /* NB, distinction of NULL vs "" is *critical* in SASL */
     if (datalen) {
         clientdata = sasl->data;
-        clientdata[datalen - 1] = '\0'; /* Should be on wire, but make sure */
+        clientdata[datalen - 1] = '\0'; /* Wire includes '\0', but make sure */
         datalen--; /* Don't count NULL byte when passing to _start() */
     }
 
-    spice_debug("Start SASL auth with mechanism %s. Data %p (%d bytes)",
-               sasl->mechname, clientdata, datalen);
-    err = sasl_server_start(sasl->conn,
-                            sasl->mechname,
-                            clientdata,
-                            datalen,
-                            &serverout,
-                            &serveroutlen);
+    if (sasl->mechname != NULL) {
+        spice_debug("Start SASL auth with mechanism %s. Data %p (%d bytes)",
+                   sasl->mechname, clientdata, datalen);
+        err = sasl_server_start(sasl->conn,
+                                sasl->mechname,
+                                clientdata,
+                                datalen,
+                                &serverout,
+                                &serveroutlen);
+        g_free(sasl->mechname);
+        sasl->mechname = NULL;
+    } else {
+        spice_debug("Step using SASL Data %p (%d bytes)", clientdata, datalen);
+        err = sasl_server_step(sasl->conn,
+                               clientdata,
+                               datalen,
+                               &serverout,
+                               &serveroutlen);
+    }
     if (err != SASL_OK &&
         err != SASL_CONTINUE) {
-        spice_warning("sasl start failed %d (%s)",
+        spice_warning("sasl step failed %d (%s)",
                     err, sasl_errdetail(sasl->conn));
         return red_sasl_async_result(opaque, RED_SASL_ERROR_GENERIC);
     }
 
     if (serveroutlen > SASL_DATA_MAX_LEN) {
-        spice_warning("sasl start reply data too long %d",
+        spice_warning("sasl step reply data too long %d",
                       serveroutlen);
         return red_sasl_async_result(opaque, RED_SASL_ERROR_GENERIC);
     }
@@ -954,7 +860,7 @@ static void red_sasl_handle_auth_start(void *opaque)
     red_stream_write_u8(stream, err == SASL_CONTINUE ? 0 : 1);
 
     if (err == SASL_CONTINUE) {
-        spice_debug("%s", "Authentication must continue (start)");
+        spice_debug("%s", "Authentication must continue");
         /* Wait for step length */
         red_stream_async_read(stream, (uint8_t *)&sasl->len, sizeof(uint32_t),
                               red_sasl_handle_auth_steplen, opaque);
@@ -987,27 +893,29 @@ authreject:
     red_sasl_async_result(opaque, RED_SASL_ERROR_AUTH_FAILED);
 }
 
-static void red_sasl_handle_auth_startlen(void *opaque)
+static void red_sasl_handle_auth_steplen(void *opaque)
 {
     RedStream *stream = ((RedSASLAuth *)opaque)->stream;
     RedSASL *sasl = &stream->priv->sasl;
 
     sasl->len = GUINT32_FROM_LE(sasl->len);
-    spice_debug("Got client start len %d", sasl->len);
+    spice_debug("Got steplen %d", sasl->len);
     if (sasl->len > SASL_DATA_MAX_LEN) {
         spice_warning("Too much SASL data %d", sasl->len);
-        return red_sasl_async_result(opaque, RED_SASL_ERROR_INVALID_DATA);
+        return red_sasl_async_result(opaque, sasl->mechname ? RED_SASL_ERROR_INVALID_DATA : RED_SASL_ERROR_GENERIC);
     }
 
     if (sasl->len == 0) {
-        return red_sasl_handle_auth_start(opaque);
+        return red_sasl_handle_auth_step(opaque);
     }
 
     sasl->data = g_realloc(sasl->data, sasl->len);
     red_stream_async_read(stream, (uint8_t *)sasl->data, sasl->len,
-                          red_sasl_handle_auth_start, opaque);
+                          red_sasl_handle_auth_step, opaque);
 }
 
+
+
 static void red_sasl_handle_auth_mechname(void *opaque)
 {
     RedStream *stream = ((RedSASLAuth *)opaque)->stream;
@@ -1027,7 +935,7 @@ static void red_sasl_handle_auth_mechname(void *opaque)
     spice_debug("Validated mechname '%s'", sasl->mechname);
 
     red_stream_async_read(stream, (uint8_t *)&sasl->len, sizeof(uint32_t),
-                          red_sasl_handle_auth_startlen, opaque);
+                          red_sasl_handle_auth_steplen, opaque);
 }
 
 static void red_sasl_handle_auth_mechlen(void *opaque)
-- 
2.14.3



More information about the Spice-devel mailing list