|
|
e2c81d |
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
|
2be4b2 |
From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fidencio@redhat.com>
|
|
|
2be4b2 |
Date: Thu, 9 Jul 2015 01:04:31 +0200
|
|
|
e2c81d |
Subject: [PATCH] Don't set SpiceLinkReply::pub_key if client advertises SASL
|
|
|
e2c81d |
cap
|
|
|
2be4b2 |
|
|
|
2be4b2 |
If the client advertises the SASL cap, it means it guarantees it will be
|
|
|
2be4b2 |
able to use SASL if the server supports, and that it does not need a valid
|
|
|
2be4b2 |
SpiceLinkReply::pub_key field when using SASL.
|
|
|
2be4b2 |
|
|
|
2be4b2 |
When the client cap is set, we thus don't need to create a RSA public key
|
|
|
2be4b2 |
if SASL is enabled server side.
|
|
|
2be4b2 |
|
|
|
2be4b2 |
The reason for needing client guarantees about not looking at the pub_key
|
|
|
2be4b2 |
field is that its presence and size is hardcoded in the protocol, but in
|
|
|
2be4b2 |
some hardened setups (using fips mode), generating a RSA 1024 bit key as
|
|
|
2be4b2 |
expected is forbidden and fails. With this new capability, the server
|
|
|
2be4b2 |
knows the client will be able to handle SASL if needed, and can skip
|
|
|
2be4b2 |
the generation of the key altogether. This means that on the setups
|
|
|
2be4b2 |
described above, SASL authentication has to be used.
|
|
|
2be4b2 |
---
|
|
|
2be4b2 |
server/reds.c | 56 +++++++++++++++++++++++++++++++++++++++-----------------
|
|
|
2be4b2 |
1 file changed, 39 insertions(+), 17 deletions(-)
|
|
|
2be4b2 |
|
|
|
2be4b2 |
diff --git a/server/reds.c b/server/reds.c
|
|
|
e2c81d |
index 9971b7a..f996c71 100644
|
|
|
2be4b2 |
--- a/server/reds.c
|
|
|
2be4b2 |
+++ b/server/reds.c
|
|
|
2be4b2 |
@@ -1469,7 +1469,7 @@ static int reds_send_link_ack(RedLinkInfo *link)
|
|
|
2be4b2 |
RedChannel *channel;
|
|
|
2be4b2 |
RedChannelCapabilities *channel_caps;
|
|
|
2be4b2 |
BUF_MEM *bmBuf;
|
|
|
2be4b2 |
- BIO *bio;
|
|
|
2be4b2 |
+ BIO *bio = NULL;
|
|
|
2be4b2 |
int ret = FALSE;
|
|
|
2be4b2 |
|
|
|
2be4b2 |
header.magic = SPICE_MAGIC;
|
|
|
2be4b2 |
@@ -1494,24 +1494,45 @@ static int reds_send_link_ack(RedLinkInfo *link)
|
|
|
2be4b2 |
ack.num_channel_caps = channel_caps->num_caps;
|
|
|
2be4b2 |
header.size += (ack.num_common_caps + ack.num_channel_caps) * sizeof(uint32_t);
|
|
|
2be4b2 |
ack.caps_offset = sizeof(SpiceLinkReply);
|
|
|
2be4b2 |
+ if (!sasl_enabled
|
|
|
2be4b2 |
+ || !red_link_info_test_capability(link, SPICE_COMMON_CAP_AUTH_SASL)) {
|
|
|
2be4b2 |
+ if (!(link->tiTicketing.rsa = RSA_new())) {
|
|
|
2be4b2 |
+ spice_warning("RSA new failed");
|
|
|
2be4b2 |
+ return FALSE;
|
|
|
2be4b2 |
+ }
|
|
|
2be4b2 |
|
|
|
2be4b2 |
- if (!(link->tiTicketing.rsa = RSA_new())) {
|
|
|
2be4b2 |
- spice_warning("RSA nes failed");
|
|
|
2be4b2 |
- return FALSE;
|
|
|
2be4b2 |
- }
|
|
|
2be4b2 |
-
|
|
|
2be4b2 |
- if (!(bio = BIO_new(BIO_s_mem()))) {
|
|
|
2be4b2 |
- spice_warning("BIO new failed");
|
|
|
2be4b2 |
- return FALSE;
|
|
|
2be4b2 |
- }
|
|
|
2be4b2 |
+ if (!(bio = BIO_new(BIO_s_mem()))) {
|
|
|
2be4b2 |
+ spice_warning("BIO new failed");
|
|
|
2be4b2 |
+ return FALSE;
|
|
|
2be4b2 |
+ }
|
|
|
2be4b2 |
|
|
|
2be4b2 |
- RSA_generate_key_ex(link->tiTicketing.rsa, SPICE_TICKET_KEY_PAIR_LENGTH, link->tiTicketing.bn,
|
|
|
2be4b2 |
- NULL);
|
|
|
2be4b2 |
- link->tiTicketing.rsa_size = RSA_size(link->tiTicketing.rsa);
|
|
|
2be4b2 |
+ if (RSA_generate_key_ex(link->tiTicketing.rsa,
|
|
|
2be4b2 |
+ SPICE_TICKET_KEY_PAIR_LENGTH,
|
|
|
2be4b2 |
+ link->tiTicketing.bn,
|
|
|
2be4b2 |
+ NULL) != 1) {
|
|
|
2be4b2 |
+ spice_warning("Failed to generate %d bits RSA key: %s",
|
|
|
2be4b2 |
+ SPICE_TICKET_KEY_PAIR_LENGTH,
|
|
|
2be4b2 |
+ ERR_error_string(ERR_get_error(), NULL));
|
|
|
2be4b2 |
+ goto end;
|
|
|
2be4b2 |
+ }
|
|
|
2be4b2 |
+ link->tiTicketing.rsa_size = RSA_size(link->tiTicketing.rsa);
|
|
|
2be4b2 |
|
|
|
2be4b2 |
- i2d_RSA_PUBKEY_bio(bio, link->tiTicketing.rsa);
|
|
|
2be4b2 |
- BIO_get_mem_ptr(bio, &bmBuf);
|
|
|
2be4b2 |
- memcpy(ack.pub_key, bmBuf->data, sizeof(ack.pub_key));
|
|
|
2be4b2 |
+ i2d_RSA_PUBKEY_bio(bio, link->tiTicketing.rsa);
|
|
|
2be4b2 |
+ BIO_get_mem_ptr(bio, &bmBuf);
|
|
|
2be4b2 |
+ memcpy(ack.pub_key, bmBuf->data, sizeof(ack.pub_key));
|
|
|
2be4b2 |
+ } else {
|
|
|
2be4b2 |
+ /* if the client sets the AUTH_SASL cap, it indicates that it
|
|
|
2be4b2 |
+ * supports SASL, and will use it if the server supports SASL as
|
|
|
2be4b2 |
+ * well. Moreover, a client setting the AUTH_SASL cap also
|
|
|
2be4b2 |
+ * indicates that it will not try using the RSA-related content
|
|
|
2be4b2 |
+ * in the SpiceLinkReply message, so we don't need to initialize
|
|
|
2be4b2 |
+ * it. Reason to avoid this is to fix auth in fips mode where
|
|
|
2be4b2 |
+ * the generation of a 1024 bit RSA key as we are trying to do
|
|
|
2be4b2 |
+ * will fail.
|
|
|
2be4b2 |
+ */
|
|
|
2be4b2 |
+ spice_warning("not initialising RSA key");
|
|
|
2be4b2 |
+ memset(ack.pub_key, '\0', sizeof(ack.pub_key));
|
|
|
2be4b2 |
+ }
|
|
|
2be4b2 |
|
|
|
2be4b2 |
if (!sync_write(link->stream, &header, sizeof(header)))
|
|
|
2be4b2 |
goto end;
|
|
|
2be4b2 |
@@ -1525,7 +1546,8 @@ static int reds_send_link_ack(RedLinkInfo *link)
|
|
|
2be4b2 |
ret = TRUE;
|
|
|
2be4b2 |
|
|
|
2be4b2 |
end:
|
|
|
2be4b2 |
- BIO_free(bio);
|
|
|
2be4b2 |
+ if (bio != NULL)
|
|
|
2be4b2 |
+ BIO_free(bio);
|
|
|
2be4b2 |
return ret;
|
|
|
2be4b2 |
}
|
|
|
2be4b2 |
|