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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.