Implemented support for "Client Auto-Reconnect". This means that the
client can re-connect using a cookie, instead of going through the normal authentication. This patch saves those cookies, and uses them during logon. Note that this feature is currently unused. It remains to add support for, say, detecting when the TCP connection has gone done and restart a new one. git-svn-id: svn://svn.code.sf.net/p/rdesktop/code/rdesktop/trunk@1539 423420c4-83ab-492f-b58f-81f9feb106b5
This commit is contained in:
parent
d0327a9989
commit
1b4c36a45f
16
constants.h
16
constants.h
@ -121,12 +121,26 @@ enum RDP_DATA_PDU_TYPE
|
||||
RDP_DATA_PDU_SYNCHRONISE = 31,
|
||||
RDP_DATA_PDU_BELL = 34,
|
||||
RDP_DATA_PDU_CLIENT_WINDOW_STATUS = 35,
|
||||
RDP_DATA_PDU_LOGON = 38,
|
||||
RDP_DATA_PDU_LOGON = 38, /* PDUTYPE2_SAVE_SESSION_INFO */
|
||||
RDP_DATA_PDU_FONT2 = 39,
|
||||
RDP_DATA_PDU_KEYBOARD_INDICATORS = 41,
|
||||
RDP_DATA_PDU_DISCONNECT = 47
|
||||
};
|
||||
|
||||
enum RDP_SAVE_SESSION_PDU_TYPE
|
||||
{
|
||||
INFOTYPE_LOGON = 0,
|
||||
INFOTYPE_LOGON_LONG = 1,
|
||||
INFOTYPE_LOGON_PLAINNOTIFY = 2,
|
||||
INFOTYPE_LOGON_EXTENDED_INF = 3
|
||||
};
|
||||
|
||||
enum RDP_LOGON_INFO_EXTENDED_TYPE
|
||||
{
|
||||
LOGON_EX_AUTORECONNECTCOOKIE = 1,
|
||||
LOGON_EX_LOGONERRORS = 2
|
||||
};
|
||||
|
||||
enum RDP_CONTROL_PDU_TYPE
|
||||
{
|
||||
RDP_CTL_REQUEST_CONTROL = 1,
|
||||
|
@ -103,6 +103,10 @@ char *g_redirect_username;
|
||||
char g_redirect_cookie[128];
|
||||
uint32 g_redirect_flags = 0;
|
||||
|
||||
uint32 g_reconnect_logonid = 0;
|
||||
char g_reconnect_random[16];
|
||||
uint8 g_client_random[SEC_RANDOM_SIZE];
|
||||
|
||||
#ifdef WITH_RDPSND
|
||||
RD_BOOL g_rdpsnd = False;
|
||||
#endif
|
||||
|
61
rdp.c
61
rdp.c
@ -67,6 +67,10 @@ extern char g_redirect_cookie[128];
|
||||
extern uint32 g_redirect_flags;
|
||||
/* END Session Directory support */
|
||||
|
||||
extern uint32 g_reconnect_logonid;
|
||||
extern char g_reconnect_random[16];
|
||||
extern uint8 g_client_random[SEC_RANDOM_SIZE];
|
||||
|
||||
#if WITH_DEBUG
|
||||
static uint32 g_packetno;
|
||||
#endif
|
||||
@ -331,6 +335,7 @@ rdp_send_logon_info(uint32 flags, char *domain, char *user,
|
||||
STREAM s;
|
||||
time_t t = time(NULL);
|
||||
time_t tzone;
|
||||
uint8 security_verifier[16];
|
||||
|
||||
if (!g_use_rdp5 || 1 == g_server_rdp_version)
|
||||
{
|
||||
@ -456,9 +461,16 @@ rdp_send_logon_info(uint32 flags, char *domain, char *user,
|
||||
/* Rest of TS_EXTENDED_INFO_PACKET */
|
||||
out_uint32_le(s, 0xfffffffe); /* clientSessionId, consider changing to 0 */
|
||||
out_uint32_le(s, g_rdp5_performanceflags);
|
||||
out_uint16(s, 0);
|
||||
|
||||
|
||||
/* Client Auto-Reconnect */
|
||||
out_uint16_le(s, 28); /* cbAutoReconnectLen */
|
||||
/* ARC_CS_PRIVATE_PACKET */
|
||||
out_uint32_le(s, 28); /* cbLen */
|
||||
out_uint32_le(s, 1); /* Version */
|
||||
out_uint32_le(s, g_reconnect_logonid); /* LogonId */
|
||||
ssl_hmac_md5(g_reconnect_random, sizeof(g_reconnect_random),
|
||||
g_client_random, SEC_RANDOM_SIZE, security_verifier);
|
||||
out_uint8a(s, security_verifier, sizeof(security_verifier));
|
||||
}
|
||||
s_mark_end(s);
|
||||
sec_send(s, sec_flags);
|
||||
@ -1306,6 +1318,50 @@ process_update_pdu(STREAM s)
|
||||
ui_end_update();
|
||||
}
|
||||
|
||||
|
||||
/* Process a Save Session Info PDU */
|
||||
void
|
||||
process_pdu_logon(STREAM s)
|
||||
{
|
||||
uint32 infotype;
|
||||
in_uint32_le(s, infotype);
|
||||
if (infotype == INFOTYPE_LOGON_EXTENDED_INF)
|
||||
{
|
||||
uint32 fieldspresent;
|
||||
|
||||
in_uint8s(s, 2); /* Length */
|
||||
in_uint32_le(s, fieldspresent);
|
||||
if (fieldspresent & LOGON_EX_AUTORECONNECTCOOKIE)
|
||||
{
|
||||
uint32 len;
|
||||
uint32 version;
|
||||
|
||||
/* TS_LOGON_INFO_FIELD */
|
||||
in_uint8s(s, 4); /* cbFieldData */
|
||||
|
||||
/* ARC_SC_PRIVATE_PACKET */
|
||||
in_uint32_le(s, len);
|
||||
if (len != 28)
|
||||
{
|
||||
warning("Invalid length in Auto-Reconnect packet\n");
|
||||
return;
|
||||
}
|
||||
|
||||
in_uint32_le(s, version);
|
||||
if (version != 1)
|
||||
{
|
||||
warning("Unsupported version of Auto-Reconnect packet\n");
|
||||
return;
|
||||
}
|
||||
|
||||
in_uint32_le(s, g_reconnect_logonid);
|
||||
in_uint8a(s, g_reconnect_random, 16);
|
||||
DEBUG(("Saving auto-reconnect cookie, id=%u\n", g_reconnect_logonid));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Process a disconnect PDU */
|
||||
void
|
||||
process_disconnect_pdu(STREAM s, uint32 * ext_disc_reason)
|
||||
@ -1382,6 +1438,7 @@ process_data_pdu(STREAM s, uint32 * ext_disc_reason)
|
||||
case RDP_DATA_PDU_LOGON:
|
||||
DEBUG(("Received Logon PDU\n"));
|
||||
/* User logged on */
|
||||
process_pdu_logon(s);
|
||||
break;
|
||||
|
||||
case RDP_DATA_PDU_DISCONNECT:
|
||||
|
8
secure.c
8
secure.c
@ -34,6 +34,7 @@ extern RD_BOOL g_console_session;
|
||||
extern int g_server_depth;
|
||||
extern VCHANNEL g_channels[];
|
||||
extern unsigned int g_num_channels;
|
||||
extern uint8 g_client_random[SEC_RANDOM_SIZE];
|
||||
|
||||
static int g_rc4_key_len;
|
||||
static SSL_RC4 g_rc4_decrypt_key;
|
||||
@ -667,7 +668,6 @@ static void
|
||||
sec_process_crypt_info(STREAM s)
|
||||
{
|
||||
uint8 *server_random = NULL;
|
||||
uint8 client_random[SEC_RANDOM_SIZE];
|
||||
uint8 modulus[SEC_MAX_MODULUS_SIZE];
|
||||
uint8 exponent[SEC_EXPONENT_SIZE];
|
||||
uint32 rc4_key_size;
|
||||
@ -680,10 +680,10 @@ sec_process_crypt_info(STREAM s)
|
||||
return;
|
||||
}
|
||||
DEBUG(("Generating client random\n"));
|
||||
generate_random(client_random);
|
||||
sec_rsa_encrypt(g_sec_crypted_random, client_random, SEC_RANDOM_SIZE,
|
||||
generate_random(g_client_random);
|
||||
sec_rsa_encrypt(g_sec_crypted_random, g_client_random, SEC_RANDOM_SIZE,
|
||||
g_server_public_key_len, modulus, exponent);
|
||||
sec_generate_keys(client_random, server_random, rc4_key_size);
|
||||
sec_generate_keys(g_client_random, server_random, rc4_key_size);
|
||||
}
|
||||
|
||||
|
||||
|
10
ssl.c
10
ssl.c
@ -223,3 +223,13 @@ ssl_sig_ok(uint8 * exponent, uint32 exp_len, uint8 * modulus, uint32 mod_len,
|
||||
*/
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ssl_hmac_md5(const void *key, int key_len, const unsigned char *msg, int msg_len, unsigned char *md)
|
||||
{
|
||||
HMAC_CTX ctx;
|
||||
HMAC_CTX_init(&ctx);
|
||||
HMAC(EVP_md5(), key, key_len, msg, msg_len, md, NULL);
|
||||
HMAC_CTX_cleanup(&ctx);
|
||||
}
|
||||
|
4
ssl.h
4
ssl.h
@ -26,6 +26,7 @@
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/x509v3.h>
|
||||
#include <openssl/hmac.h>
|
||||
|
||||
#if defined(OPENSSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x0090800f)
|
||||
#define D2I_X509_CONST const
|
||||
@ -60,4 +61,7 @@ int ssl_rkey_get_exp_mod(SSL_RKEY * rkey, uint8 * exponent, uint32 max_exp_len,
|
||||
RD_BOOL ssl_sig_ok(uint8 * exponent, uint32 exp_len, uint8 * modulus, uint32 mod_len,
|
||||
uint8 * signature, uint32 sig_len);
|
||||
|
||||
void ssl_hmac_md5(const void *key, int key_len,
|
||||
const unsigned char *msg, int msg_len, unsigned char *md);
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user