[Spice-devel] [PATCH 2/7] spice-ppc: Fixing endianess for channel startup negotiation
Erlon Cruz
sombrafam at gmail.com
Tue Aug 7 11:43:09 PDT 2012
From: Erlon Cruz <erlon.cruz at br.flextronics.com>
Signed-off-by: Erlon R. Cruz <erlon.cruz at br.flextronics.com>
Signed-off-by: Fabiano Fidêncio <Fabiano.Fidêncio at fit-tecnologia.org.br>
Signed-off-by: Rafael F. Santos <Rafael.Santos at fit-tecnologia.org.br>
---
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
More information about the Spice-devel
mailing list