mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice
synced 2026-01-06 19:05:21 +00:00
red-stream: WebDAV doesn't work when SASL is active
When SASL is active, if a read request is made and SASL buffer contains some data (but not enough to fulfill the request), upon return the taken data from the buffer is not accounted for and hence part of the message gets discarded. red_stream_sasl_read function takes available data from sasl buffer and returns if it's enough. If it's not, nbyte is decremented and buf pointer is incremented to account for the taken data (if any). Then it tries to get more data from the socket and decode it. Suppose there was some data in the sasl buffer, but not enough. Then the socket is not readable (EAGAIN, EINTR, whatever) or the new data isn't enough for sasl_decode (hence decodedlen == 0). In both cases the function returns as if no data was read, but it took some data from sasl buffer. This data is lost and from this point on the communication ceases on the channel (eventually new data is read, but messages are corrupt without the parts previously discarded). On the other hand, if some data is read from sasl buffer and everything else works fine, the output buffer contains all the data, but the count returned only inform the caller about the newly read data (which causes the similar effect of discarding part of the message). Fixes: https://gitlab.freedesktop.org/spice/spice/-/issues/40 Acked-by: Frediano Ziglio <fziglio@redhat.com>
This commit is contained in:
parent
21f9d25aa8
commit
15b1e2a3bb
1
AUTHORS
1
AUTHORS
@ -42,6 +42,7 @@ Patches also contributed by
|
||||
Fabiano Fidêncio <fabiano@fidencio.org>
|
||||
Francois Gouget <fgouget@codeweavers.com>
|
||||
Gal Hammer <ghammer@redhat.com>
|
||||
Gilmar Santos Jr <jgasjr@gmail.com>
|
||||
Hans de Goede <hdegoede@redhat.com>
|
||||
Javier Celaya <javier.celaya@flexvm.es>
|
||||
Jeremy White <jwhite@codeweavers.com>
|
||||
|
||||
@ -707,20 +707,20 @@ static ssize_t red_stream_sasl_read(RedStream *s, uint8_t *buf, size_t nbyte)
|
||||
const char *decoded;
|
||||
unsigned int decodedlen;
|
||||
int err;
|
||||
int n;
|
||||
int n, offset;
|
||||
|
||||
n = spice_buffer_copy(&s->priv->sasl.inbuffer, buf, nbyte);
|
||||
if (n > 0) {
|
||||
spice_buffer_remove(&s->priv->sasl.inbuffer, n);
|
||||
if (n == nbyte)
|
||||
return n;
|
||||
nbyte -= n;
|
||||
buf += n;
|
||||
offset = spice_buffer_copy(&s->priv->sasl.inbuffer, buf, nbyte);
|
||||
if (offset > 0) {
|
||||
spice_buffer_remove(&s->priv->sasl.inbuffer, offset);
|
||||
if (offset == nbyte)
|
||||
return offset;
|
||||
nbyte -= offset;
|
||||
buf += offset;
|
||||
}
|
||||
|
||||
n = s->priv->read(s, encoded, sizeof(encoded));
|
||||
if (n <= 0) {
|
||||
return n;
|
||||
return offset > 0 ? offset : n;
|
||||
}
|
||||
|
||||
err = sasl_decode(s->priv->sasl.conn,
|
||||
@ -729,18 +729,18 @@ static ssize_t red_stream_sasl_read(RedStream *s, uint8_t *buf, size_t nbyte)
|
||||
if (err != SASL_OK) {
|
||||
spice_warning("sasl_decode error: %d", err);
|
||||
errno = EIO;
|
||||
return -1;
|
||||
return offset > 0 ? offset : -1;
|
||||
}
|
||||
|
||||
if (decodedlen == 0) {
|
||||
errno = EAGAIN;
|
||||
return -1;
|
||||
return offset > 0 ? offset : -1;
|
||||
}
|
||||
|
||||
n = MIN(nbyte, decodedlen);
|
||||
memcpy(buf, decoded, n);
|
||||
spice_buffer_append(&s->priv->sasl.inbuffer, decoded + n, decodedlen - n);
|
||||
return n;
|
||||
return offset + n;
|
||||
}
|
||||
|
||||
static char *addr_to_string(const char *format,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user