]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
sasl: Fix authentication when using PLAIN mechanism
authorChristophe Fergeau <cfergeau@redhat.com>
Thu, 21 Nov 2013 17:40:52 +0000 (18:40 +0100)
committerChristophe Fergeau <cfergeau@redhat.com>
Tue, 26 Nov 2013 10:52:58 +0000 (11:52 +0100)
With some authentication mechanism (PLAIN for example), sasl_client_start()
can return SASL_OK, which translates to virNetSASLSessionClientStart()
returning VIR_NET_SASL_COMPLETE.
cyrus-sasl documentation is a bit vague as to what to do in such situation,
but upstream clarified this a bit in
http://asg.andrew.cmu.edu/archive/message.php?mailbox=archive.cyrus-sasl&msg=10104

When we got VIR_NET_SASL_COMPLETE after virNetSASLSessionClientStart() and
if the remote also tells us that authentication is complete, then we should
end the authentication procedure rather than forcing a call to
virNetSASLSessionClientStep(). Without this patch, when trying to use SASL
PLAIN, I get:
errorĀ :authentication failed : Failed to step SASL negotiation: -1
(SASL(-1): generic failure: Unable to find a callback: 32775)

This patch is based on a spice-gtk patch by Dietmar Maurer.

src/remote/remote_driver.c

index a73344639b9e3f71057a3870e9c448ee69651082..60b65a36e4c3c2c59be2e7a00e0d9df17729577a 100644 (file)
@@ -4127,6 +4127,11 @@ remoteAuthSASL(virConnectPtr conn, struct private_data *priv,
     VIR_DEBUG("Client step result complete: %d. Data %zu bytes %p",
               complete, serverinlen, serverin);
 
+    /* Previous server call showed completion & sasl_client_start() told us
+     * we are locally complete too */
+    if (complete && err == VIR_NET_SASL_COMPLETE)
+        goto done;
+
     /* Loop-the-loop...
      * Even if the server has completed, the client must *always* do at least one step
      * in this loop to verify the server isn't lying about something. Mutual auth */
@@ -4201,6 +4206,7 @@ remoteAuthSASL(virConnectPtr conn, struct private_data *priv,
         priv->is_secure = 1;
     }
 
+done:
     VIR_DEBUG("SASL authentication complete");
     virNetClientSetSASLSession(priv->client, sasl);
     ret = 0;