virNetServerClientImmediateClose;
virNetServerClientInit;
virNetServerClientInitKeepAlive;
+virNetServerClientIsAuthPendingLocked;
virNetServerClientIsClosedLocked;
virNetServerClientIsLocal;
virNetServerClientIsSecure;
virNetServerClientRemoveFilter;
virNetServerClientSendMessage;
virNetServerClientSetAuthLocked;
+virNetServerClientSetAuthPendingLocked;
virNetServerClientSetCloseHook;
virNetServerClientSetDispatcher;
virNetServerClientSetReadonly;
srv->clients[srv->nclients-1] = virObjectRef(client);
virObjectLock(client);
- if (virNetServerClientNeedAuthLocked(client))
+ if (virNetServerClientIsAuthPendingLocked(client))
virNetServerTrackPendingAuthLocked(srv);
virObjectUnlock(client);
#endif
+/**
+ * virNetServerSetClientAuthCompletedLocked:
+ * @srv: server must be locked by the caller
+ * @client: client must be locked by the caller
+ *
+ * If the client authentication was pending, clear that pending and
+ * update the server tracking.
+ */
+static void
+virNetServerSetClientAuthCompletedLocked(virNetServerPtr srv,
+ virNetServerClientPtr client)
+{
+ if (virNetServerClientIsAuthPendingLocked(client)) {
+ virNetServerClientSetAuthPendingLocked(client, false);
+ virNetServerTrackCompletedAuthLocked(srv);
+ }
+}
+
+
/**
* virNetServerSetClientAuthenticated:
* @srv: server must be unlocked
virObjectLock(srv);
virObjectLock(client);
virNetServerClientSetAuthLocked(client, VIR_NET_SERVER_SERVICE_AUTH_NONE);
- virNetServerTrackCompletedAuthLocked(srv);
+ virNetServerSetClientAuthCompletedLocked(srv, client);
virNetServerCheckLimits(srv);
virObjectUnlock(client);
virObjectUnlock(srv);
if (virNetServerClientIsClosedLocked(client)) {
VIR_DELETE_ELEMENT(srv->clients, i, srv->nclients);
- if (virNetServerClientNeedAuthLocked(client))
- virNetServerTrackCompletedAuthLocked(srv);
+ /* Update server authentication tracking */
+ virNetServerSetClientAuthCompletedLocked(srv, client);
virObjectUnlock(client);
virNetServerCheckLimits(srv);
bool delayedClose;
virNetSocketPtr sock;
int auth;
+ bool auth_pending;
bool readonly;
#if WITH_GNUTLS
virNetTLSContextPtr tlsCtxt;
virNetServerClientNewInternal(unsigned long long id,
virNetSocketPtr sock,
int auth,
+ bool auth_pending,
#ifdef WITH_GNUTLS
virNetTLSContextPtr tls,
#endif
client->id = id;
client->sock = virObjectRef(sock);
client->auth = auth;
+ client->auth_pending = auth_pending;
client->readonly = readonly;
#ifdef WITH_GNUTLS
client->tlsCtxt = virObjectRef(tls);
{
virNetServerClientPtr client;
time_t now;
+ bool auth_pending = !virNetServerClientAuthMethodImpliesAuthenticated(auth);
VIR_DEBUG("sock=%p auth=%d tls=%p", sock, auth,
#ifdef WITH_GNUTLS
return NULL;
}
- if (!(client = virNetServerClientNewInternal(id, sock, auth,
+ if (!(client = virNetServerClientNewInternal(id, sock, auth, auth_pending,
#ifdef WITH_GNUTLS
tls,
#endif
virNetServerClientPtr client = NULL;
virNetSocketPtr sock;
int auth;
- bool readonly;
+ bool readonly, auth_pending;
unsigned int nrequests_max;
unsigned long long id;
long long timestamp;
_("Missing auth field in JSON state document"));
return NULL;
}
+
+ if (!virJSONValueObjectHasKey(object, "auth_pending")) {
+ auth_pending = !virNetServerClientAuthMethodImpliesAuthenticated(auth);
+ } else {
+ if (virJSONValueObjectGetBoolean(object, "auth_pending", &auth_pending) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Malformed auth_pending field in JSON state document"));
+ return NULL;
+ }
+
+ /* If the used authentication method implies that the new
+ * client is automatically authenticated, the authentication
+ * cannot be pending */
+ if (auth_pending && virNetServerClientAuthMethodImpliesAuthenticated(auth)) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Invalid auth_pending and auth combination in JSON state document"));
+ return NULL;
+ }
+ }
+
if (virJSONValueObjectGetBoolean(object, "readonly", &readonly) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Missing readonly field in JSON state document"));
if (!(client = virNetServerClientNewInternal(id,
sock,
auth,
+ auth_pending,
#ifdef WITH_GNUTLS
NULL,
#endif
if (virJSONValueObjectAppendNumberInt(object, "auth", client->auth) < 0)
goto error;
+ if (virJSONValueObjectAppendBoolean(object, "auth_pending", client->auth_pending) < 0)
+ goto error;
if (virJSONValueObjectAppendBoolean(object, "readonly", client->readonly) < 0)
goto error;
if (virJSONValueObjectAppendNumberUint(object, "nrequests_max", client->nrequests_max) < 0)
}
+/* The caller must hold the lock for @client */
+void
+virNetServerClientSetAuthPendingLocked(virNetServerClientPtr client,
+ bool auth_pending)
+{
+ client->auth_pending = auth_pending;
+}
+
+
+/* The caller must hold the lock for @client */
+bool
+virNetServerClientIsAuthPendingLocked(virNetServerClientPtr client)
+{
+ return client->auth_pending;
+}
+
+
static void
virNetServerClientKeepAliveDeadCB(void *opaque)
{