From: Erlon Cruz <erlon.cruz@xxxxxxxxxxxxxxxxxx> Signed-off-by: Erlon R. Cruz <erlon.cruz@xxxxxxxxxxxxxxxxxx> Signed-off-by: Fabiano Fidêncio <Fabiano.Fidêncio@xxxxxxxxxxxxxxxxxxxxx> Signed-off-by: Rafael F. Santos <Rafael.Santos@xxxxxxxxxxxxxxxxxxxxx> --- server/reds.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 files changed, 69 insertions(+), 13 deletions(-) diff --git a/server/reds.c b/server/reds.c index e3ea154..9df6e2d 100644 --- a/server/reds.c +++ b/server/reds.c @@ -36,6 +36,7 @@ #include <errno.h> #include <ctype.h> #include <stdbool.h> +#include <endian.h> #include <openssl/bio.h> #include <openssl/pem.h> @@ -1216,6 +1217,23 @@ static void reds_channel_init_auth_caps(RedLinkInfo *link, RedChannel *channel) red_channel_set_common_cap(channel, SPICE_COMMON_CAP_PROTOCOL_AUTH_SELECTION); } +#define WORD32_MASK 0x03 +static inline void buf_swap_htole32(void *buf, size_t len){ + + uint32_t *pos = buf; + + if(WORD32_MASK&len){ + printf("error swapping unaligned 32 bits word: len %d\n",(int)len); + exit(0); + } + + while(len > 0){ + *pos = htole32(*pos); + pos++; + len -= 4; + } +} + static int reds_send_link_ack(RedLinkInfo *link) { SpiceLinkHeader header; @@ -1224,12 +1242,12 @@ static int reds_send_link_ack(RedLinkInfo *link) RedChannelCapabilities *channel_caps; BUF_MEM *bmBuf; BIO *bio; - int ret = FALSE; + int ret = FALSE, *commom_caps = -1, *caps = -1; header.magic = SPICE_MAGIC; header.size = sizeof(ack); - header.major_version = SPICE_VERSION_MAJOR; - header.minor_version = SPICE_VERSION_MINOR; + header.major_version = htole32(SPICE_VERSION_MAJOR); + header.minor_version = htole32(SPICE_VERSION_MINOR); ack.error = SPICE_LINK_ERR_OK; @@ -1243,10 +1261,12 @@ static int reds_send_link_ack(RedLinkInfo *link) reds_channel_init_auth_caps(link, channel); /* make sure common caps are set */ channel_caps = &channel->local_caps; - ack.num_common_caps = channel_caps->num_common_caps; - ack.num_channel_caps = channel_caps->num_caps; - header.size += (ack.num_common_caps + ack.num_channel_caps) * sizeof(uint32_t); - ack.caps_offset = sizeof(SpiceLinkReply); + ack.num_common_caps = htole32(channel_caps->num_common_caps); + ack.num_channel_caps = htole32(channel_caps->num_caps); + header.size += (channel_caps->num_common_caps + channel_caps->num_caps) * sizeof(uint32_t); + ack.caps_offset = htole32(sizeof(SpiceLinkReply)); + + header.size = htole32(header.size); if (!(link->tiTicketing.rsa = RSA_new())) { spice_warning("RSA nes failed"); @@ -1264,8 +1284,20 @@ static int reds_send_link_ack(RedLinkInfo *link) i2d_RSA_PUBKEY_bio(bio, link->tiTicketing.rsa); BIO_get_mem_ptr(bio, &bmBuf); + memcpy(ack.pub_key, bmBuf->data, sizeof(ack.pub_key)); + commom_caps = spice_memdup(channel_caps->common_caps, + channel_caps->num_common_caps * sizeof(uint32_t)); + buf_swap_htole32(commom_caps, + channel_caps->num_common_caps * sizeof(uint32_t)); + + caps = spice_memdup(channel_caps->caps, + channel_caps->num_caps * sizeof(uint32_t)); + + buf_swap_htole32(commom_caps, + channel_caps->num_caps * sizeof(uint32_t)); + if (!sync_write(link->stream, &header, sizeof(header))) goto end; if (!sync_write(link->stream, &ack, sizeof(ack))) @@ -1275,6 +1307,9 @@ static int reds_send_link_ack(RedLinkInfo *link) if (!sync_write(link->stream, channel_caps->caps, channel_caps->num_caps * sizeof(uint32_t))) goto end; + free(commom_caps); + free(caps); + ret = TRUE; end: @@ -1288,11 +1323,12 @@ static int reds_send_link_error(RedLinkInfo *link, uint32_t error) SpiceLinkReply reply; header.magic = SPICE_MAGIC; - header.size = sizeof(reply); - header.major_version = SPICE_VERSION_MAJOR; - header.minor_version = SPICE_VERSION_MINOR; + header.size = htole32(sizeof(reply)); + header.major_version = htole32(SPICE_VERSION_MAJOR); + header.minor_version = htole32(SPICE_VERSION_MINOR); memset(&reply, 0, sizeof(reply)); - reply.error = error; + reply.error = htole32(error); + return sync_write(link->stream, &header, sizeof(header)) && sync_write(link->stream, &reply, sizeof(reply)); } @@ -1315,7 +1351,9 @@ static void reds_info_new_channel(RedLinkInfo *link, int connection_id) static void reds_send_link_result(RedLinkInfo *link, uint32_t error) { - sync_write(link->stream, &error, sizeof(error)); + uint32_t serror; + serror = htole32(error); + sync_write(link->stream, &serror, sizeof(serror)); } int reds_expects_link_id(uint32_t connection_id) @@ -2337,6 +2375,8 @@ static void reds_handle_auth_mechanism(void *opaque) { RedLinkInfo *link = (RedLinkInfo *)opaque; + link->auth_mechanism.auth_mechanism = le32toh(link->auth_mechanism.auth_mechanism); + spice_info("Auth method: %d", link->auth_mechanism.auth_mechanism); if (link->auth_mechanism.auth_mechanism == SPICE_COMMON_CAP_AUTH_SPICE @@ -2371,9 +2411,17 @@ static void reds_handle_read_link_done(void *opaque) RedLinkInfo *link = (RedLinkInfo *)opaque; SpiceLinkMess *link_mess = link->link_mess; AsyncRead *obj = &link->asyc_read; + + link_mess->caps_offset = le32toh(link_mess->caps_offset); + link_mess->channel_id = link_mess->channel_id; + link_mess->channel_type = link_mess->channel_type; + link_mess->connection_id = le32toh(link_mess->connection_id); + link_mess->num_channel_caps = le32toh(link_mess->num_channel_caps); + link_mess->num_common_caps = le32toh(link_mess->num_common_caps); + uint32_t num_caps = link_mess->num_common_caps + link_mess->num_channel_caps; uint32_t *caps = (uint32_t *)((uint8_t *)link_mess + link_mess->caps_offset); - int auth_selection; + int auth_selection,i; if (num_caps && (num_caps * sizeof(uint32_t) + link_mess->caps_offset > link->link_header.size || @@ -2383,6 +2431,9 @@ static void reds_handle_read_link_done(void *opaque) return; } + for(i = 0; i < num_caps;i++) + caps[i] = le32toh(caps[i]); + auth_selection = test_capabilty(caps, link_mess->num_common_caps, SPICE_COMMON_CAP_PROTOCOL_AUTH_SELECTION); @@ -2439,6 +2490,11 @@ static void reds_handle_read_header_done(void *opaque) SpiceLinkHeader *header = &link->link_header; AsyncRead *obj = &link->asyc_read; + header->magic = header->magic; + header->major_version = le32toh(header->major_version); + header->minor_version = le32toh(header->minor_version); + header->size = le32toh(header->size); + if (header->magic != SPICE_MAGIC) { reds_send_link_error(link, SPICE_LINK_ERR_INVALID_MAGIC); reds_link_free(link); -- 1.7.4.1 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/spice-devel