1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2025-03-07 17:28:15 +00:00

virNetServer: Introduce unauth clients counter

The counter gets incremented on each unauthenticated client added to the
server and decremented whenever the client authenticates.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
Michal Privoznik 2014-03-04 15:37:27 +01:00
parent 030cbd6302
commit 4015396b2c
3 changed files with 58 additions and 11 deletions

View File

@ -2619,7 +2619,7 @@ cleanup:
/*-------------------------------------------------------------*/ /*-------------------------------------------------------------*/
static int static int
remoteDispatchAuthList(virNetServerPtr server ATTRIBUTE_UNUSED, remoteDispatchAuthList(virNetServerPtr server,
virNetServerClientPtr client, virNetServerClientPtr client,
virNetMessagePtr msg ATTRIBUTE_UNUSED, virNetMessagePtr msg ATTRIBUTE_UNUSED,
virNetMessageErrorPtr rerr, virNetMessageErrorPtr rerr,
@ -2649,6 +2649,7 @@ remoteDispatchAuthList(virNetServerPtr server ATTRIBUTE_UNUSED,
goto cleanup; goto cleanup;
VIR_INFO("Bypass polkit auth for privileged client %s", ident); VIR_INFO("Bypass polkit auth for privileged client %s", ident);
virNetServerClientSetAuth(client, 0); virNetServerClientSetAuth(client, 0);
virNetServerTrackCompletedAuth(server);
auth = VIR_NET_SERVER_SERVICE_AUTH_NONE; auth = VIR_NET_SERVER_SERVICE_AUTH_NONE;
VIR_FREE(ident); VIR_FREE(ident);
} }
@ -2764,7 +2765,8 @@ authfail:
* Returns 0 if ok, -1 on error, -2 if rejected * Returns 0 if ok, -1 on error, -2 if rejected
*/ */
static int static int
remoteSASLFinish(virNetServerClientPtr client) remoteSASLFinish(virNetServerPtr server,
virNetServerClientPtr client)
{ {
const char *identity; const char *identity;
struct daemonClientPrivate *priv = virNetServerClientGetPrivateData(client); struct daemonClientPrivate *priv = virNetServerClientGetPrivateData(client);
@ -2789,6 +2791,7 @@ remoteSASLFinish(virNetServerClientPtr client)
return -2; return -2;
virNetServerClientSetAuth(client, 0); virNetServerClientSetAuth(client, 0);
virNetServerTrackCompletedAuth(server);
virNetServerClientSetSASLSession(client, priv->sasl); virNetServerClientSetSASLSession(client, priv->sasl);
VIR_DEBUG("Authentication successful %d", virNetServerClientGetFD(client)); VIR_DEBUG("Authentication successful %d", virNetServerClientGetFD(client));
@ -2810,7 +2813,7 @@ error:
* This starts the SASL authentication negotiation. * This starts the SASL authentication negotiation.
*/ */
static int static int
remoteDispatchAuthSaslStart(virNetServerPtr server ATTRIBUTE_UNUSED, remoteDispatchAuthSaslStart(virNetServerPtr server,
virNetServerClientPtr client, virNetServerClientPtr client,
virNetMessagePtr msg ATTRIBUTE_UNUSED, virNetMessagePtr msg ATTRIBUTE_UNUSED,
virNetMessageErrorPtr rerr, virNetMessageErrorPtr rerr,
@ -2868,7 +2871,7 @@ remoteDispatchAuthSaslStart(virNetServerPtr server ATTRIBUTE_UNUSED,
ret->complete = 0; ret->complete = 0;
} else { } else {
/* Check username whitelist ACL */ /* Check username whitelist ACL */
if ((err = remoteSASLFinish(client)) < 0) { if ((err = remoteSASLFinish(server, client)) < 0) {
if (err == -2) if (err == -2)
goto authdeny; goto authdeny;
else else
@ -2908,7 +2911,7 @@ error:
static int static int
remoteDispatchAuthSaslStep(virNetServerPtr server ATTRIBUTE_UNUSED, remoteDispatchAuthSaslStep(virNetServerPtr server,
virNetServerClientPtr client, virNetServerClientPtr client,
virNetMessagePtr msg ATTRIBUTE_UNUSED, virNetMessagePtr msg ATTRIBUTE_UNUSED,
virNetMessageErrorPtr rerr, virNetMessageErrorPtr rerr,
@ -2966,7 +2969,7 @@ remoteDispatchAuthSaslStep(virNetServerPtr server ATTRIBUTE_UNUSED,
ret->complete = 0; ret->complete = 0;
} else { } else {
/* Check username whitelist ACL */ /* Check username whitelist ACL */
if ((err = remoteSASLFinish(client)) < 0) { if ((err = remoteSASLFinish(server, client)) < 0) {
if (err == -2) if (err == -2)
goto authdeny; goto authdeny;
else else
@ -3051,7 +3054,7 @@ remoteDispatchAuthSaslStep(virNetServerPtr server ATTRIBUTE_UNUSED,
#if WITH_POLKIT1 #if WITH_POLKIT1
static int static int
remoteDispatchAuthPolkit(virNetServerPtr server ATTRIBUTE_UNUSED, remoteDispatchAuthPolkit(virNetServerPtr server,
virNetServerClientPtr client, virNetServerClientPtr client,
virNetMessagePtr msg ATTRIBUTE_UNUSED, virNetMessagePtr msg ATTRIBUTE_UNUSED,
virNetMessageErrorPtr rerr, virNetMessageErrorPtr rerr,
@ -3142,6 +3145,7 @@ remoteDispatchAuthPolkit(virNetServerPtr server ATTRIBUTE_UNUSED,
ret->complete = 1; ret->complete = 1;
virNetServerClientSetAuth(client, 0); virNetServerClientSetAuth(client, 0);
virNetServerTrackCompletedAuth(server);
virMutexUnlock(&priv->lock); virMutexUnlock(&priv->lock);
virCommandFree(cmd); virCommandFree(cmd);
VIR_FREE(pkout); VIR_FREE(pkout);
@ -3182,7 +3186,7 @@ authdeny:
} }
#elif WITH_POLKIT0 #elif WITH_POLKIT0
static int static int
remoteDispatchAuthPolkit(virNetServerPtr server ATTRIBUTE_UNUSED, remoteDispatchAuthPolkit(virNetServerPtr server,
virNetServerClientPtr client, virNetServerClientPtr client,
virNetMessagePtr msg ATTRIBUTE_UNUSED, virNetMessagePtr msg ATTRIBUTE_UNUSED,
virNetMessageErrorPtr rerr, virNetMessageErrorPtr rerr,
@ -3297,6 +3301,7 @@ remoteDispatchAuthPolkit(virNetServerPtr server ATTRIBUTE_UNUSED,
ret->complete = 1; ret->complete = 1;
virNetServerClientSetAuth(client, 0); virNetServerClientSetAuth(client, 0);
virNetServerTrackCompletedAuth(server);
virMutexUnlock(&priv->lock); virMutexUnlock(&priv->lock);
VIR_FREE(ident); VIR_FREE(ident);
return 0; return 0;

View File

@ -88,9 +88,10 @@ struct _virNetServer {
size_t nprograms; size_t nprograms;
virNetServerProgramPtr *programs; virNetServerProgramPtr *programs;
size_t nclients; size_t nclients; /* Current clients count */
size_t nclients_max; virNetServerClientPtr *clients; /* Clients */
virNetServerClientPtr *clients; size_t nclients_max; /* Max allowed clients count */
size_t nclients_unauth; /* Unauthenticated clients count */
int keepaliveInterval; int keepaliveInterval;
unsigned int keepaliveCount; unsigned int keepaliveCount;
@ -118,6 +119,8 @@ static virClassPtr virNetServerClass;
static void virNetServerDispose(void *obj); static void virNetServerDispose(void *obj);
static void virNetServerUpdateServicesLocked(virNetServerPtr srv, static void virNetServerUpdateServicesLocked(virNetServerPtr srv,
bool enabled); bool enabled);
static inline size_t virNetServerTrackPendingAuthLocked(virNetServerPtr srv);
static inline size_t virNetServerTrackCompletedAuthLocked(virNetServerPtr srv);
static int virNetServerOnceInit(void) static int virNetServerOnceInit(void)
{ {
@ -273,6 +276,9 @@ static int virNetServerAddClient(virNetServerPtr srv,
srv->clients[srv->nclients-1] = client; srv->clients[srv->nclients-1] = client;
virObjectRef(client); virObjectRef(client);
if (virNetServerClientNeedAuth(client))
virNetServerTrackPendingAuthLocked(srv);
if (srv->nclients == srv->nclients_max) { if (srv->nclients == srv->nclients_max) {
/* Temporarily stop accepting new clients */ /* Temporarily stop accepting new clients */
VIR_DEBUG("Temporarily suspending services due to max_clients"); VIR_DEBUG("Temporarily suspending services due to max_clients");
@ -1133,6 +1139,9 @@ void virNetServerRun(virNetServerPtr srv)
VIR_DELETE_ELEMENT(srv->clients, i, srv->nclients); VIR_DELETE_ELEMENT(srv->clients, i, srv->nclients);
if (virNetServerClientNeedAuth(client))
virNetServerTrackCompletedAuthLocked(srv);
/* Enable services if we can accept a new client. /* Enable services if we can accept a new client.
* The new client can be accepted if we are at the limit. */ * The new client can be accepted if we are at the limit. */
if (srv->nclients == srv->nclients_max - 1) { if (srv->nclients == srv->nclients_max - 1) {
@ -1229,3 +1238,33 @@ bool virNetServerKeepAliveRequired(virNetServerPtr srv)
virObjectUnlock(srv); virObjectUnlock(srv);
return required; return required;
} }
static inline size_t
virNetServerTrackPendingAuthLocked(virNetServerPtr srv)
{
return ++srv->nclients_unauth;
}
static inline size_t
virNetServerTrackCompletedAuthLocked(virNetServerPtr srv)
{
return --srv->nclients_unauth;
}
size_t virNetServerTrackPendingAuth(virNetServerPtr srv)
{
size_t ret;
virObjectLock(srv);
ret = virNetServerTrackPendingAuthLocked(srv);
virObjectUnlock(srv);
return ret;
}
size_t virNetServerTrackCompletedAuth(virNetServerPtr srv)
{
size_t ret;
virObjectLock(srv);
ret = virNetServerTrackCompletedAuthLocked(srv);
virObjectUnlock(srv);
return ret;
}

View File

@ -97,4 +97,7 @@ void virNetServerClose(virNetServerPtr srv);
bool virNetServerKeepAliveRequired(virNetServerPtr srv); bool virNetServerKeepAliveRequired(virNetServerPtr srv);
size_t virNetServerTrackPendingAuth(virNetServerPtr srv);
size_t virNetServerTrackCompletedAuth(virNetServerPtr srv);
#endif #endif