const char *virNetSASLSessionGetIdentity(virNetSASLSessionPtr sasl) { const void *val = NULL; int err; virMutexLock(&sasl->lock); err = sasl_getprop(sasl->conn, SASL_USERNAME, &val); if (err != SASL_OK) { virNetError(VIR_ERR_AUTH_FAILED, _("cannot query SASL username on connection %d (%s)"), err, sasl_errstring(err, NULL, NULL)); val = NULL; goto cleanup; } if (val == NULL) { virNetError(VIR_ERR_AUTH_FAILED, _("no client username was found")); goto cleanup; } VIR_DEBUG("SASL client username %s", (const char *)val); cleanup: virMutexUnlock(&sasl->lock); return (const char*)val; }
virNetSASLContextPtr virNetSASLContextNewClient(void) { virNetSASLContextPtr ctxt; int err; err = sasl_client_init(NULL); if (err != SASL_OK) { virNetError(VIR_ERR_AUTH_FAILED, _("failed to initialize SASL library: %d (%s)"), err, sasl_errstring(err, NULL, NULL)); return NULL; } if (VIR_ALLOC(ctxt) < 0) { virReportOOMError(); return NULL; } if (virMutexInit(&ctxt->lock) < 0) { virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("Failed to initialized mutex")); VIR_FREE(ctxt); return NULL; } ctxt->refs = 1; return ctxt; }
int virNetMessageEncodeNumFDs(virNetMessagePtr msg) { XDR xdr; unsigned int numFDs = msg->nfds; int ret = -1; xdrmem_create(&xdr, msg->buffer + msg->bufferOffset, msg->bufferLength - msg->bufferOffset, XDR_ENCODE); if (numFDs > VIR_NET_MESSAGE_NUM_FDS_MAX) { virNetError(VIR_ERR_RPC, _("Too many FDs to send %d, expected %d maximum"), numFDs, VIR_NET_MESSAGE_NUM_FDS_MAX); goto cleanup; } if (!xdr_u_int(&xdr, &numFDs)) { virNetError(VIR_ERR_RPC, "%s", _("Unable to encode number of FDs")); goto cleanup; } msg->bufferOffset += xdr_getpos(&xdr); VIR_DEBUG("Send %zu FDs to peer", msg->nfds); ret = 0; cleanup: xdr_destroy(&xdr); return ret; }
int virNetMessageEncodePayloadRaw(virNetMessagePtr msg, const char *data, size_t len) { XDR xdr; unsigned int msglen; if ((msg->bufferLength - msg->bufferOffset) < len) { virNetError(VIR_ERR_RPC, _("Stream data too long to send (%zu bytes needed, %zu bytes available)"), len, (msg->bufferLength - msg->bufferOffset)); return -1; } memcpy(msg->buffer + msg->bufferOffset, data, len); msg->bufferOffset += len; /* Re-encode the length word. */ VIR_DEBUG("Encode length as %zu", msg->bufferOffset); xdrmem_create(&xdr, msg->buffer, VIR_NET_MESSAGE_HEADER_XDR_LEN, XDR_ENCODE); msglen = msg->bufferOffset; if (!xdr_u_int(&xdr, &msglen)) { virNetError(VIR_ERR_RPC, "%s", _("Unable to encode message length")); goto error; } xdr_destroy(&xdr); msg->bufferLength = msg->bufferOffset; msg->bufferOffset = 0; return 0; error: xdr_destroy(&xdr); return -1; }
virNetSASLContextPtr virNetSASLContextNewServer(const char *const*usernameWhitelist) { virNetSASLContextPtr ctxt; int err; err = sasl_server_init(NULL, "libvirt"); if (err != SASL_OK) { virNetError(VIR_ERR_AUTH_FAILED, _("failed to initialize SASL library: %d (%s)"), err, sasl_errstring(err, NULL, NULL)); return NULL; } if (VIR_ALLOC(ctxt) < 0) { virReportOOMError(); return NULL; } if (virMutexInit(&ctxt->lock) < 0) { virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("Failed to initialized mutex")); VIR_FREE(ctxt); return NULL; } ctxt->usernameWhitelist = usernameWhitelist; ctxt->refs = 1; return ctxt; }
int virNetClientSend(virNetClientPtr client, virNetMessagePtr msg, bool expectReply) { virNetClientCallPtr call; int ret = -1; PROBE(RPC_CLIENT_MSG_TX_QUEUE, "client=%p len=%zu prog=%u vers=%u proc=%u type=%u status=%u serial=%u", client, msg->bufferLength, msg->header.prog, msg->header.vers, msg->header.proc, msg->header.type, msg->header.status, msg->header.serial); if (expectReply && (msg->bufferLength != 0) && (msg->header.status == VIR_NET_CONTINUE)) { virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("Attempt to send an asynchronous message with a synchronous reply")); return -1; } if (VIR_ALLOC(call) < 0) { virReportOOMError(); return -1; } virNetClientLock(client); if (virCondInit(&call->cond) < 0) { virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("cannot initialize condition variable")); goto cleanup; } msg->donefds = 0; if (msg->bufferLength) call->mode = VIR_NET_CLIENT_MODE_WAIT_TX; else call->mode = VIR_NET_CLIENT_MODE_WAIT_RX; call->msg = msg; call->expectReply = expectReply; ret = virNetClientIO(client, call); cleanup: ignore_value(virCondDestroy(&call->cond)); VIR_FREE(call); virNetClientUnlock(client); return ret; }
/* * @msg: the outgoing message, whose header to encode * * Encodes the length word and header of the message, setting the * message offset ready to encode the payload. Leaves space * for the length field later. Upon return bufferLength will * refer to the total available space for message, while * bufferOffset will refer to current space used by header * * returns 0 if successfully encoded, -1 upon fatal error */ int virNetMessageEncodeHeader(virNetMessagePtr msg) { XDR xdr; int ret = -1; unsigned int len = 0; msg->bufferLength = VIR_NET_MESSAGE_MAX + VIR_NET_MESSAGE_LEN_MAX; if (VIR_REALLOC_N(msg->buffer, msg->bufferLength) < 0) { virReportOOMError(); goto cleanup; } msg->bufferOffset = 0; /* Format the header. */ xdrmem_create(&xdr, msg->buffer, msg->bufferLength, XDR_ENCODE); /* The real value is filled in shortly */ if (!xdr_u_int(&xdr, &len)) { virNetError(VIR_ERR_RPC, "%s", _("Unable to encode message length")); goto cleanup; } if (!xdr_virNetMessageHeader(&xdr, &msg->header)) { virNetError(VIR_ERR_RPC, "%s", _("Unable to encode message header")); goto cleanup; } len = xdr_getpos(&xdr); xdr_setpos(&xdr, 0); /* Fill in current length - may be re-written later * if a payload is added */ if (!xdr_u_int(&xdr, &len)) { virNetError(VIR_ERR_RPC, "%s", _("Unable to re-encode message length")); goto cleanup; } msg->bufferOffset += len; ret = 0; cleanup: xdr_destroy(&xdr); return ret; }
int virNetMessageDecodeLength(virNetMessagePtr msg) { XDR xdr; unsigned int len; int ret = -1; xdrmem_create(&xdr, msg->buffer, msg->bufferLength, XDR_DECODE); if (!xdr_u_int(&xdr, &len)) { virNetError(VIR_ERR_RPC, "%s", _("Unable to decode message length")); goto cleanup; } msg->bufferOffset = xdr_getpos(&xdr); if (len < VIR_NET_MESSAGE_LEN_MAX) { virNetError(VIR_ERR_RPC, _("packet %d bytes received from server too small, want %d"), len, VIR_NET_MESSAGE_LEN_MAX); goto cleanup; } /* Length includes length word - adjust to real length to read. */ len -= VIR_NET_MESSAGE_LEN_MAX; if (len > VIR_NET_MESSAGE_MAX) { virNetError(VIR_ERR_RPC, _("packet %d bytes received from server too large, want %d"), len, VIR_NET_MESSAGE_MAX); goto cleanup; } /* Extend our declared buffer length and carry on reading the header + payload */ msg->bufferLength += len; if (VIR_REALLOC_N(msg->buffer, msg->bufferLength) < 0) { virReportOOMError(); goto cleanup; } VIR_DEBUG("Got length, now need %zu total (%u more)", msg->bufferLength, len); ret = 0; cleanup: xdr_destroy(&xdr); return ret; }
int virNetMessageDecodePayload(virNetMessagePtr msg, xdrproc_t filter, void *data) { XDR xdr; /* Deserialise payload of the message. This assumes that * virNetMessageDecodeHeader has already been run, so * just start from after that data */ xdrmem_create(&xdr, msg->buffer + msg->bufferOffset, msg->bufferLength - msg->bufferOffset, XDR_DECODE); if (!(*filter)(&xdr, data)) { virNetError(VIR_ERR_RPC, "%s", _("Unable to decode message payload")); goto error; } /* Get the length stored in buffer. */ msg->bufferLength += xdr_getpos(&xdr); xdr_destroy(&xdr); return 0; error: xdr_destroy(&xdr); return -1; }
/* * @msg: the complete incoming message, whose header to decode * * Decodes the header part of the message, but does not * validate the decoded fields in the header. It expects * bufferLength to refer to length of the data packet. Upon * return bufferOffset will refer to the amount of the packet * consumed by decoding of the header. * * returns 0 if successfully decoded, -1 upon fatal error */ int virNetMessageDecodeHeader(virNetMessagePtr msg) { XDR xdr; int ret = -1; msg->bufferOffset = VIR_NET_MESSAGE_LEN_MAX; /* Parse the header. */ xdrmem_create(&xdr, msg->buffer + msg->bufferOffset, msg->bufferLength - msg->bufferOffset, XDR_DECODE); if (!xdr_virNetMessageHeader(&xdr, &msg->header)) { virNetError(VIR_ERR_RPC, "%s", _("Unable to decode message header")); goto cleanup; } msg->bufferOffset += xdr_getpos(&xdr); ret = 0; cleanup: xdr_destroy(&xdr); return ret; }
int virNetClientStreamEventRemoveCallback(virNetClientStreamPtr st) { int ret = -1; virMutexUnlock(&st->lock); if (!st->cb) { virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("no stream callback registered")); goto cleanup; } if (!st->cbDispatch && st->cbFree) (st->cbFree)(st->cbOpaque); st->cb = NULL; st->cbOpaque = NULL; st->cbFree = NULL; st->cbEvents = 0; virEventRemoveTimeout(st->cbTimer); ret = 0; cleanup: virMutexUnlock(&st->lock); return ret; }
int virNetSASLSessionSecProps(virNetSASLSessionPtr sasl, int minSSF, int maxSSF, bool allowAnonymous) { sasl_security_properties_t secprops; int err; int ret = -1; VIR_DEBUG("minSSF=%d maxSSF=%d allowAnonymous=%d maxbufsize=%zu", minSSF, maxSSF, allowAnonymous, sasl->maxbufsize); virMutexLock(&sasl->lock); memset(&secprops, 0, sizeof secprops); secprops.min_ssf = minSSF; secprops.max_ssf = maxSSF; secprops.maxbufsize = sasl->maxbufsize; secprops.security_flags = allowAnonymous ? 0 : SASL_SEC_NOANONYMOUS | SASL_SEC_NOPLAINTEXT; err = sasl_setprop(sasl->conn, SASL_SEC_PROPS, &secprops); if (err != SASL_OK) { virNetError(VIR_ERR_INTERNAL_ERROR, _("cannot set security props %d (%s)"), err, sasl_errstring(err, NULL, NULL)); goto cleanup; } ret = 0; cleanup: virMutexUnlock(&sasl->lock); return ret; }
virNetClientStreamPtr virNetClientStreamNew(virNetClientProgramPtr prog, int proc, unsigned serial) { virNetClientStreamPtr st; if (VIR_ALLOC(st) < 0) { virReportOOMError(); return NULL; } st->refs = 1; st->prog = prog; st->proc = proc; st->serial = serial; if (virMutexInit(&st->lock) < 0) { virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("cannot initialize mutex")); VIR_FREE(st); return NULL; } virNetClientProgramRef(prog); return st; }
char *virNetSASLSessionListMechanisms(virNetSASLSessionPtr sasl) { const char *mechlist; char *ret = NULL; int err; virMutexLock(&sasl->lock); err = sasl_listmech(sasl->conn, NULL, /* Don't need to set user */ "", /* Prefix */ ",", /* Separator */ "", /* Suffix */ &mechlist, NULL, NULL); if (err != SASL_OK) { virNetError(VIR_ERR_INTERNAL_ERROR, _("cannot list SASL mechanisms %d (%s)"), err, sasl_errdetail(sasl->conn)); goto cleanup; } if (!(ret = strdup(mechlist))) { virReportOOMError(); goto cleanup; } cleanup: virMutexUnlock(&sasl->lock); return ret; }
static int virNetClientCallDispatch(virNetClientPtr client) { PROBE(RPC_CLIENT_MSG_RX, "client=%p len=%zu prog=%u vers=%u proc=%u type=%u status=%u serial=%u", client, client->msg.bufferLength, client->msg.header.prog, client->msg.header.vers, client->msg.header.proc, client->msg.header.type, client->msg.header.status, client->msg.header.serial); switch (client->msg.header.type) { case VIR_NET_REPLY: /* Normal RPC replies */ case VIR_NET_REPLY_WITH_FDS: /* Normal RPC replies with FDs */ return virNetClientCallDispatchReply(client); case VIR_NET_MESSAGE: /* Async notifications */ return virNetClientCallDispatchMessage(client); case VIR_NET_STREAM: /* Stream protocol */ return virNetClientCallDispatchStream(client); default: virNetError(VIR_ERR_RPC, _("got unexpected RPC call prog %d vers %d proc %d type %d"), client->msg.header.prog, client->msg.header.vers, client->msg.header.proc, client->msg.header.type); return -1; } }
static int virNetClientCallDispatchReply(virNetClientPtr client) { virNetClientCallPtr thecall; /* Ok, definitely got an RPC reply now find out who's been waiting for it */ thecall = client->waitDispatch; while (thecall && !(thecall->msg->header.prog == client->msg.header.prog && thecall->msg->header.vers == client->msg.header.vers && thecall->msg->header.serial == client->msg.header.serial)) thecall = thecall->next; if (!thecall) { virNetError(VIR_ERR_RPC, _("no call waiting for reply with prog %d vers %d serial %d"), client->msg.header.prog, client->msg.header.vers, client->msg.header.serial); return -1; } memcpy(thecall->msg->buffer, client->msg.buffer, sizeof(client->msg.buffer)); memcpy(&thecall->msg->header, &client->msg.header, sizeof(client->msg.header)); thecall->msg->bufferLength = client->msg.bufferLength; thecall->msg->bufferOffset = client->msg.bufferOffset; thecall->mode = VIR_NET_CLIENT_MODE_COMPLETE; return 0; }
int virNetMessageDupFD(virNetMessagePtr msg, size_t slot) { int fd; if (slot >= msg->nfds) { virNetError(VIR_ERR_INTERNAL_ERROR, _("No FD available at slot %zu"), slot); return -1; } if ((fd = dup(msg->fds[slot])) < 0) { virReportSystemError(errno, _("Unable to duplicate FD %d"), msg->fds[slot]); return -1; } if (virSetInherit(fd, false) < 0) { VIR_FORCE_CLOSE(fd); virReportSystemError(errno, _("Cannot set close-on-exec %d"), fd); return -1; } return fd; }
virNetSASLSessionPtr virNetSASLSessionNewClient(virNetSASLContextPtr ctxt ATTRIBUTE_UNUSED, const char *service, const char *hostname, const char *localAddr, const char *remoteAddr, const sasl_callback_t *cbs) { virNetSASLSessionPtr sasl = NULL; int err; if (VIR_ALLOC(sasl) < 0) { virReportOOMError(); goto cleanup; } if (virMutexInit(&sasl->lock) < 0) { virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("Failed to initialized mutex")); VIR_FREE(sasl); return NULL; } sasl->refs = 1; /* Arbitrary size for amount of data we can encode in a single block */ sasl->maxbufsize = 1 << 16; err = sasl_client_new(service, hostname, localAddr, remoteAddr, cbs, SASL_SUCCESS_DATA, &sasl->conn); if (err != SASL_OK) { virNetError(VIR_ERR_AUTH_FAILED, _("Failed to create SASL client context: %d (%s)"), err, sasl_errstring(err, NULL, NULL)); goto cleanup; } return sasl; cleanup: virNetSASLSessionFree(sasl); return NULL; }
int virNetSASLContextCheckIdentity(virNetSASLContextPtr ctxt, const char *identity) { const char *const*wildcards; int ret = -1; virMutexLock(&ctxt->lock); /* If the list is not set, allow any DN. */ wildcards = ctxt->usernameWhitelist; if (!wildcards) { ret = 1; /* No ACL, allow all */ goto cleanup; } while (*wildcards) { int rv = fnmatch (*wildcards, identity, 0); if (rv == 0) { ret = 1; goto cleanup; /* Succesful match */ } if (rv != FNM_NOMATCH) { virNetError(VIR_ERR_INTERNAL_ERROR, _("Malformed TLS whitelist regular expression '%s'"), *wildcards); goto cleanup; } wildcards++; } /* Denied */ VIR_ERROR(_("SASL client %s not allowed in whitelist"), identity); /* This is the most common error: make it informative. */ virNetError(VIR_ERR_SYSTEM_ERROR, "%s", _("Client's username is not on the list of allowed clients")); ret = 0; cleanup: virMutexUnlock(&ctxt->lock); return ret; }
int virNetMessageEncodePayload(virNetMessagePtr msg, xdrproc_t filter, void *data) { XDR xdr; unsigned int msglen; /* Serialise payload of the message. This assumes that * virNetMessageEncodeHeader has already been run, so * just appends to that data */ xdrmem_create(&xdr, msg->buffer + msg->bufferOffset, msg->bufferLength - msg->bufferOffset, XDR_ENCODE); if (!(*filter)(&xdr, data)) { virNetError(VIR_ERR_RPC, "%s", _("Unable to encode message payload")); goto error; } /* Get the length stored in buffer. */ msg->bufferOffset += xdr_getpos(&xdr); xdr_destroy(&xdr); /* Re-encode the length word. */ VIR_DEBUG("Encode length as %zu", msg->bufferOffset); xdrmem_create(&xdr, msg->buffer, VIR_NET_MESSAGE_HEADER_XDR_LEN, XDR_ENCODE); msglen = msg->bufferOffset; if (!xdr_u_int(&xdr, &msglen)) { virNetError(VIR_ERR_RPC, "%s", _("Unable to encode message length")); goto error; } xdr_destroy(&xdr); msg->bufferLength = msg->bufferOffset; msg->bufferOffset = 0; return 0; error: xdr_destroy(&xdr); return -1; }
int virNetMessageDecodeNumFDs(virNetMessagePtr msg) { XDR xdr; unsigned int numFDs; int ret = -1; size_t i; xdrmem_create(&xdr, msg->buffer + msg->bufferOffset, msg->bufferLength - msg->bufferOffset, XDR_DECODE); if (!xdr_u_int(&xdr, &numFDs)) { virNetError(VIR_ERR_RPC, "%s", _("Unable to decode number of FDs")); goto cleanup; } msg->bufferOffset += xdr_getpos(&xdr); if (numFDs > VIR_NET_MESSAGE_NUM_FDS_MAX) { virNetError(VIR_ERR_RPC, _("Received too many FDs %d, expected %d maximum"), numFDs, VIR_NET_MESSAGE_NUM_FDS_MAX); goto cleanup; } msg->nfds = numFDs; if (VIR_ALLOC_N(msg->fds, msg->nfds) < 0) { virReportOOMError(); goto cleanup; } for (i = 0 ; i < msg->nfds ; i++) msg->fds[i] = -1; VIR_DEBUG("Got %zu FDs from peer", msg->nfds); ret = 0; cleanup: xdr_destroy(&xdr); return ret; }
int virNetSASLSessionClientStep(virNetSASLSessionPtr sasl, const char *serverin, size_t serverinlen, sasl_interact_t **prompt_need, const char **clientout, size_t *clientoutlen) { unsigned inlen = serverinlen; unsigned outlen = 0; int err; int ret = -1; VIR_DEBUG("sasl=%p serverin=%s serverinlen=%zu prompt_need=%p clientout=%p clientoutlen=%p", sasl, serverin, serverinlen, prompt_need, clientout, clientoutlen); virMutexLock(&sasl->lock); err = sasl_client_step(sasl->conn, serverin, inlen, prompt_need, clientout, &outlen); *clientoutlen = outlen; switch (err) { case SASL_OK: if (virNetSASLSessionUpdateBufSize(sasl) < 0) goto cleanup; ret = VIR_NET_SASL_COMPLETE; break; case SASL_CONTINUE: ret = VIR_NET_SASL_CONTINUE; break; case SASL_INTERACT: ret = VIR_NET_SASL_INTERACT; break; default: virNetError(VIR_ERR_AUTH_FAILED, _("Failed to step SASL negotiation: %d (%s)"), err, sasl_errdetail(sasl->conn)); break; } cleanup: virMutexUnlock(&sasl->lock); return ret; }
int virNetSASLSessionServerStart(virNetSASLSessionPtr sasl, const char *mechname, const char *clientin, size_t clientinlen, const char **serverout, size_t *serveroutlen) { unsigned inlen = clientinlen; unsigned outlen = 0; int err; int ret = -1; virMutexLock(&sasl->lock); err = sasl_server_start(sasl->conn, mechname, clientin, inlen, serverout, &outlen); *serveroutlen = outlen; switch (err) { case SASL_OK: if (virNetSASLSessionUpdateBufSize(sasl) < 0) goto cleanup; ret = VIR_NET_SASL_COMPLETE; break; case SASL_CONTINUE: ret = VIR_NET_SASL_CONTINUE; break; case SASL_INTERACT: ret = VIR_NET_SASL_INTERACT; break; default: virNetError(VIR_ERR_AUTH_FAILED, _("Failed to start SASL negotiation: %d (%s)"), err, sasl_errdetail(sasl->conn)); break; } cleanup: virMutexUnlock(&sasl->lock); return ret; }
int virNetServerProgramUnknownError(virNetServerClientPtr client, virNetMessagePtr msg, virNetMessageHeaderPtr req) { virNetMessageError rerr; virNetError(VIR_ERR_RPC, _("Cannot find program %d version %d"), req->prog, req->vers); memset(&rerr, 0, sizeof(rerr)); return virNetServerProgramSendError(req->prog, req->vers, client, msg, &rerr, req->proc, VIR_NET_REPLY, req->serial); }
static int virNetServerDispatchNewClient(virNetServerServicePtr svc ATTRIBUTE_UNUSED, virNetServerClientPtr client, void *opaque) { virNetServerPtr srv = opaque; virNetServerLock(srv); if (srv->nclients >= srv->nclients_max) { virNetError(VIR_ERR_RPC, _("Too many active clients (%zu), dropping connection from %s"), srv->nclients_max, virNetServerClientRemoteAddrString(client)); goto error; } if (virNetServerClientInit(client) < 0) goto error; if (srv->clientInitHook && srv->clientInitHook(srv, client) < 0) goto error; if (VIR_EXPAND_N(srv->clients, srv->nclients, 1) < 0) { virReportOOMError(); goto error; } srv->clients[srv->nclients-1] = client; virNetServerClientRef(client); virNetServerClientSetDispatcher(client, virNetServerDispatchNewMessage, srv); virNetServerClientInitKeepAlive(client, srv->keepaliveInterval, srv->keepaliveCount); virNetServerUnlock(srv); return 0; error: virNetServerUnlock(srv); return -1; }
static int virNetSASLSessionUpdateBufSize(virNetSASLSessionPtr sasl) { union { unsigned *maxbufsize; const void *ptr; } u; int err; err = sasl_getprop(sasl->conn, SASL_MAXOUTBUF, &u.ptr); if (err != SASL_OK) { virNetError(VIR_ERR_INTERNAL_ERROR, _("cannot get security props %d (%s)"), err, sasl_errstring(err, NULL, NULL)); return -1; } VIR_DEBUG("Negotiated bufsize is %u vs requested size %zu", *u.maxbufsize, sasl->maxbufsize); sasl->maxbufsize = *u.maxbufsize; return 0; }
int virNetSASLSessionGetKeySize(virNetSASLSessionPtr sasl) { int err; int ssf; const void *val; virMutexLock(&sasl->lock); err = sasl_getprop(sasl->conn, SASL_SSF, &val); if (err != SASL_OK) { virNetError(VIR_ERR_AUTH_FAILED, _("cannot query SASL ssf on connection %d (%s)"), err, sasl_errstring(err, NULL, NULL)); ssf = -1; goto cleanup; } ssf = *(const int *)val; cleanup: virMutexUnlock(&sasl->lock); return ssf; }
int virNetSASLSessionExtKeySize(virNetSASLSessionPtr sasl, int ssf) { int err; int ret = -1; virMutexLock(&sasl->lock); err = sasl_setprop(sasl->conn, SASL_SSF_EXTERNAL, &ssf); if (err != SASL_OK) { virNetError(VIR_ERR_INTERNAL_ERROR, _("cannot set external SSF %d (%s)"), err, sasl_errstring(err, NULL, NULL)); goto cleanup; } ret = 0; cleanup: virMutexUnlock(&sasl->lock); return ret; }
int virNetClientStreamEventUpdateCallback(virNetClientStreamPtr st, int events) { int ret = -1; virMutexLock(&st->lock); if (!st->cb) { virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("no stream callback registered")); goto cleanup; } st->cbEvents = events; virNetClientStreamEventTimerUpdate(st); ret = 0; cleanup: virMutexUnlock(&st->lock); return ret; }
ssize_t virNetSASLSessionEncode(virNetSASLSessionPtr sasl, const char *input, size_t inputLen, const char **output, size_t *outputlen) { unsigned inlen = inputLen; unsigned outlen = 0; int err; ssize_t ret = -1; virMutexLock(&sasl->lock); if (inputLen > sasl->maxbufsize) { virReportSystemError(EINVAL, _("SASL data length %zu too long, max %zu"), inputLen, sasl->maxbufsize); goto cleanup; } err = sasl_encode(sasl->conn, input, inlen, output, &outlen); *outputlen = outlen; if (err != SASL_OK) { virNetError(VIR_ERR_INTERNAL_ERROR, _("failed to encode SASL data: %d (%s)"), err, sasl_errstring(err, NULL, NULL)); goto cleanup; } ret = 0; cleanup: virMutexUnlock(&sasl->lock); return ret; }