CVS: rdesktop constants.h,1.44,1.45 iso.c,1.16,1.17 mcs.c,1.17,1.18 proto.h,1.81,1.82 rdesktop.c,1.136,1.137 rdp.c,1.91,1.92 secure.c,1.52,1.53 tcp.c,1.31,1.32
Peter Åstrand <[email protected]>
| Newsgroups | gmane.network.rdesktop.cvs |
|---|---|
| Message-ID | <[email protected]> |
Update of /cvsroot/rdesktop/rdesktop
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20521
Modified Files:
constants.h iso.c mcs.c proto.h rdesktop.c rdp.c secure.c
tcp.c
Log Message:
Applied patch #1247780 (slightly modified) from Brian Chapeau: Session Directory support.
Index: constants.h
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/constants.h,v
retrieving revision 1.44
retrieving revision 1.45
diff -C2 -d -r1.44 -r1.45
*** constants.h 20 May 2005 22:09:31 -0000 1.44
--- constants.h 8 Aug 2005 19:15:53 -0000 1.45
***************
*** 70,73 ****
--- 70,74 ----
#define SEC_LOGON_INFO 0x0040
#define SEC_LICENCE_NEG 0x0080
+ #define SEC_REDIRECT_ENCRYPT 0x0C00
#define SEC_TAG_SRV_INFO 0x0c01
***************
*** 107,110 ****
--- 108,112 ----
RDP_PDU_DEMAND_ACTIVE = 1,
RDP_PDU_CONFIRM_ACTIVE = 3,
+ RDP_PDU_REDIRECT = 4, /* MS Server 2003 Session Redirect */
RDP_PDU_DEACTIVATE = 6,
RDP_PDU_DATA = 7
Index: iso.c
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/iso.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -C2 -d -r1.16 -r1.17
*** iso.c 6 Mar 2005 21:11:04 -0000 1.16
--- iso.c 8 Aug 2005 19:15:54 -0000 1.17
***************
*** 192,195 ****
--- 192,219 ----
}
+ /* Establish a reconnection up to the ISO layer */
+ BOOL
+ iso_reconnect(char *server)
+ {
+ uint8 code = 0;
+
+ if (!tcp_connect(server))
+ return False;
+
+ iso_send_msg(ISO_PDU_CR);
+
+ if (iso_recv_msg(&code, NULL) == NULL)
+ return False;
+
+ if (code != ISO_PDU_CC)
+ {
+ error("expected CC, got 0x%x\n", code);
+ tcp_disconnect();
+ return False;
+ }
+
+ return True;
+ }
+
/* Disconnect from the ISO layer */
void
***************
*** 199,200 ****
--- 223,231 ----
tcp_disconnect();
}
+
+ /* reset the state to support reconnecting */
+ void
+ iso_reset_state(void)
+ {
+ tcp_reset_state();
+ }
Index: mcs.c
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/mcs.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -C2 -d -r1.17 -r1.18
*** mcs.c 6 Mar 2005 21:11:04 -0000 1.17
--- mcs.c 8 Aug 2005 19:15:54 -0000 1.18
***************
*** 413,416 ****
--- 413,457 ----
}
+ /* Establish a connection up to the MCS layer */
+ BOOL
+ mcs_reconnect(char *server, STREAM mcs_data)
+ {
+ unsigned int i;
+
+ if (!iso_reconnect(server))
+ return False;
+
+ mcs_send_connect_initial(mcs_data);
+ if (!mcs_recv_connect_response(mcs_data))
+ goto error;
+
+ mcs_send_edrq();
+
+ mcs_send_aurq();
+ if (!mcs_recv_aucf(&g_mcs_userid))
+ goto error;
+
+ mcs_send_cjrq(g_mcs_userid + MCS_USERCHANNEL_BASE);
+
+ if (!mcs_recv_cjcf())
+ goto error;
+
+ mcs_send_cjrq(MCS_GLOBAL_CHANNEL);
+ if (!mcs_recv_cjcf())
+ goto error;
+
+ for (i = 0; i < g_num_channels; i++)
+ {
+ mcs_send_cjrq(g_channels[i].mcs_id);
+ if (!mcs_recv_cjcf())
+ goto error;
+ }
+ return True;
+
+ error:
+ iso_disconnect();
+ return False;
+ }
+
/* Disconnect from the MCS layer */
void
***************
*** 419,420 ****
--- 460,469 ----
iso_disconnect();
}
+
+ /* reset the state of the mcs layer */
+ void
+ mcs_reset_state(void)
+ {
+ g_mcs_userid = 0;
+ iso_reset_state();
+ }
Index: proto.h
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/proto.h,v
retrieving revision 1.81
retrieving revision 1.82
diff -C2 -d -r1.81 -r1.82
*** proto.h 4 Aug 2005 13:39:57 -0000 1.81
--- proto.h 8 Aug 2005 19:15:55 -0000 1.82
***************
*** 47,51 ****
--- 47,53 ----
STREAM iso_recv(uint8 * rdpver);
BOOL iso_connect(char *server, char *username);
+ BOOL iso_reconnect(char *server);
void iso_disconnect(void);
+ void iso_reset_state(void);
/* licence.c */
void licence_process(STREAM s);
***************
*** 56,60 ****
--- 58,64 ----
STREAM mcs_recv(uint16 * channel, uint8 * rdpver);
BOOL mcs_connect(char *server, STREAM mcs_data, char *username);
+ BOOL mcs_reconnect(char *server, STREAM mcs_data);
void mcs_disconnect(void);
+ void mcs_reset_state(void);
/* orders.c */
void process_orders(STREAM s, uint16 num_orders);
***************
*** 115,118 ****
--- 119,125 ----
BOOL rdp_connect(char *server, uint32 flags, char *domain, char *password, char *command,
char *directory);
+ BOOL rdp_reconnect(char *server, uint32 flags, char *domain, char *password, char *command,
+ char *directory, char *cookie);
+ void rdp_reset_state(void);
void rdp_disconnect(void);
/* rdpdr.c */
***************
*** 149,153 ****
--- 156,162 ----
STREAM sec_recv(uint8 * rdpver);
BOOL sec_connect(char *server, char *username);
+ BOOL sec_reconnect(char *server);
void sec_disconnect(void);
+ void sec_reset_state(void);
/* serial.c */
int serial_enum_devices(uint32 * id, char *optarg);
***************
*** 161,164 ****
--- 170,174 ----
void tcp_disconnect(void);
char *tcp_get_address(void);
+ void tcp_reset_state(void);
/* xclip.c */
void ui_clip_format_announce(uint8 * data, uint32 length);
Index: rdesktop.c
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/rdesktop.c,v
retrieving revision 1.136
retrieving revision 1.137
diff -C2 -d -r1.136 -r1.137
*** rdesktop.c 4 Aug 2005 12:51:44 -0000 1.136
--- rdesktop.c 8 Aug 2005 19:15:55 -0000 1.137
***************
*** 93,96 ****
--- 93,104 ----
uint32 g_rdp5_performanceflags =
RDP5_NO_WALLPAPER | RDP5_NO_FULLWINDOWDRAG | RDP5_NO_MENUANIMATIONS;
+ /* Session Directory redirection */
+ BOOL g_redirect = False;
+ char g_redirect_server[64];
+ char g_redirect_domain[16];
+ char g_redirect_password[64];
+ char g_redirect_username[64];
+ char g_redirect_cookie[128];
+ uint32 g_redirect_flags = 0;
#ifdef WITH_RDPSND
***************
*** 276,279 ****
--- 284,293 ----
}
+ static void
+ rdesktop_reset_state(void)
+ {
+ rdp_reset_state();
+ }
+
static BOOL
read_password(char *password, int size)
***************
*** 377,380 ****
--- 391,396 ----
char *locale = NULL;
int username_option = 0;
+ int run_count = 0; /* Session Directory support */
+ BOOL continue_connect = True; /* Session Directory support */
#ifdef HAVE_LOCALE_H
***************
*** 791,814 ****
rdpdr_init();
! if (!rdp_connect(server, flags, domain, password, shell, directory))
! return 1;
! /* By setting encryption to False here, we have an encrypted login
! packet but unencrypted transfer of other packets */
! if (!packet_encryption)
! g_encryption = False;
! DEBUG(("Connection successful.\n"));
! memset(password, 0, sizeof(password));
! if (ui_create_window())
! {
! rdp_main_loop(&deactivated, &ext_disc_reason);
! ui_destroy_window();
}
- DEBUG(("Disconnecting...\n"));
- rdp_disconnect();
cache_save_state();
ui_deinit();
--- 807,863 ----
rdpdr_init();
! while (run_count < 2 && continue_connect) /* add support for Session Directory; only reconnect once */
! {
! if (run_count == 0)
! {
! if (!rdp_connect(server, flags, domain, password, shell, directory))
! return 1;
! }
! else if (!rdp_reconnect
! (server, flags, domain, password, shell, directory, g_redirect_cookie))
! return 1;
! /* By setting encryption to False here, we have an encrypted login
! packet but unencrypted transfer of other packets */
! if (!packet_encryption)
! g_encryption = False;
! DEBUG(("Connection successful.\n"));
! memset(password, 0, sizeof(password));
! if (run_count == 0)
! if (!ui_create_window())
! continue_connect = False;
!
! if (continue_connect)
! rdp_main_loop(&deactivated, &ext_disc_reason);
!
! DEBUG(("Disconnecting...\n"));
! rdp_disconnect();
!
! if ((g_redirect == True) && (run_count == 0)) /* Support for Session Directory */
! {
! /* reset state of major globals */
! rdesktop_reset_state();
!
! STRNCPY(domain, g_redirect_domain, sizeof(domain));
! STRNCPY(g_username, g_redirect_username, sizeof(g_username));
! STRNCPY(password, g_redirect_password, sizeof(password));
! STRNCPY(server, g_redirect_server, sizeof(server));
! flags |= RDP_LOGON_AUTO;
!
! g_redirect = False;
! }
! else
! {
! continue_connect = False;
! ui_destroy_window();
! break;
! }
!
! run_count++;
}
cache_save_state();
ui_deinit();
Index: rdp.c
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/rdp.c,v
retrieving revision 1.91
retrieving revision 1.92
diff -C2 -d -r1.91 -r1.92
*** rdp.c 2 Aug 2005 09:29:41 -0000 1.91
--- rdp.c 8 Aug 2005 19:15:55 -0000 1.92
***************
*** 56,59 ****
--- 56,69 ----
extern RDPCOMP g_mppc_dict;
+ /* Session Directory support */
+ extern BOOL g_redirect;
+ extern char g_redirect_server[64];
+ extern char g_redirect_domain[16];
+ extern char g_redirect_password[64];
+ extern char g_redirect_username[64];
+ extern char g_redirect_cookie[128];
+ extern uint32 g_redirect_flags;
+ /* END Session Directory support */
+
#if WITH_DEBUG
static uint32 g_packetno;
***************
*** 72,76 ****
uint8 rdpver;
! if ((rdp_s == NULL) || (g_next_packet >= rdp_s->end))
{
rdp_s = sec_recv(&rdpver);
--- 82,86 ----
uint8 rdpver;
! if ((rdp_s == NULL) || (g_next_packet >= rdp_s->end) || (g_next_packet == NULL))
{
rdp_s = sec_recv(&rdpver);
***************
*** 261,264 ****
--- 271,278 ----
return rdp_in_unistr(s, string, uni_len);
}
+
+ /* we must update the location of the current STREAM for future reads of s->p */
+ s->p += uni_len;
+
return pout - string;
}
***************
*** 1285,1288 ****
--- 1299,1350 ----
}
+ /* Process redirect PDU from Session Directory */
+ static BOOL
+ process_redirect_pdu(STREAM s /*, uint32 * ext_disc_reason */ )
+ {
+ uint32 len;
+
+ /* these 2 bytes are unknown, seem to be zeros */
+ in_uint8s(s, 2);
+
+ /* read connection flags */
+ in_uint32_le(s, g_redirect_flags);
+
+ /* read length of ip string */
+ in_uint32_le(s, len);
+
+ /* read ip string */
+ rdp_in_unistr(s, g_redirect_server, len);
+
+ /* read length of cookie string */
+ in_uint32_le(s, len);
+
+ /* read cookie string (plain ASCII) */
+ in_uint8a(s, g_redirect_cookie, len);
+ g_redirect_cookie[len] = 0;
+
+ /* read length of username string */
+ in_uint32_le(s, len);
+
+ /* read username string */
+ rdp_in_unistr(s, g_redirect_username, len);
+
+ /* read length of domain string */
+ in_uint32_le(s, len);
+
+ /* read domain string */
+ rdp_in_unistr(s, g_redirect_domain, len);
+
+ /* read length of password string */
+ in_uint32_le(s, len);
+
+ /* read password string */
+ rdp_in_unistr(s, g_redirect_password, len);
+
+ g_redirect = True;
+
+ return True;
+ }
+
/* Process incoming packets */
/* nevers gets out of here till app is done */
***************
*** 1318,1321 ****
--- 1380,1386 ----
*deactivated = True;
break;
+ case RDP_PDU_REDIRECT:
+ return process_redirect_pdu(s);
+ break;
case RDP_PDU_DATA:
disc = process_data_pdu(s, ext_disc_reason);
***************
*** 1345,1348 ****
--- 1410,1434 ----
}
+ /* Establish a reconnection up to the RDP layer */
+ BOOL
+ rdp_reconnect(char *server, uint32 flags, char *domain, char *password,
+ char *command, char *directory, char *cookie)
+ {
+ if (!sec_reconnect(server))
+ return False;
+
+ rdp_send_logon_info(flags, domain, g_username, password, command, directory);
+ return True;
+ }
+
+ /* Called during redirection to reset the state to support redirection */
+ void
+ rdp_reset_state(void)
+ {
+ g_next_packet = NULL; /* reset the packet information */
+ g_rdp_shareid = 0;
+ sec_reset_state();
+ }
+
/* Disconnect from the RDP layer */
void
Index: secure.c
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/secure.c,v
retrieving revision 1.52
retrieving revision 1.53
diff -C2 -d -r1.52 -r1.53
*** secure.c 3 Aug 2005 11:48:22 -0000 1.52
--- secure.c 8 Aug 2005 19:15:56 -0000 1.53
***************
*** 57,60 ****
--- 57,64 ----
uint16 g_server_rdp_version = 0;
+ /* These values must be available to reset state - Session Directory */
+ static int sec_encrypt_use_count = 0;
+ static int sec_decrypt_use_count = 0;
+
/*
* I believe this is based on SSLv3 with the following differences:
***************
*** 252,266 ****
sec_encrypt(uint8 * data, int length)
{
! static int use_count;
!
! if (use_count == 4096)
{
sec_update(sec_encrypt_key, sec_encrypt_update_key);
RC4_set_key(&rc4_encrypt_key, rc4_key_len, sec_encrypt_key);
! use_count = 0;
}
RC4(&rc4_encrypt_key, length, data, data);
! use_count++;
}
--- 256,268 ----
sec_encrypt(uint8 * data, int length)
{
! if (sec_encrypt_use_count == 4096)
{
sec_update(sec_encrypt_key, sec_encrypt_update_key);
RC4_set_key(&rc4_encrypt_key, rc4_key_len, sec_encrypt_key);
! sec_encrypt_use_count = 0;
}
RC4(&rc4_encrypt_key, length, data, data);
! sec_encrypt_use_count++;
}
***************
*** 269,283 ****
sec_decrypt(uint8 * data, int length)
{
! static int use_count;
!
! if (use_count == 4096)
{
sec_update(sec_decrypt_key, sec_decrypt_update_key);
RC4_set_key(&rc4_decrypt_key, rc4_key_len, sec_decrypt_key);
! use_count = 0;
}
RC4(&rc4_decrypt_key, length, data, data);
! use_count++;
}
--- 271,283 ----
sec_decrypt(uint8 * data, int length)
{
! if (sec_decrypt_use_count == 4096)
{
sec_update(sec_decrypt_key, sec_decrypt_update_key);
RC4_set_key(&rc4_decrypt_key, rc4_key_len, sec_decrypt_key);
! sec_decrypt_use_count = 0;
}
RC4(&rc4_decrypt_key, length, data, data);
! sec_decrypt_use_count++;
}
***************
*** 854,857 ****
--- 854,892 ----
continue;
}
+
+ if (sec_flags & 0x0400) /* SEC_REDIRECT_ENCRYPT */
+ {
+ uint8 swapbyte;
+
+ in_uint8s(s, 8); /* signature */
+ sec_decrypt(s->p, s->end - s->p);
+
+ /* Check for a redirect packet, starts with 00 04 */
+ if (s->p[0] == 0 && s->p[1] == 4)
+ {
+ /* for some reason the PDU and the length seem to be swapped.
+ This isn't good, but we're going to do a byte for byte
+ swap. So the first foure value appear as: 00 04 XX YY,
+ where XX YY is the little endian length. We're going to
+ use 04 00 as the PDU type, so after our swap this will look
+ like: XX YY 04 00 */
+ swapbyte = s->p[0];
+ s->p[0] = s->p[2];
+ s->p[2] = swapbyte;
+
+ swapbyte = s->p[1];
+ s->p[1] = s->p[3];
+ s->p[3] = swapbyte;
+
+ swapbyte = s->p[2];
+ s->p[2] = s->p[3];
+ s->p[3] = swapbyte;
+ }
+ #ifdef WITH_DEBUG
+ /* warning! this debug statement will show passwords in the clear! */
+ hexdump(s->p, s->end - s->p);
+ #endif
+ }
+
}
***************
*** 890,893 ****
--- 925,949 ----
}
+ /* Establish a secure connection */
+ BOOL
+ sec_reconnect(char *server)
+ {
+ struct stream mcs_data;
+
+ /* We exchange some RDP data during the MCS-Connect */
+ mcs_data.size = 512;
+ mcs_data.p = mcs_data.data = (uint8 *) xmalloc(mcs_data.size);
+ sec_out_mcs_data(&mcs_data);
+
+ if (!mcs_reconnect(server, &mcs_data))
+ return False;
+
+ /* sec_process_mcs_data(&mcs_data); */
+ if (g_encryption)
+ sec_establish_key();
+ xfree(mcs_data.data);
+ return True;
+ }
+
/* Disconnect a connection */
void
***************
*** 896,897 ****
--- 952,963 ----
mcs_disconnect();
}
+
+ /* reset the state of the sec layer */
+ void
+ sec_reset_state(void)
+ {
+ g_server_rdp_version = 0;
+ sec_encrypt_use_count = 0;
+ sec_decrypt_use_count = 0;
+ mcs_reset_state();
+ }
Index: tcp.c
===================================================================
RCS file: /cvsroot/rdesktop/rdesktop/tcp.c,v
retrieving revision 1.31
retrieving revision 1.32
diff -C2 -d -r1.31 -r1.32
*** tcp.c 3 Aug 2005 10:56:16 -0000 1.31
--- tcp.c 8 Aug 2005 19:15:57 -0000 1.32
***************
*** 243,244 ****
--- 243,278 ----
return ipaddr;
}
+
+ /* reset the state of the tcp layer */
+ /* Support for Session Directory */
+ void
+ tcp_reset_state(void)
+ {
+ sock = -1; /* reset socket */
+
+ /* Clear the incoming stream */
+ if (in.data != NULL)
+ xfree(in.data);
+ in.p = NULL;
+ in.end = NULL;
+ in.data = NULL;
+ in.size = 0;
+ in.iso_hdr = NULL;
+ in.mcs_hdr = NULL;
+ in.sec_hdr = NULL;
+ in.rdp_hdr = NULL;
+ in.channel_hdr = NULL;
+
+ /* Clear the outgoing stream */
+ if (out.data != NULL)
+ xfree(out.data);
+ out.p = NULL;
+ out.end = NULL;
+ out.data = NULL;
+ out.size = 0;
+ out.iso_hdr = NULL;
+ out.mcs_hdr = NULL;
+ out.sec_hdr = NULL;
+ out.rdp_hdr = NULL;
+ out.channel_hdr = NULL;
+ }
-------------------------------------------------------
SF.Net email is Sponsored by the Better Software Conference & EXPO
September 19-22, 2005 * San Francisco, CA * Development Lifecycle Practices
Agile & Plan-Driven Development * Managing Projects & Teams * Testing & QA
Security * Process Improvement & Measurement * http://www.sqe.com/bsce5sf