/[rdesktop]/sourceforge.net/trunk/rdesktop/rdp.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /sourceforge.net/trunk/rdesktop/rdp.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 4 by matty, Wed May 10 07:36:34 2000 UTC revision 424 by forsberg, Thu Jun 19 07:29:53 2003 UTC
# Line 1  Line 1 
1  /*  /* -*- c-basic-offset: 8 -*-
2     rdesktop: A Remote Desktop Protocol client.     rdesktop: A Remote Desktop Protocol client.
3     Protocol services - RDP layer     Protocol services - RDP layer
4     Copyright (C) Matthew Chapman 1999-2000     Copyright (C) Matthew Chapman 1999-2002
5        
6     This program is free software; you can redistribute it and/or modify     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by     it under the terms of the GNU General Public License as published by
# Line 18  Line 18 
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */  */
20    
21  #include "includes.h"  #include "rdesktop.h"
22    
23  /* Establish a connection up to the RDP layer */  extern uint16 g_mcs_userid;
24  HCONN rdp_connect(char *server)  extern char username[16];
25  {  extern BOOL bitmap_compression;
26          HCONN conn;  extern BOOL orders;
27          RDP_ACTIVE_PDU active;  extern BOOL encryption;
28          RDP_DATA_HEADER hdr;  extern BOOL desktop_save;
29          RDP_UPDATE_PDU update;  extern BOOL use_rdp5;
30          RDP_ORDER_STATE os;  extern uint16 server_rdp_version;
31          uint8 type;  
32    uint8 *next_packet;
33          memset(&os, 0, sizeof(os));  uint32 rdp_shareid;
34    
35          if ((conn = mcs_connect(server)) == NULL)  #if WITH_DEBUG
36                  return NULL;  static uint32 packetno;
37    #endif
38    
39    /* Receive an RDP packet */
40    static STREAM
41    rdp_recv(uint8 * type)
42    {
43            static STREAM rdp_s;
44            uint16 length, pdu_type;
45    
46            if ((rdp_s == NULL) || (next_packet >= rdp_s->end))
47            {
48                    rdp_s = sec_recv();
49                    if (rdp_s == NULL)
50                            return NULL;
51    
52          rdp_establish_key(conn);                  next_packet = rdp_s->p;
53          mcs_recv(conn, False); /* Server's licensing certificate */          }
54          rdp_send_cert(conn);          else
         mcs_recv(conn, False);  
   
         if (rdp_recv_pdu(conn, &type) && (type != RDP_PDU_DEMAND_ACTIVE))  
55          {          {
56                  fprintf(stderr, "RDP error, expected Demand Active\n");                  rdp_s->p = next_packet;
                 mcs_disconnect(conn);  
                 return NULL;  
57          }          }
58    
59          rdp_io_active_pdu(&conn->in, &active, RDP_PDU_DEMAND_ACTIVE);          in_uint16_le(rdp_s, length);
60          rdp_send_confirm_active(conn);          /* 32k packets are really 8, keepalive fix */
61          rdp_send_synchronize(conn);          if (length == 0x8000)
         rdp_send_control(conn, RDP_CTL_COOPERATE);  
         rdp_send_control(conn, RDP_CTL_REQUEST_CONTROL);  
         rdp_recv_pdu(conn, &type); // RDP_PDU_SYNCHRONIZE  
         rdp_recv_pdu(conn, &type); // RDP_CTL_COOPERATE  
         rdp_recv_pdu(conn, &type); // RDP_CTL_GRANT_CONTROL  
         rdp_send_input(conn);  
         rdp_send_fonts(conn, 1);  
         rdp_send_fonts(conn, 2);  
         rdp_recv_pdu(conn, &type); // RDP_PDU_UNKNOWN 0x28  
         while (rdp_recv_pdu(conn, &type))  
62          {          {
63                  if (type != RDP_PDU_DATA)                  next_packet += 8;
64                          continue;                  *type = 0;
65                    return rdp_s;
                 rdp_io_data_header(&conn->in, &hdr);  
   
                 switch (hdr.data_pdu_type)  
                 {  
                 case RDP_DATA_PDU_UPDATE:  
                         rdp_io_update_pdu(&conn->in, &update);  
                         if (update.update_type == RDP_UPDATE_ORDERS)  
                         {  
                                 fprintf(stderr, "Received orders\n");  
                                 process_orders(conn, &os);  
                         }  
                         break;  
                 }  
66          }          }
67            in_uint16_le(rdp_s, pdu_type);
68            in_uint8s(rdp_s, 2);    /* userid */
69            *type = pdu_type & 0xf;
70    
71          return conn;  #if WITH_DEBUG
72            DEBUG(("RDP packet #%d, (type %x)\n", ++packetno, *type));
73            //      hexdump(next_packet, length);
74    #endif /*  */
75    
76            next_packet += length;
77            return rdp_s;
78  }  }
79    
80  void prs_io_coord(STREAM s, uint16 *coord, BOOL delta)  /* Initialise an RDP data packet */
81    static STREAM
82    rdp_init_data(int maxlen)
83  {  {
84          uint8 change;          STREAM s;
85    
86          if (delta)          s = sec_init(encryption ? SEC_ENCRYPT : 0, maxlen + 18);
87          {          s_push_layer(s, rdp_hdr, 18);
88                  prs_io_uint8(s, &change);  
89                  *coord += change;          return s;
         }  
         else  
         {  
                 lsb_io_uint16(s, coord);  
         }  
90  }  }
91    
92  void process_opaque_rect(HCONN conn, RDP_ORDER_STATE *os, BOOL delta)  /* Send an RDP data packet */
93    static void
94    rdp_send_data(STREAM s, uint8 data_pdu_type)
95  {  {
96          uint8 present;          uint16 length;
         prs_io_uint8(&conn->in, &present);  
   
         if (present & 1)  
                 prs_io_coord(&conn->in, &os->opaque_rect.x, delta);  
   
         if (present & 2)  
                 prs_io_coord(&conn->in, &os->opaque_rect.y, delta);  
97    
98          if (present & 4)          s_pop_layer(s, rdp_hdr);
99                  prs_io_coord(&conn->in, &os->opaque_rect.cx, delta);          length = s->end - s->p;
100    
101          if (present & 8)          out_uint16_le(s, length);
102                  prs_io_coord(&conn->in, &os->opaque_rect.cy, delta);          out_uint16_le(s, (RDP_PDU_DATA | 0x10));
103            out_uint16_le(s, (g_mcs_userid + 1001));
104    
105          if (present & 16)          out_uint32_le(s, rdp_shareid);
106                  prs_io_uint8(&conn->in, &os->opaque_rect.colour);          out_uint8(s, 0);        /* pad */
107            out_uint8(s, 1);        /* streamid */
108            out_uint16_le(s, (length - 14));
109            out_uint8(s, data_pdu_type);
110            out_uint8(s, 0);        /* compress_type */
111            out_uint16(s, 0);       /* compress_len */
112    
113          fprintf(stderr, "Opaque rectangle at %d, %d\n", os->opaque_rect.x, os->opaque_rect.y);          sec_send(s, encryption ? SEC_ENCRYPT : 0);
114  }  }
115    
116  void process_orders(HCONN conn, RDP_ORDER_STATE *os)  /* Output a string in Unicode */
117    void
118    rdp_out_unistr(STREAM s, char *string, int len)
119  {  {
120          uint16 num_orders;          int i = 0, j = 0;
         int processed = 0;  
         BOOL res = True;  
         //      unsigned char *p;  
   
         lsb_io_uint16(&conn->in, &num_orders);  
121    
122          conn->in.offset += 2;          len += 2;
         //      p = &conn->in.data[conn->in.offset];  
123    
124          //      fprintf(stderr, "%02X %02X %02X %02X\n", p[0], p[1], p[2], p[3]);          while (i < len)
   
         while ((processed < num_orders) && res)  
125          {          {
126                  uint8 order_flags;                  s->p[i++] = string[j++];
127                    s->p[i++] = 0;
128                  prs_io_uint8(&conn->in, &order_flags);          }
129    
130                  if (!(order_flags & RDP_ORDER_STANDARD))          s->p += len;
131                          return;  }
132    
133                  if (order_flags & RDP_ORDER_SECONDARY)  /* Parse a logon info packet */
134                  {  static void
135                          RDP_SECONDARY_ORDER rso;  rdp_send_logon_info(uint32 flags, char *domain, char *user,
136                        char *password, char *program, char *directory)
137    {
138            int len_domain = 2 * strlen(domain);
139            int len_user = 2 * strlen(user);
140            int len_password = 2 * strlen(password);
141            int len_program = 2 * strlen(program);
142            int len_directory = 2 * strlen(directory);
143            int len_ip = 2 * strlen("127.0.0.1");
144            int len_dll = 2 * strlen("C:\\WINNT\\System32\\mstscax.dll");
145            int packetlen = 0;
146            uint32 sec_flags = encryption ? (SEC_LOGON_INFO | SEC_ENCRYPT) : SEC_LOGON_INFO;
147            STREAM s;
148    
149                          rdp_io_secondary_order(&conn->in, &rso);          if (!use_rdp5 || 1 == server_rdp_version)
150                          switch (rso.type)          {
151                          {                  DEBUG_RDP5(("Sending RDP4-style Logon packet\n"));
                         case RDP_ORDER_BMPCACHE:  
                         {  
                                 RDP_BITMAP_HEADER rbh;  
                                 char output[8192];  
152    
153                                  rdp_io_bitmap_header(&conn->in, &rbh);                  s = sec_init(sec_flags, 18 + len_domain + len_user + len_password
154                                  fprintf(stderr, "Decompressing bitmap %d x %d, final size %d\n", rbh.width, rbh.height, rbh.final_size);                               + len_program + len_directory + 10);
                                 bitmap_decompress(conn->in.data  
                                                   + conn->in.offset, rbh.size,  
                                                   output, rbh.width);  
                                 conn->in.offset += rbh.size;  
                                 break;  
                         }  
                         default:  
                                 fprintf(stderr, "Unknown secondary order %d\n",  
                                         rso.type);  
                                 return;  
                         }  
155    
156                    out_uint32(s, 0);
157                    out_uint32_le(s, flags);
158                    out_uint16_le(s, len_domain);
159                    out_uint16_le(s, len_user);
160                    out_uint16_le(s, len_password);
161                    out_uint16_le(s, len_program);
162                    out_uint16_le(s, len_directory);
163                    rdp_out_unistr(s, domain, len_domain);
164                    rdp_out_unistr(s, user, len_user);
165                    rdp_out_unistr(s, password, len_password);
166                    rdp_out_unistr(s, program, len_program);
167                    rdp_out_unistr(s, directory, len_directory);
168            }
169            else
170            {
171                    flags |= RDP_LOGON_BLOB;
172                    DEBUG_RDP5(("Sending RDP5-style Logon packet\n"));
173                    packetlen = 4 + // Unknown uint32
174                            4 +     // flags
175                            2 +     // len_domain
176                            2 +     // len_user
177                            (flags & RDP_LOGON_AUTO ? 2 : 0) +      // len_password
178                            (flags & RDP_LOGON_BLOB ? 2 : 0) +      // Length of BLOB
179                            2 +     // len_program
180                            2 +     // len_directory
181                            (0 < len_domain ? len_domain : 2) +     // domain
182                            len_user + (flags & RDP_LOGON_AUTO ? len_password : 0) + 0 +    // We have no 512 byte BLOB. Perhaps we must?
183                            (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO) ? 2 : 0) + // After the BLOB is a unknown int16. If there is a BLOB, that is.
184                            (0 < len_program ? len_program : 2) + (0 < len_directory ? len_directory : 2) + 2 +     // Unknown (2)
185                            2 +     // Client ip length
186                            len_ip +        // Client ip
187                            2 +     // DLL string length
188                            len_dll +       // DLL string
189                            2 +     // Unknown
190                            2 +     // Unknown
191                            64 +    // Time zone #0
192                            2 +     // Unknown
193                            64 +    // Time zone #1
194                            32;     // Unknown
195    
196                    s = sec_init(sec_flags, packetlen);
197                    DEBUG_RDP5(("Called sec_init with packetlen %d\n", packetlen));
198    
199                    out_uint32(s, 0);       // Unknown
200                    out_uint32_le(s, flags);
201                    out_uint16_le(s, len_domain);
202                    out_uint16_le(s, len_user);
203                    if (flags & RDP_LOGON_AUTO)
204                    {
205                            out_uint16_le(s, len_password);
206    
207                  }                  }
208                    if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO))
                 if (order_flags & RDP_ORDER_CHANGE)  
                         prs_io_uint8(&conn->in, &os->order_type);  
   
                 switch (os->order_type)  
209                  {                  {
210                  case RDP_ORDER_OPAQUE_RECT:                          out_uint16_le(s, 0);
                         process_opaque_rect(conn, os, order_flags & RDP_ORDER_DELTA);  
                         break;  
                 default:  
                         fprintf(stderr, "Unknown order %d\n", os->order_type);  
                         return;  
211                  }                  }
212                    out_uint16_le(s, len_program);
213                    out_uint16_le(s, len_directory);
214                    if (0 < len_domain)
215                            rdp_out_unistr(s, domain, len_domain);
216                    else
217                            out_uint16_le(s, 0);
218                    rdp_out_unistr(s, user, len_user);
219                    if (flags & RDP_LOGON_AUTO)
220                    {
221                            rdp_out_unistr(s, password, len_password);
222                    }
223                    if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO))
224                    {
225                            out_uint16_le(s, 0);
226                    }
227                    if (0 < len_program)
228                    {
229                            rdp_out_unistr(s, program, len_program);
230    
231                  processed++;                  }
232          }                  else
233  }                  {
234                            out_uint16_le(s, 0);
235  /* Work this out later. This is useless anyway when encryption is off. */                  }
236  uint8 precanned_key_packet[] = {                  if (0 < len_directory)
237     0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x00,0x00,0x00,0x00,0x00,                  {
238     0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6c,0x86,                          rdp_out_unistr(s, directory, len_directory);
239     0xf7,0x99,0xef,0x60,0xc4,0x49,0x52,0xd0,0xd8,0xea,0xb5,0x4f,0x58,0x19,                  }
240     0x52,0x2a,0x93,0x83,0x57,0x4f,0x4e,0x04,0xde,0x96,0x51,0xab,0x13,0x20,                  else
241     0xd8,0xe5,0x00,0x00,0x00,0x00,0x00,0x00                  {
242  };                          out_uint16_le(s, 0);
243                    }
244                    out_uint16_le(s, 2);
245                    out_uint16_le(s, len_ip + 2);   // Length of client ip
246                    rdp_out_unistr(s, "127.0.0.1", len_ip);
247                    out_uint16_le(s, len_dll + 2);
248                    rdp_out_unistr(s, "C:\\WINNT\\System32\\mstscax.dll", len_dll);
249                    out_uint16_le(s, 0xffc4);
250                    out_uint16_le(s, 0xffff);
251                    rdp_out_unistr(s, "GTB, normaltid", 2 * strlen("GTB, normaltid"));
252                    out_uint8s(s, 62 - 2 * strlen("GTB, normaltid"));
253    
 /* Create an RC4 key and transfer it to the server */  
 void rdp_establish_key(HCONN conn)  
 {  
         mcs_init_data(conn);  
         memcpy(conn->out.data + conn->out.offset, precanned_key_packet,  
                sizeof(precanned_key_packet));  
         conn->out.offset += sizeof(precanned_key_packet);  
         MARK_END(conn->out);  
         mcs_send_data(conn, MCS_GLOBAL_CHANNEL, True);  
 }  
   
 /* Horrible horrible certificate stuff. Work out later. */  
 uint8 precanned_cert_packet[] = {  
 0x80,0x00,0x00,0x00,0x12,0x02,0xb4,0x04,0x01,0x00,0x00,  
 0x00,0x00,0x00,0x01,0x02,0x9d,0xa3,0x7a,0x93,0x34,0x7b,0x28,0x37,0x24,0xa0,0x1f,  
 0x61,0x26,0xfd,0x96,0x3a,0x92,0x83,0xf3,0xe9,0x6a,0x2e,0x81,0x7c,0x2c,0xe4,0x72,//  
 0x01,0x18,0xe9,0xa1,0x0f,0x00,0x00,0x48,0x00,0x84,0x23,0x90,0xe6,0xd3,0xf8,0x20,  
 0xdb,0xa8,0x1b,0xb2,0xd0,0x78,0x2c,0x35,0xde,0xe3,0x0e,0x63,0x40,0xca,0xac,0x71,  
 0xc9,0x17,0x49,0x05,0x25,0xeb,0x9b,0xd0,0xa6,0x5c,0x90,0x3e,0x9d,0x4b,0x27,0x01,  
 0x79,0x1c,0x22,0xfb,0x3c,0x2c,0xb9,0x9f,0xf5,0x21,0xf3,0xee,0xd5,0x4d,0x47,0x1c,  
 0x85,0xbe,0x83,0x93,0xe8,0xed,0x8c,0x5c,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  
 0x00,0x01,0x00,0x10,0x04,0x30,0x82,0x04,0x0c,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,  
 0x0d,0x01,0x07,0x02,0xa0,0x82,0x03,0xfd,0x30,0x82,0x03,0xf9,0x02,0x01,0x01,0x31,  
 0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x82,  
 0x03,0xe1,0x30,0x82,0x01,0x77,0x30,0x82,0x01,0x25,0xa0,0x03,0x02,0x01,0x02,0x02,  
 0x08,0x01,0xbf,0x06,0x84,0x9d,0xdb,0x2d,0xe0,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,  
 0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x30,0x38,0x31,0x36,0x30,0x11,0x06,0x03,  
 0x55,0x04,0x03,0x1e,0x0a,0x00,0x4e,0x00,0x54,0x00,0x54,0x00,0x53,0x00,0x45,0x30,  
 0x21,0x06,0x03,0x55,0x04,0x07,0x1e,0x1a,0x00,0x4d,0x00,0x69,0x00,0x63,0x00,0x72,  
 0x00,0x6f,0x00,0x73,0x00,0x6f,0x00,0x66,0x00,0x74,0x00,0x2e,0x00,0x63,0x00,0x6f,  
 0x00,0x6d,0x30,0x1e,0x17,0x0d,0x39,0x39,0x30,0x39,0x32,0x34,0x31,0x32,0x30,0x32,  
 0x30,0x34,0x5a,0x17,0x0d,0x34,0x39,0x30,0x39,0x32,0x34,0x31,0x32,0x30,0x32,0x30,  
 0x34,0x5a,0x30,0x38,0x31,0x36,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x1e,0x0a,0x00,  
 0x4e,0x00,0x54,0x00,0x54,0x00,0x53,0x00,0x45,0x30,0x21,0x06,0x03,0x55,0x04,0x07,  
 0x1e,0x1a,0x00,0x4d,0x00,0x69,0x00,0x63,0x00,0x72,0x00,0x6f,0x00,0x73,0x00,0x6f,  
 0x00,0x66,0x00,0x74,0x00,0x2e,0x00,0x63,0x00,0x6f,0x00,0x6d,0x30,0x5c,0x30,0x0d,  
 0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,  
 0x30,0x48,0x02,0x41,0x00,0x91,0xb2,0x16,0x1c,0xae,0x4f,0x7f,0x7c,0xaf,0x57,0x2b,  
 0x23,0x4c,0x0c,0x25,0x3c,0x4f,0x66,0x9d,0x25,0xc3,0x4f,0x29,0xee,0x8b,0xda,0x4e,  
 0x95,0xe7,0x3b,0xaa,0xc0,0xa7,0xba,0xaf,0x99,0x8c,0x47,0x24,0x8b,0x09,0x77,0xbc,  
 0x2c,0xf4,0xe7,0x1a,0x07,0x58,0x7b,0x11,0x37,0x2a,0xa8,0x90,0xc3,0x50,0x92,0x80,  
 0x15,0xc5,0xda,0x51,0x8b,0x02,0x03,0x01,0x00,0x01,0xa3,0x13,0x30,0x11,0x30,0x0f,  
 0x06,0x03,0x55,0x1d,0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x00,0x30,  
 0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x03,0x41,0x00,0x14,0x04,0x67,  
 0x28,0xc8,0xd3,0x1f,0x13,0x14,0x2e,0x2c,0x93,0x09,0x25,0xbb,0xbe,0x86,0x6a,0xd3,  
 0x47,0x6f,0x44,0x16,0x7b,0x94,0x8c,0xb2,0xa2,0xd5,0xf7,0x4f,0xb1,0x8f,0x7f,0xde,  
 0x0b,0x88,0x34,0x4a,0x1d,0xdc,0xa1,0xfd,0x26,0xbd,0x43,0xbb,0x38,0xf1,0x87,0x34,  
 0xbb,0xe9,0x3b,0xfa,0x7f,0x1e,0xff,0xe1,0x10,0x7e,0xee,0x6e,0xd8,0x30,0x82,0x02,  
 0x62,0x30,0x82,0x02,0x10,0xa0,0x03,0x02,0x01,0x02,0x02,0x05,0x01,0x00,0x00,0x00,  
 0x01,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x38,0x31,0x36,  
 0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x1e,0x0a,0x00,0x4e,0x00,0x54,0x00,0x54,0x00,  
 0x53,0x00,0x45,0x30,0x21,0x06,0x03,0x55,0x04,0x07,0x1e,0x1a,0x00,0x4d,0x00,0x69,  
 0x00,0x63,0x00,0x72,0x00,0x6f,0x00,0x73,0x00,0x6f,0x00,0x66,0x00,0x74,0x00,0x2e,  
 0x00,0x63,0x00,0x6f,0x00,0x6d,0x30,0x1e,0x17,0x0d,0x39,0x39,0x30,0x39,0x32,0x34,  
 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x34,0x39,0x30,0x39,0x32,0x34,0x30,  
 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x79,0x31,0x77,0x30,0x17,0x06,0x03,0x55,0x04,  
 0x03,0x1e,0x10,0x00,0x52,0x00,0x45,0x00,0x53,0x00,0x37,0x00,0x2d,0x00,0x4e,0x00,  
 0x45,0x00,0x57,0x30,0x17,0x06,0x03,0x55,0x04,0x07,0x1e,0x10,0x00,0x7a,0x00,0x32,  
 0x00,0x32,0x00,0x33,0x00,0x32,0x00,0x32,0x00,0x30,0x00,0x33,0x30,0x43,0x06,0x03,  
 0x55,0x04,0x05,0x1e,0x3c,0x00,0x31,0x00,0x42,0x00,0x63,0x00,0x4b,0x00,0x65,0x00,  
 0x57,0x00,0x50,0x00,0x6c,0x00,0x37,0x00,0x58,0x00,0x47,0x00,0x61,0x00,0x73,0x00,  
 0x38,0x00,0x4a,0x00,0x79,0x00,0x50,0x00,0x34,0x00,0x30,0x00,0x7a,0x00,0x49,0x00,  
 0x6d,0x00,0x6e,0x00,0x6f,0x00,0x51,0x00,0x5a,0x00,0x59,0x00,0x3d,0x00,0x0d,0x00,  
 0x0a,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,  
 0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0x91,0xb2,0x16,0x1c,0xae,0x4f,  
 0x7f,0x7c,0xaf,0x57,0x2b,0x23,0x4c,0x0c,0x25,0x3c,0x4f,0x66,0x9d,0x25,0xc3,0x4f,  
 0x29,0xee,0x8b,0xda,0x4e,0x95,0xe7,0x3b,0xaa,0xc0,0xa7,0xba,0xaf,0x99,0x8c,0x47,  
 0x24,0x8b,0x09,0x77,0xbc,0x2c,0xf4,0xe7,0x1a,0x07,0x58,0x7b,0x11,0x37,0x2a,0xa8,  
 0x90,0xc3,0x50,0x92,0x80,0x15,0xc5,0xda,0x51,0x8b,0x02,0x03,0x01,0x00,0x01,0xa3,  
 0x81,0xc3,0x30,0x81,0xc0,0x30,0x14,0x06,0x09,0x2b,0x06,0x01,0x04,0x01,0x82,0x37,  
 0x12,0x04,0x01,0x01,0xff,0x04,0x04,0x01,0x00,0x01,0x00,0x30,0x3c,0x06,0x09,0x2b,  
 0x06,0x01,0x04,0x01,0x82,0x37,0x12,0x02,0x01,0x01,0xff,0x04,0x2c,0x4d,0x00,0x69,  
 0x00,0x63,0x00,0x72,0x00,0x6f,0x00,0x73,0x00,0x6f,0x00,0x66,0x00,0x74,0x00,0x20,  
 0x00,0x43,0x00,0x6f,0x00,0x72,0x00,0x70,0x00,0x6f,0x00,0x72,0x00,0x61,0x00,0x74,  
 0x00,0x69,0x00,0x6f,0x00,0x6e,0x00,0x00,0x00,0x30,0x4c,0x06,0x09,0x2b,0x06,0x01,  
 0x04,0x01,0x82,0x37,0x12,0x05,0x01,0x01,0xff,0x04,0x3c,0x00,0x10,0x00,0x00,0x01,  
 0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x09,0x04,0x00,0x00,0x18,0x00,0x18,0x00,0x30,  
 0x00,0x01,0x00,0x32,0x00,0x33,0x00,0x36,0x00,0x2d,0x00,0x34,0x00,0x2e,0x00,0x30,  
 0x00,0x30,0x00,0x2d,0x00,0x45,0x00,0x58,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,  
 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x1c,0x06,0x03,0x55,0x1d,0x23,0x01,0x01,  
 0xff,0x04,0x12,0x30,0x10,0xa1,0x07,0x81,0x05,0x4e,0x54,0x54,0x53,0x45,0x82,0x05,  
 0x01,0x00,0x00,0x00,0x01,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,  
 0x03,0x41,0x00,0x7b,0x1d,0xfd,0x24,0xea,0xf2,0xe8,0x17,0xdd,0x88,0x7e,0xfd,0xee,  
 0x28,0x61,0x7a,0x02,0xc3,0x73,0xcf,0x32,0x0f,0x7c,0x66,0x87,0x31,0xa7,0xbe,0x1b,  
 0x31,0xe2,0x20,0xa5,0x76,0x91,0x68,0x97,0x53,0x9e,0x80,0xcd,0x2b,0xd0,0x8e,0x8b,  
 0x7f,0x89,0x1b,0x62,0xa8,0xf8,0xee,0x5e,0x56,0xbd,0x9c,0x6b,0x80,0x06,0x54,0xd3,  
 0xf0,0xbf,0xb2,0x31,0x00,0x01,0x00,0x14,0x00,0xc7,0x32,0xf2,0x5b,0x98,0x0e,0x04,  
 0x49,0xa0,0x27,0x7e,0xf5,0xf6,0x0f,0xda,0x08,0x1d,0xe9,0x79,0xd1,0x31,0xc6,0x50,  
 0x90,0x4a,0xd3,0x1f,0x1d,0xf0,0x65,0x0d,0xb6,0x1f,0xaf,0xc9,0x1d  
 };  
254    
255  /* Send license certificate and related data to the server */                  out_uint32_le(s, 0x0a0000);
256  void rdp_send_cert(HCONN conn)                  out_uint32_le(s, 0x050000);
257  {                  out_uint32_le(s, 3);
258          mcs_init_data(conn);                  out_uint32_le(s, 0);
259          prs_io_uint8s(&conn->out, precanned_cert_packet, sizeof(precanned_cert_packet));                  out_uint32_le(s, 0);
         MARK_END(conn->out);  
         mcs_send_data(conn, MCS_GLOBAL_CHANNEL, True);  
 }  
260    
261  /* Initialise RDP transport packet */                  rdp_out_unistr(s, "GTB, sommartid", 2 * strlen("GTB, sommartid"));
262  void rdp_init(HCONN conn)                  out_uint8s(s, 62 - 2 * strlen("GTB, sommartid"));
 {  
         mcs_init_data(conn);  
         PUSH_LAYER(conn->out, rdp_offset, 6);  
 }  
263    
264  /* Transmit RDP transport packet */                  out_uint32_le(s, 0x30000);
265  void rdp_send(HCONN conn, uint16 pdu_type)                  out_uint32_le(s, 0x050000);
266  {                  out_uint32_le(s, 2);
267          RDP_HEADER hdr;                  out_uint32(s, 0);
268          int length;                  out_uint32_le(s, 0xffffffc4);
269                    out_uint32_le(s, 0xfffffffe);
270                    out_uint32_le(s, 0x0f);
271                    out_uint32(s, 0);
272    
         POP_LAYER(conn->out, rdp_offset);  
         length = conn->out.end - conn->out.offset;  
         rdp_make_header(&hdr, length, pdu_type, conn->mcs_userid);  
         rdp_io_header(&conn->out, &hdr);  
         mcs_send_data(conn, MCS_GLOBAL_CHANNEL, True);  
 }  
273    
274  /* Initialise RDP transport data packet */          }
275  void rdp_init_data(HCONN conn)          s_mark_end(s);
276  {          sec_send(s, sec_flags);
         mcs_init_data(conn);  
         PUSH_LAYER(conn->out, rdp_offset, 18);  
277  }  }
278    
279  /* Transmit RDP transport data packet */  /* Send a control PDU */
280  void rdp_send_data(HCONN conn, uint16 data_pdu_type)  static void
281    rdp_send_control(uint16 action)
282  {  {
283          RDP_HEADER hdr;          STREAM s;
         RDP_DATA_HEADER datahdr;  
         int length = conn->out.end - conn->out.offset;  
284    
285          POP_LAYER(conn->out, rdp_offset);          s = rdp_init_data(8);
         length = conn->out.end - conn->out.offset;  
         rdp_make_header(&hdr, length, RDP_PDU_DATA, conn->mcs_userid);  
         rdp_io_header(&conn->out, &hdr);  
         rdp_make_data_header(&datahdr, 0x103ea, length, data_pdu_type);  
         rdp_io_data_header(&conn->out, &datahdr);  
         mcs_send_data(conn, MCS_GLOBAL_CHANNEL, True);  
 }  
286    
287  void rdp_send_confirm_active(HCONN conn)          out_uint16_le(s, action);
288  {          out_uint16(s, 0);       /* userid */
289          RDP_ACTIVE_PDU active;          out_uint32(s, 0);       /* control id */
290    
291          rdp_init(conn);          s_mark_end(s);
292          rdp_make_active_pdu(&active, 0x103ea, conn->mcs_userid);          rdp_send_data(s, RDP_DATA_PDU_CONTROL);
         rdp_io_active_pdu(&conn->out, &active, RDP_PDU_CONFIRM_ACTIVE);  
         MARK_END(conn->out);  
         rdp_send(conn, RDP_PDU_CONFIRM_ACTIVE);  
293  }  }
294    
295  void rdp_send_synchronize(HCONN conn)  /* Send a synchronisation PDU */
296    static void
297    rdp_send_synchronise(void)
298  {  {
299          RDP_SYNCHRONIZE_PDU sync;          STREAM s;
300    
301          rdp_init_data(conn);          s = rdp_init_data(4);
         rdp_make_synchronize_pdu(&sync, 1002);  
         rdp_io_synchronize_pdu(&conn->out, &sync);  
         MARK_END(conn->out);  
         rdp_send_data(conn, RDP_DATA_PDU_SYNCHRONIZE);  
 }  
302    
303  void rdp_send_control(HCONN conn, uint16 action)          out_uint16_le(s, 1);    /* type */
304  {          out_uint16_le(s, 1002);
         RDP_CONTROL_PDU control;  
305    
306          rdp_init_data(conn);          s_mark_end(s);
307          rdp_make_control_pdu(&control, action);          rdp_send_data(s, RDP_DATA_PDU_SYNCHRONISE);
         rdp_io_control_pdu(&conn->out, &control);  
         MARK_END(conn->out);  
         rdp_send_data(conn, RDP_DATA_PDU_CONTROL);  
308  }  }
309    
310  void rdp_send_fonts(HCONN conn, uint16 seqno)  /* Send a single input event */
311    void
312    rdp_send_input(uint32 time, uint16 message_type, uint16 device_flags, uint16 param1, uint16 param2)
313  {  {
314          RDP_FONT_PDU fonts;          STREAM s;
315    
316          rdp_init_data(conn);          s = rdp_init_data(16);
         rdp_make_font_pdu(&fonts, seqno);  
         rdp_io_font_pdu(&conn->out, &fonts);  
         MARK_END(conn->out);  
         rdp_send_data(conn, RDP_DATA_PDU_FONT2);  
 }  
317    
318  void rdp_send_input(HCONN conn)          out_uint16_le(s, 1);    /* number of events */
319  {          out_uint16(s, 0);       /* pad */
         RDP_INPUT_PDU input;  
320    
321          rdp_init_data(conn);          out_uint32_le(s, time);
322          rdp_make_input_pdu(&input);          out_uint16_le(s, message_type);
323          rdp_io_input_pdu(&conn->out, &input);          out_uint16_le(s, device_flags);
324          MARK_END(conn->out);          out_uint16_le(s, param1);
325          rdp_send_data(conn, RDP_DATA_PDU_INPUT);          out_uint16_le(s, param2);
326    
327            s_mark_end(s);
328            rdp_send_data(s, RDP_DATA_PDU_INPUT);
329  }  }
330    
331  BOOL rdp_recv_pdu(HCONN conn, uint8 *type)  /* Send an (empty) font information PDU */
332    static void
333    rdp_send_fonts(uint16 seq)
334  {  {
335          RDP_HEADER hdr;          STREAM s;
336    
337          if (!mcs_recv(conn, False) || !rdp_io_header(&conn->in, &hdr))          s = rdp_init_data(8);
                 return False;  
338    
339          *type = hdr.pdu_type & 0xf;          out_uint16(s, 0);       /* number of fonts */
340          return True;          out_uint16_le(s, 0x3e); /* unknown */
341  }          out_uint16_le(s, seq);  /* unknown */
342            out_uint16_le(s, 0x32); /* entry size */
343    
344  /* Disconnect from the RDP layer */          s_mark_end(s);
345  void rdp_disconnect(HCONN conn)          rdp_send_data(s, RDP_DATA_PDU_FONT2);
 {  
         mcs_disconnect(conn);  
346  }  }
347    
348  void rdp_make_header(RDP_HEADER *hdr, uint16 length, uint16 pdu_type,  /* Output general capability set */
349                       uint16 userid)  static void
350    rdp_out_general_caps(STREAM s)
351  {  {
352          hdr->length = length;          out_uint16_le(s, RDP_CAPSET_GENERAL);
353          hdr->pdu_type = pdu_type | 0x10; /* Version 1 */          out_uint16_le(s, RDP_CAPLEN_GENERAL);
         hdr->userid = userid + 1001;  
 }  
354    
355  void rdp_make_data_header(RDP_DATA_HEADER *hdr, uint32 shareid,          out_uint16_le(s, 1);    /* OS major type */
356                            uint16 length, uint16 data_pdu_type)          out_uint16_le(s, 3);    /* OS minor type */
357  {          out_uint16_le(s, 0x200);        /* Protocol version */
358          hdr->shareid = shareid;          out_uint16(s, 0);       /* Pad */
359          hdr->pad = 0;          out_uint16(s, 0);       /* Compression types */
360          hdr->streamid = 1;          out_uint16_le(s, use_rdp5 ? 0x40d : 0);
361          hdr->length = length - 14;          /* Pad, according to T.128. 0x40d seems to
362          hdr->data_pdu_type = data_pdu_type;             trigger
363          hdr->compress_type = 0;             the server to start sending RDP5 packets.
364          hdr->compress_len = 0;             However, the value is 0x1d04 with W2KTSK and
365               NT4MS. Hmm.. Anyway, thankyou, Microsoft,
366               for sending such information in a padding
367               field.. */
368            out_uint16(s, 0);       /* Update capability */
369            out_uint16(s, 0);       /* Remote unshare capability */
370            out_uint16(s, 0);       /* Compression level */
371            out_uint16(s, 0);       /* Pad */
372  }  }
373    
374  void rdp_make_general_caps(RDP_GENERAL_CAPS *caps)  /* Output bitmap capability set */
375    static void
376    rdp_out_bitmap_caps(STREAM s)
377  {  {
378          caps->os_major_type = 1;          out_uint16_le(s, RDP_CAPSET_BITMAP);
379          caps->os_minor_type = 3;          out_uint16_le(s, RDP_CAPLEN_BITMAP);
         caps->ver_protocol = 0x200;  
 }  
380    
381  void rdp_make_bitmap_caps(RDP_BITMAP_CAPS *caps)          out_uint16_le(s, 8);    /* Preferred BPP */
382  {          out_uint16_le(s, 1);    /* Receive 1 BPP */
383          caps->preferred_bpp = 8;          out_uint16_le(s, 1);    /* Receive 4 BPP */
384          caps->receive1bpp = 1;          out_uint16_le(s, 1);    /* Receive 8 BPP */
385          caps->receive4bpp = 1;          out_uint16_le(s, 800);  /* Desktop width */
386          caps->receive8bpp = 1;          out_uint16_le(s, 600);  /* Desktop height */
387          caps->width = 640;          out_uint16(s, 0);       /* Pad */
388          caps->height = 480;          out_uint16(s, 0);       /* Allow resize */
389          caps->compression = 1;          out_uint16_le(s, bitmap_compression ? 1 : 0);   /* Support compression */
390          caps->unknown2 = 1;          out_uint16(s, 0);       /* Unknown */
391            out_uint16_le(s, 1);    /* Unknown */
392            out_uint16(s, 0);       /* Pad */
393  }  }
394    
395  void rdp_make_order_caps(RDP_ORDER_CAPS *caps)  /* Output order capability set */
396    static void
397    rdp_out_order_caps(STREAM s)
398  {  {
399          caps->xgranularity = 1;          uint8 order_caps[32];
         caps->ygranularity = 20;  
         caps->max_order_level = 1;  
         caps->num_fonts = 0x147;  
         caps->cap_flags = 0x2A;  
400    
 //      caps->cap_flags = ORDER_CAP_NEGOTIATE | ORDER_CAP_NOSUPPORT;  
401    
402          caps->support[0] = caps->support[1] = caps->support[2]          memset(order_caps, 0, 32);
403                  = caps->support[3] = caps->support[4] = caps->support[5]          order_caps[0] = 1;      /* dest blt */
404                  = caps->support[6] = caps->support[8] = caps->support[11]          order_caps[1] = 1;      /* pat blt */
405                  = caps->support[12] = caps->support[22] = caps->support[28]          order_caps[2] = 1;      /* screen blt */
406                  = caps->support[29] = caps->support[30] = 1;          order_caps[3] = 1;      /* required for memblt? */
407          caps->text_cap_flags = 0x6A1;          order_caps[8] = 1;      /* line */
408          caps->desk_save_size = 0x38400;          order_caps[9] = 1;      /* line */
409          caps->unknown2 = 0x4E4;          order_caps[10] = 1;     /* rect */
410  }          order_caps[11] = (desktop_save == False ? 0 : 1);       /* desksave */
411            order_caps[13] = 1;     /* memblt */
412            order_caps[14] = 1;     /* triblt */
413            order_caps[22] = 1;     /* polyline */
414            order_caps[27] = 1;     /* text2 */
415            out_uint16_le(s, RDP_CAPSET_ORDER);
416            out_uint16_le(s, RDP_CAPLEN_ORDER);
417    
418  void rdp_make_bmpcache_caps(RDP_BMPCACHE_CAPS *caps)          out_uint8s(s, 20);      /* Terminal desc, pad */
419  {          out_uint16_le(s, 1);    /* Cache X granularity */
420          caps->caches[0].entries = 0x258;          out_uint16_le(s, 20);   /* Cache Y granularity */
421          caps->caches[0].max_cell_size = 0x100;          out_uint16(s, 0);       /* Pad */
422          caps->caches[1].entries = 0x12c;          out_uint16_le(s, 1);    /* Max order level */
423          caps->caches[1].max_cell_size = 0x400;          out_uint16_le(s, 0x147);        /* Number of fonts */
424          caps->caches[2].entries = 0x106;          out_uint16_le(s, 0x2a); /* Capability flags */
425          caps->caches[2].max_cell_size = 0x1000;          out_uint8p(s, order_caps, 32);  /* Orders supported */
426            out_uint16_le(s, 0x6a1);        /* Text capability flags */
427            out_uint8s(s, 6);       /* Pad */
428            out_uint32_le(s, desktop_save == False ? 0 : 0x38400);  /* Desktop cache size */
429            out_uint32(s, 0);       /* Unknown */
430            out_uint32_le(s, 0x4e4);        /* Unknown */
431  }  }
432    
433  void rdp_make_control_caps(RDP_CONTROL_CAPS *caps)  /* Output bitmap cache capability set */
434    static void
435    rdp_out_bmpcache_caps(STREAM s)
436  {  {
437          caps->control_interest = 2;          out_uint16_le(s, RDP_CAPSET_BMPCACHE);
438          caps->detach_interest = 2;          out_uint16_le(s, RDP_CAPLEN_BMPCACHE);
 }  
439    
440  void rdp_make_activate_caps(RDP_ACTIVATE_CAPS *caps)          out_uint8s(s, 24);      /* unused */
441  {          out_uint16_le(s, 0x258);        /* entries */
442  }          out_uint16_le(s, 0x100);        /* max cell size */
443            out_uint16_le(s, 0x12c);        /* entries */
444  void rdp_make_pointer_caps(RDP_POINTER_CAPS *caps)          out_uint16_le(s, 0x400);        /* max cell size */
445  {          out_uint16_le(s, 0x106);        /* entries */
446          caps->colour_pointer = 0;          out_uint16_le(s, 0x1000);       /* max cell size */
         caps->cache_size = 20;  
447  }  }
448    
449  void rdp_make_share_caps(RDP_SHARE_CAPS *caps, uint16 userid)  /* Output control capability set */
450    static void
451    rdp_out_control_caps(STREAM s)
452  {  {
453  }          out_uint16_le(s, RDP_CAPSET_CONTROL);
454            out_uint16_le(s, RDP_CAPLEN_CONTROL);
455    
456  void rdp_make_colcache_caps(RDP_COLCACHE_CAPS *caps)          out_uint16(s, 0);       /* Control capabilities */
457  {          out_uint16(s, 0);       /* Remote detach */
458          caps->cache_size = 6;          out_uint16_le(s, 2);    /* Control interest */
459            out_uint16_le(s, 2);    /* Detach interest */
460  }  }
461    
462  void rdp_make_active_pdu(RDP_ACTIVE_PDU *pdu, uint32 shareid, uint16 userid)  /* Output activation capability set */
463    static void
464    rdp_out_activate_caps(STREAM s)
465  {  {
466          memset(pdu, 0, sizeof(*pdu));          out_uint16_le(s, RDP_CAPSET_ACTIVATE);
467          pdu->shareid = shareid;          out_uint16_le(s, RDP_CAPLEN_ACTIVATE);
         pdu->userid  = 1002;  
         pdu->source_len = sizeof(RDP_SOURCE);  
         memcpy(pdu->source, RDP_SOURCE, sizeof(RDP_SOURCE));  
   
         pdu->caps_len = RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER  
                 + RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE + RDP_CAPLEN_ACTIVATE  
                 + RDP_CAPLEN_CONTROL + RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE  
                 + RDP_CAPLEN_UNKNOWN;  
         pdu->num_caps = 0xD;  
   
         rdp_make_general_caps (&pdu->general_caps );  
         rdp_make_bitmap_caps  (&pdu->bitmap_caps  );  
         rdp_make_order_caps   (&pdu->order_caps   );  
         rdp_make_bmpcache_caps(&pdu->bmpcache_caps);  
         rdp_make_control_caps (&pdu->control_caps );  
         rdp_make_activate_caps(&pdu->activate_caps);  
         rdp_make_pointer_caps (&pdu->pointer_caps );  
         rdp_make_share_caps   (&pdu->share_caps, userid);  
         rdp_make_colcache_caps(&pdu->colcache_caps);  
 }  
468    
469  void rdp_make_control_pdu(RDP_CONTROL_PDU *pdu, uint16 action)          out_uint16(s, 0);       /* Help key */
470  {          out_uint16(s, 0);       /* Help index key */
471          pdu->action = action;          out_uint16(s, 0);       /* Extended help key */
472          pdu->userid = 0;          out_uint16(s, 0);       /* Window activate */
         pdu->controlid = 0;  
473  }  }
474    
475  void rdp_make_synchronize_pdu(RDP_SYNCHRONIZE_PDU *pdu, uint16 userid)  /* Output pointer capability set */
476    static void
477    rdp_out_pointer_caps(STREAM s)
478  {  {
479          pdu->type = 1;          out_uint16_le(s, RDP_CAPSET_POINTER);
480          pdu->userid = userid;          out_uint16_le(s, RDP_CAPLEN_POINTER);
 }  
481    
482  void rdp_make_font_pdu(RDP_FONT_PDU *pdu, uint16 seqno)          out_uint16(s, 0);       /* Colour pointer */
483  {          out_uint16_le(s, 20);   /* Cache size */
         pdu->num_fonts = 0;  
         pdu->unknown1 = 0x3e;  
         pdu->unknown2 = seqno;  
         pdu->entry_size = RDP_FONT_INFO_SIZE;  
484  }  }
485    
486  void rdp_make_input_pdu(RDP_INPUT_PDU *pdu)  /* Output share capability set */
487    static void
488    rdp_out_share_caps(STREAM s)
489  {  {
490          uint32 now = time(NULL);          out_uint16_le(s, RDP_CAPSET_SHARE);
491            out_uint16_le(s, RDP_CAPLEN_SHARE);
         pdu->num_events = 3;  
         pdu->pad = 0;  
492    
493          pdu->event[0].event_time = now;          out_uint16(s, 0);       /* userid */
494          pdu->event[0].message_type = RDP_INPUT_SYNCHRONIZE;          out_uint16(s, 0);       /* pad */
         pdu->event[0].device_flags = 0;  
         pdu->event[0].mouse_x = 0;  
         pdu->event[0].mouse_y = 0;  
   
         pdu->event[1].event_time = now;  
         pdu->event[1].message_type = RDP_INPUT_UNKNOWN;  
         pdu->event[1].device_flags = 0x8000;  
         pdu->event[1].mouse_x = 15;  
         pdu->event[1].mouse_y = 0;  
   
         pdu->event[2].event_time = now;  
         pdu->event[2].message_type = RDP_INPUT_MOUSE;  
         pdu->event[2].device_flags = MOUSE_FLAG_MOVE;  
         pdu->event[2].mouse_x = 425;  
         pdu->event[2].mouse_y = 493;  
495  }  }
496    
497  BOOL rdp_io_header(STREAM s, RDP_HEADER *hdr)  /* Output colour cache capability set */
498    static void
499    rdp_out_colcache_caps(STREAM s)
500  {  {
501          BOOL res = True;          out_uint16_le(s, RDP_CAPSET_COLCACHE);
502            out_uint16_le(s, RDP_CAPLEN_COLCACHE);
503    
504          res = res ? lsb_io_uint16(s, &hdr->length  ) : False;          out_uint16_le(s, 6);    /* cache size */
505          res = res ? lsb_io_uint16(s, &hdr->pdu_type) : False;          out_uint16(s, 0);       /* pad */
         res = res ? lsb_io_uint16(s, &hdr->userid  ) : False;  
   
         return res;  
506  }  }
507    
508  BOOL rdp_io_data_header(STREAM s, RDP_DATA_HEADER *hdr)  static uint8 canned_caps[] = {
509  {          0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x04,
510          BOOL res = True;          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
511            0x00, 0x00, 0x00, 0x00, 0x00,
512          res = res ? lsb_io_uint32(s, &hdr->shareid      ) : False;          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
513          res = res ? prs_io_uint8 (s, &hdr->pad          ) : False;          0x00, 0x00, 0x00, 0x00, 0x00,
514          res = res ? prs_io_uint8 (s, &hdr->streamid     ) : False;          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
515          res = res ? lsb_io_uint16(s, &hdr->length       ) : False;          0x00, 0x00, 0x00, 0x00, 0x00,
516          res = res ? prs_io_uint8 (s, &hdr->data_pdu_type) : False;          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
517          res = res ? prs_io_uint8 (s, &hdr->compress_type) : False;          0x00, 0x00, 0x00, 0x00, 0x00,
518          res = res ? lsb_io_uint16(s, &hdr->compress_len ) : False;          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
519            0x0C, 0x00, 0x08, 0x00, 0x01,
520          return res;          0x00, 0x00, 0x00, 0x0E, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00,
521  }          0x10, 0x00, 0x34, 0x00, 0xFE,
522            0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x08, 0x00,
523            0xFE, 0x00, 0x08, 0x00, 0xFE,
524            0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00, 0xFE, 0x00, 0x40, 0x00,
525            0xFE, 0x00, 0x80, 0x00, 0xFE,
526            0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01,
527            0x02, 0x00, 0x00, 0x00
528    };
529    
530  BOOL rdp_io_general_caps(STREAM s, RDP_GENERAL_CAPS *caps)  /* Output unknown capability sets (number 13, 12, 14 and 16) */
531    static void
532    rdp_out_unknown_caps(STREAM s)
533    {
534            out_uint16_le(s, RDP_CAPSET_UNKNOWN);
535            out_uint16_le(s, 0x58);
536    
537            out_uint8p(s, canned_caps, RDP_CAPLEN_UNKNOWN - 4);
538    }
539    
540    #define RDP5_FLAG 0x0030
541    /* Send a confirm active PDU */
542    static void
543    rdp_send_confirm_active(void)
544    {
545            STREAM s;
546            uint32 sec_flags = encryption ? (RDP5_FLAG | SEC_ENCRYPT) : RDP5_FLAG;
547            uint16 caplen =
548                    RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +
549                    RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +
550                    RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +
551                    RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE + RDP_CAPLEN_UNKNOWN + 4 /* w2k fix, why? */ ;
552    
553            s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));
554    
555            out_uint16_le(s, 2 + 14 + caplen + sizeof(RDP_SOURCE));
556            out_uint16_le(s, (RDP_PDU_CONFIRM_ACTIVE | 0x10));      /* Version 1 */
557            out_uint16_le(s, (g_mcs_userid + 1001));
558    
559            out_uint32_le(s, rdp_shareid);
560            out_uint16_le(s, 0x3ea);        /* userid */
561            out_uint16_le(s, sizeof(RDP_SOURCE));
562            out_uint16_le(s, caplen);
563    
564            out_uint8p(s, RDP_SOURCE, sizeof(RDP_SOURCE));
565            out_uint16_le(s, 0xd);  /* num_caps */
566            out_uint8s(s, 2);       /* pad */
567    
568            rdp_out_general_caps(s);
569            rdp_out_bitmap_caps(s);
570            rdp_out_order_caps(s);
571            rdp_out_bmpcache_caps(s);
572            rdp_out_colcache_caps(s);
573            rdp_out_activate_caps(s);
574            rdp_out_control_caps(s);
575            rdp_out_pointer_caps(s);
576            rdp_out_share_caps(s);
577            rdp_out_unknown_caps(s);
578    
579            s_mark_end(s);
580            sec_send(s, sec_flags);
581    }
582    
583    /* Respond to a demand active PDU */
584    static void
585    process_demand_active(STREAM s)
586  {  {
587          uint16 length = RDP_CAPLEN_GENERAL;          uint8 type;
         uint16 pkt_length = length;  
         BOOL res;  
   
         res = lsb_io_uint16(s, &pkt_length);  
         if (pkt_length != length)  
         {  
                 fprintf(stderr, "Unrecognised capabilities size\n");  
                 return False;  
         }  
   
         res = res ? lsb_io_uint16(s, &caps->os_major_type ) : False;  
         res = res ? lsb_io_uint16(s, &caps->os_minor_type ) : False;  
         res = res ? lsb_io_uint16(s, &caps->ver_protocol  ) : False;  
         res = res ? lsb_io_uint16(s, &caps->pad1          ) : False;  
         res = res ? lsb_io_uint16(s, &caps->compress_types) : False;  
         res = res ? lsb_io_uint16(s, &caps->pad2          ) : False;  
         res = res ? lsb_io_uint16(s, &caps->cap_update    ) : False;  
         res = res ? lsb_io_uint16(s, &caps->remote_unshare) : False;  
         res = res ? lsb_io_uint16(s, &caps->compress_level) : False;  
         res = res ? lsb_io_uint16(s, &caps->pad3          ) : False;  
   
         return res;  
 }  
   
 BOOL rdp_io_bitmap_caps(STREAM s, RDP_BITMAP_CAPS *caps)  
 {  
         uint16 length = RDP_CAPLEN_BITMAP;  
         uint16 pkt_length = length;  
         BOOL res;  
   
         res = lsb_io_uint16(s, &pkt_length);  
         if (pkt_length != length)  
         {  
                 fprintf(stderr, "Unrecognised capabilities size\n");  
                 return False;  
         }  
588    
589          res = res ? lsb_io_uint16(s, &caps->preferred_bpp) : False;          in_uint32_le(s, rdp_shareid);
         res = res ? lsb_io_uint16(s, &caps->receive1bpp  ) : False;  
         res = res ? lsb_io_uint16(s, &caps->receive4bpp  ) : False;  
         res = res ? lsb_io_uint16(s, &caps->receive8bpp  ) : False;  
         res = res ? lsb_io_uint16(s, &caps->width        ) : False;  
         res = res ? lsb_io_uint16(s, &caps->height       ) : False;  
         res = res ? lsb_io_uint16(s, &caps->pad1         ) : False;  
         res = res ? lsb_io_uint16(s, &caps->allow_resize ) : False;  
         res = res ? lsb_io_uint16(s, &caps->compression  ) : False;  
         res = res ? lsb_io_uint16(s, &caps->unknown1     ) : False;  
         res = res ? lsb_io_uint16(s, &caps->unknown2     ) : False;  
         res = res ? lsb_io_uint16(s, &caps->pad2         ) : False;  
   
         return res;  
 }  
   
 BOOL rdp_io_order_caps(STREAM s, RDP_ORDER_CAPS *caps)  
 {  
         uint16 length = RDP_CAPLEN_ORDER;  
         uint16 pkt_length = length;  
         BOOL res;  
590    
591          res = lsb_io_uint16(s, &pkt_length);          DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", rdp_shareid));
         if (pkt_length != length)  
         {  
                 fprintf(stderr, "Unrecognised capabilities size\n");  
                 return False;  
         }  
592    
593          res = res ? prs_io_uint8s(s,  caps->terminal_desc, 16) : False;          rdp_send_confirm_active();
594          res = res ? lsb_io_uint32(s, &caps->pad1             ) : False;          rdp_send_synchronise();
595          res = res ? lsb_io_uint16(s, &caps->xgranularity     ) : False;          rdp_send_control(RDP_CTL_COOPERATE);
596          res = res ? lsb_io_uint16(s, &caps->ygranularity     ) : False;          rdp_send_control(RDP_CTL_REQUEST_CONTROL);
597          res = res ? lsb_io_uint16(s, &caps->pad2             ) : False;          rdp_recv(&type);        /* RDP_PDU_SYNCHRONIZE */
598          res = res ? lsb_io_uint16(s, &caps->max_order_level  ) : False;          rdp_recv(&type);        /* RDP_CTL_COOPERATE */
599          res = res ? lsb_io_uint16(s, &caps->num_fonts        ) : False;          rdp_recv(&type);        /* RDP_CTL_GRANT_CONTROL */
600          res = res ? lsb_io_uint16(s, &caps->cap_flags        ) : False;          rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, 0, 0);
601          res = res ? prs_io_uint8s(s,  caps->support      , 32) : False;          rdp_send_fonts(1);
602          res = res ? lsb_io_uint16(s, &caps->text_cap_flags   ) : False;          rdp_send_fonts(2);
603          res = res ? lsb_io_uint16(s, &caps->pad3             ) : False;          rdp_recv(&type);        /* RDP_PDU_UNKNOWN 0x28 */
604          res = res ? lsb_io_uint32(s, &caps->pad4             ) : False;          reset_order_state();
         res = res ? lsb_io_uint32(s, &caps->desk_save_size   ) : False;  
         res = res ? lsb_io_uint32(s, &caps->unknown1         ) : False;  
         res = res ? lsb_io_uint32(s, &caps->unknown2         ) : False;  
   
         return res;  
605  }  }
606    
607  BOOL rdp_io_bmpcache_info(STREAM s, RDP_BMPCACHE_INFO *info)  /* Process a null system pointer PDU */
608    void
609    process_null_system_pointer_pdu(STREAM s)
610  {  {
611          if (!lsb_io_uint16(s, &info->entries      ))          // FIXME: We should probably set another cursor here,
612                  return False;          // like the X window system base cursor or something.
613            ui_set_cursor(cache_get_cursor(0));
         if (!lsb_io_uint16(s, &info->max_cell_size))  
                 return False;  
   
         return True;  
614  }  }
615    
616  BOOL rdp_io_bmpcache_caps(STREAM s, RDP_BMPCACHE_CAPS *caps)  /* Process a colour pointer PDU */
617    void
618    process_colour_pointer_pdu(STREAM s)
619  {  {
620          uint16 length = RDP_CAPLEN_BMPCACHE;          uint16 x, y, width, height, cache_idx, masklen, datalen;
621          uint16 pkt_length = length;          uint8 *mask, *data;
622          BOOL res;          HCURSOR cursor;
         int i;  
   
         res = lsb_io_uint16(s, &pkt_length);  
         if (pkt_length != length)  
         {  
                 fprintf(stderr, "Unrecognised capabilities size\n");  
                 return False;  
         }  
   
         for (i = 0; i < 6; i++)  
                 res = res ? lsb_io_uint32(s, &caps->unused[i]) : False;  
   
         for (i = 0; i < 3; i++)  
                 res = res ? rdp_io_bmpcache_info(s, &caps->caches[i]) : False;  
623    
624          return res;          in_uint16_le(s, cache_idx);
625            in_uint16_le(s, x);
626            in_uint16_le(s, y);
627            in_uint16_le(s, width);
628            in_uint16_le(s, height);
629            in_uint16_le(s, masklen);
630            in_uint16_le(s, datalen);
631            in_uint8p(s, data, datalen);
632            in_uint8p(s, mask, masklen);
633            cursor = ui_create_cursor(x, y, width, height, mask, data);
634            ui_set_cursor(cursor);
635            cache_put_cursor(cache_idx, cursor);
636  }  }
637    
638  BOOL rdp_io_control_caps(STREAM s, RDP_CONTROL_CAPS *caps)  /* Process a cached pointer PDU */
639    void
640    process_cached_pointer_pdu(STREAM s)
641  {  {
642          uint16 length = RDP_CAPLEN_CONTROL;          uint16 cache_idx;
         uint16 pkt_length = length;  
         BOOL res;  
   
         res = lsb_io_uint16(s, &pkt_length);  
         if (pkt_length != length)  
         {  
                 fprintf(stderr, "Unrecognised capabilities size\n");  
                 return False;  
         }  
643    
644          res = res ? lsb_io_uint16(s, &caps->control_caps    ) : False;          in_uint16_le(s, cache_idx);
645          res = res ? lsb_io_uint16(s, &caps->remote_detach   ) : False;          ui_set_cursor(cache_get_cursor(cache_idx));
         res = res ? lsb_io_uint16(s, &caps->control_interest) : False;  
         res = res ? lsb_io_uint16(s, &caps->detach_interest ) : False;  
   
         return res;  
646  }  }
647    
 BOOL rdp_io_activate_caps(STREAM s, RDP_ACTIVATE_CAPS *caps)  
 {  
         uint16 length = RDP_CAPLEN_ACTIVATE;  
         uint16 pkt_length = length;  
         BOOL res;  
   
         res = lsb_io_uint16(s, &pkt_length);  
         if (pkt_length != length)  
         {  
                 fprintf(stderr, "Unrecognised capabilities size\n");  
                 return False;  
         }  
   
         res = res ? lsb_io_uint16(s, &caps->help_key         ) : False;  
         res = res ? lsb_io_uint16(s, &caps->help_index_key   ) : False;  
         res = res ? lsb_io_uint16(s, &caps->help_extended_key) : False;  
         res = res ? lsb_io_uint16(s, &caps->window_activate  ) : False;  
   
         return res;  
 }  
648    
649  BOOL rdp_io_pointer_caps(STREAM s, RDP_POINTER_CAPS *caps)  /* Process a pointer PDU */
650    static void
651    process_pointer_pdu(STREAM s)
652  {  {
653          uint16 length = RDP_CAPLEN_POINTER;          uint16 message_type;
654          uint16 pkt_length = length;          uint16 x, y;
         BOOL res;  
655    
656          res = lsb_io_uint16(s, &pkt_length);          in_uint16_le(s, message_type);
657          if (pkt_length != length)          in_uint8s(s, 2);        /* pad */
         {  
                 fprintf(stderr, "Unrecognised capabilities size\n");  
                 return False;  
         }  
658    
659          res = res ? lsb_io_uint16(s, &caps->colour_pointer) : False;          switch (message_type)
660          res = res ? lsb_io_uint16(s, &caps->cache_size    ) : False;          {
661                    case RDP_POINTER_MOVE:
662                            in_uint16_le(s, x);
663                            in_uint16_le(s, y);
664                            if (s_check(s))
665                                    ui_move_pointer(x, y);
666                            break;
667    
668          return res;                  case RDP_POINTER_COLOR:
669  }                          process_colour_pointer_pdu(s);
670                            break;
671    
672  BOOL rdp_io_share_caps(STREAM s, RDP_SHARE_CAPS *caps)                  case RDP_POINTER_CACHED:
673  {                          process_cached_pointer_pdu(s);
674          uint16 length = RDP_CAPLEN_SHARE;                          break;
         uint16 pkt_length = length;  
         BOOL res;  
675    
676          res = lsb_io_uint16(s, &pkt_length);                  default:
677          if (pkt_length != length)                          DEBUG(("Pointer message 0x%x\n", message_type));
         {  
                 fprintf(stderr, "Unrecognised capabilities size\n");  
                 return False;  
678          }          }
   
         res = res ? lsb_io_uint16(s, &caps->userid) : False;  
         res = res ? lsb_io_uint16(s, &caps->pad   ) : False;  
   
         return res;  
679  }  }
680    
681  BOOL rdp_io_colcache_caps(STREAM s, RDP_COLCACHE_CAPS *caps)  /* Process bitmap updates */
682    void
683    process_bitmap_updates(STREAM s)
684  {  {
685          uint16 length = RDP_CAPLEN_COLCACHE;          uint16 num_updates;
686          uint16 pkt_length = length;          uint16 left, top, right, bottom, width, height;
687          BOOL res;          uint16 cx, cy, bpp, Bpp, compress, bufsize, size;
688            uint8 *data, *bmpdata;
689            int i;
690    
691          res = lsb_io_uint16(s, &pkt_length);          in_uint16_le(s, num_updates);
         if (pkt_length != length)  
         {  
                 fprintf(stderr, "Unrecognised capabilities size\n");  
                 return False;  
         }  
692    
693          res = res ? lsb_io_uint16(s, &caps->cache_size) : False;          for (i = 0; i < num_updates; i++)
694          res = res ? lsb_io_uint16(s, &caps->pad       ) : False;          {
695                    in_uint16_le(s, left);
696                    in_uint16_le(s, top);
697                    in_uint16_le(s, right);
698                    in_uint16_le(s, bottom);
699                    in_uint16_le(s, width);
700                    in_uint16_le(s, height);
701                    in_uint16_le(s, bpp);
702                    Bpp = (bpp + 7) / 8;
703                    in_uint16_le(s, compress);
704                    in_uint16_le(s, bufsize);
705    
706          return res;                  cx = right - left + 1;
707  }                  cy = bottom - top + 1;
708    
709  uint8 canned_caps[] = {                  DEBUG(("BITMAP_UPDATE(l=%d,t=%d,r=%d,b=%d,w=%d,h=%d,Bpp=%d,cmp=%d)\n",
710  0x01,0x00,0x00,0x00,0x09,0x04,0x00,0x00,0x04,                         left, top, right, bottom, width, height, Bpp, compress));
 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  
 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  
 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  
 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  
 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x08,0x00,0x01,  
 0x00,0x00,0x00,0x0E,0x00,0x08,0x00,0x01,0x00,0x00,0x00,0x10,0x00,0x34,0x00,0xFE,  
 0x00,0x04,0x00,0xFE,0x00,0x04,0x00,0xFE,0x00,0x08,0x00,0xFE,0x00,0x08,0x00,0xFE,  
 0x00,0x10,0x00,0xFE,0x00,0x20,0x00,0xFE,0x00,0x40,0x00,0xFE,0x00,0x80,0x00,0xFE,  
 0x00,0x00,0x01,0x40,0x00,0x00,0x08,0x00,0x01,0x00,0x01,0x02,0x00,0x00,0x00  
 };  
711    
712  BOOL rdp_io_unknown_caps(STREAM s, void *caps)                  if (!compress)
713  {                  {
714          uint16 length = 0x58;                          int y;
715          uint16 pkt_length = length;                          bmpdata = (uint8 *) xmalloc(width * height * Bpp);
716          BOOL res;                          for (y = 0; y < height; y++)
717                            {
718                                    in_uint8a(s, &bmpdata[(height - y - 1) * (width * Bpp)],
719                                              width * Bpp);
720                            }
721                            ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
722                            xfree(bmpdata);
723                            continue;
724                    }
725    
         res = lsb_io_uint16(s, &pkt_length);  
         if (pkt_length != length)  
         {  
                 fprintf(stderr, "Unrecognised capabilities size\n");  
                 return False;  
         }  
726    
727          res = res ? prs_io_uint8s(s, canned_caps, RDP_CAPLEN_UNKNOWN-4) : False;                  if (compress & 0x400)
728                    {
729                            size = bufsize;
730                    }
731                    else
732                    {
733                            in_uint8s(s, 2);        /* pad */
734                            in_uint16_le(s, size);
735                            in_uint8s(s, 4);        /* line_size, final_size */
736                    }
737                    in_uint8p(s, data, size);
738                    bmpdata = (uint8 *) xmalloc(width * height * Bpp);
739                    if (bitmap_decompress(bmpdata, width, height, data, size, Bpp))
740                    {
741                            ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
742                    }
743                    else
744                    {
745                            DEBUG_RDP5(("Failed to decompress data\n"));
746                    }
747    
748          return res;                  xfree(bmpdata);
749            }
750  }  }
751    
752  BOOL rdp_io_active_pdu(STREAM s, RDP_ACTIVE_PDU *pdu, int pdutype)  /* Process a palette update */
753    void
754    process_palette(STREAM s)
755  {  {
756          uint16 capset;          COLOURENTRY *entry;
757          uint16 length;          COLOURMAP map;
758          BOOL res;          HCOLOURMAP hmap;
759          int i;          int i;
760    
761          res = lsb_io_uint32(s, &pdu->shareid);          in_uint8s(s, 2);        /* pad */
762            in_uint16_le(s, map.ncolours);
763            in_uint8s(s, 2);        /* pad */
764    
765          if (pdutype == RDP_PDU_CONFIRM_ACTIVE)          map.colours = (COLOURENTRY *) xmalloc(3 * map.ncolours);
                 res = res ? lsb_io_uint16(s, &pdu->userid    ) : False;  
766    
767          res = res ? lsb_io_uint16(s, &pdu->source_len) : False;          DEBUG(("PALETTE(c=%d)\n", map.ncolours));
         res = res ? lsb_io_uint16(s, &pdu->caps_len  ) : False;  
768    
769          if (pdu->source_len > 48)          for (i = 0; i < map.ncolours; i++)
770          {          {
771                  fprintf(stderr, "RDP source descriptor too long\n");                  entry = &map.colours[i];
772                  return False;                  in_uint8(s, entry->red);
773          }                  in_uint8(s, entry->green);
774                    in_uint8(s, entry->blue);
         res = res ? prs_io_uint8s(s,  pdu->source, pdu->source_len) : False;  
         res = res ? lsb_io_uint16(s, &pdu->num_caps  ) : False;  
         res = res ? lsb_io_uint16(s, &pdu->pad       ) : False;  
   
         if (s->marshall)  
         {  
                 capset = RDP_CAPSET_GENERAL;  
                 res = res ? lsb_io_uint16(s, &capset) : False;  
                 res = res ? rdp_io_general_caps(s, &pdu->general_caps) : False;  
   
                 capset = RDP_CAPSET_BITMAP;  
                 res = res ? lsb_io_uint16(s, &capset) : False;  
                 res = res ? rdp_io_bitmap_caps (s, &pdu->bitmap_caps ) : False;  
   
                 capset = RDP_CAPSET_ORDER;  
                 res = res ? lsb_io_uint16(s, &capset) : False;  
                 res = res ? rdp_io_order_caps  (s, &pdu->order_caps  ) : False;  
   
                 capset = RDP_CAPSET_BMPCACHE;  
                 res = res ? lsb_io_uint16(s, &capset) : False;  
                 res = res ? rdp_io_bmpcache_caps(s, &pdu->bmpcache_caps) : False;  
   
                 capset = RDP_CAPSET_COLCACHE;  
                 res = res ? lsb_io_uint16(s, &capset) : False;  
                 res = res ? rdp_io_colcache_caps(s, &pdu->colcache_caps) : False;  
   
                 capset = RDP_CAPSET_ACTIVATE;  
                 res = res ? lsb_io_uint16(s, &capset) : False;  
                 res = res ? rdp_io_activate_caps(s, &pdu->activate_caps) : False;  
   
                 capset = RDP_CAPSET_CONTROL;  
                 res = res ? lsb_io_uint16(s, &capset) : False;  
                 res = res ? rdp_io_control_caps(s, &pdu->control_caps) : False;  
   
                 capset = RDP_CAPSET_POINTER;  
                 res = res ? lsb_io_uint16(s, &capset) : False;  
                 res = res ? rdp_io_pointer_caps(s, &pdu->pointer_caps) : False;  
   
                 capset = RDP_CAPSET_SHARE;  
                 res = res ? lsb_io_uint16(s, &capset) : False;  
                 res = res ? rdp_io_share_caps  (s, &pdu->share_caps  ) : False;  
   
                 capset = RDP_CAPSET_UNKNOWN;  
                 res = res ? lsb_io_uint16(s, &capset) : False;  
                 res = res ? rdp_io_unknown_caps(s, NULL) : False;  
         }  
         else  
         {  
                 for (i = 0; i < pdu->num_caps; i++)  
                 {  
                         if (!res)  
                                 return False;  
   
                         if (!lsb_io_uint16(s, &capset))  
                                 return False;  
   
                         switch (capset)  
                         {  
                         case RDP_CAPSET_GENERAL:  
                                 res = rdp_io_general_caps (s, &pdu->general_caps );  
                                 break;  
                         case RDP_CAPSET_BITMAP:  
                                 res = rdp_io_bitmap_caps  (s, &pdu->bitmap_caps  );  
                                 break;  
                         case RDP_CAPSET_ORDER:  
                                 res = rdp_io_order_caps   (s, &pdu->order_caps   );  
                                 break;  
                         case RDP_CAPSET_BMPCACHE:  
                                 res = rdp_io_bmpcache_caps(s, &pdu->bmpcache_caps);  
                                 break;  
                         case RDP_CAPSET_CONTROL:  
                                 res = rdp_io_control_caps (s, &pdu->control_caps );  
                                 break;  
                         case RDP_CAPSET_ACTIVATE:  
                                 res = rdp_io_activate_caps(s, &pdu->activate_caps);  
                                 break;  
                         case RDP_CAPSET_POINTER:  
                                 res = rdp_io_pointer_caps (s, &pdu->pointer_caps );  
                                 break;  
                         case RDP_CAPSET_SHARE:  
                                 res = rdp_io_share_caps   (s, &pdu->share_caps   );  
                                 break;  
                         case RDP_CAPSET_COLCACHE:  
                                 res = rdp_io_colcache_caps(s, &pdu->colcache_caps);  
                                 break;  
                         default:  
                                 fprintf(stderr, "Warning: Unrecognised capset %x\n",  
                                         capset);  
   
                                 if (!lsb_io_uint16(s, &length))  
                                         return False;  
   
                                 s->offset += (length - 4);  
                         }  
                 }  
775          }          }
776    
777          return res;          hmap = ui_create_colourmap(&map);
778  }          ui_set_colourmap(hmap);
   
 BOOL rdp_io_control_pdu(STREAM s, RDP_CONTROL_PDU *pdu)  
 {  
         BOOL res = True;  
   
         res = res ? lsb_io_uint16(s, &pdu->action   ) : False;  
         res = res ? lsb_io_uint16(s, &pdu->userid   ) : False;  
         res = res ? lsb_io_uint32(s, &pdu->controlid) : False;  
779    
780          return res;          xfree(map.colours);
781  }  }
782    
783  BOOL rdp_io_synchronize_pdu(STREAM s, RDP_SYNCHRONIZE_PDU *pdu)  /* Process an update PDU */
784    static void
785    process_update_pdu(STREAM s)
786  {  {
787          BOOL res = True;          uint16 update_type, count;
788    
789          res = res ? lsb_io_uint16(s, &pdu->type  ) : False;          in_uint16_le(s, update_type);
         res = res ? lsb_io_uint16(s, &pdu->userid) : False;  
790    
791          return res;          switch (update_type)
792  }          {
793                    case RDP_UPDATE_ORDERS:
794                            in_uint8s(s, 2);        /* pad */
795                            in_uint16_le(s, count);
796                            in_uint8s(s, 2);        /* pad */
797                            process_orders(s, count);
798                            break;
799    
800  BOOL rdp_io_input_event(STREAM s, RDP_INPUT_EVENT *evt)                  case RDP_UPDATE_BITMAP:
801  {                          process_bitmap_updates(s);
802          BOOL res = True;                          break;
803    
804          res = res ? lsb_io_uint32(s, &evt->event_time)   : False;                  case RDP_UPDATE_PALETTE:
805          res = res ? lsb_io_uint16(s, &evt->message_type) : False;                          process_palette(s);
806                            break;
807    
808          if (!res)                  case RDP_UPDATE_SYNCHRONIZE:
809                  return False;                          break;
810    
811          switch (evt->message_type)                  default:
812          {                          unimpl("update %d\n", update_type);
         case RDP_INPUT_CODEPOINT:  
         case RDP_INPUT_VIRTKEY:  
                 res = res ? lsb_io_uint16(s, &evt->device_flags) : False;  
                 res = res ? lsb_io_uint16(s, &evt->kbd_keycode ) : False;  
                 break;  
         case RDP_INPUT_SYNCHRONIZE:  
         case RDP_INPUT_UNKNOWN:  
         case RDP_INPUT_MOUSE:  
                 res = res ? lsb_io_uint16(s, &evt->device_flags) : False;  
                 res = res ? lsb_io_uint16(s, &evt->mouse_x     ) : False;  
                 res = res ? lsb_io_uint16(s, &evt->mouse_y     ) : False;  
                 break;  
         default:  
                 fprintf(stderr, "Unknown input type %d\n", evt->message_type);  
                 return False;  
813          }          }
814    
         return res;  
815  }  }
816    
817  BOOL rdp_io_input_pdu(STREAM s, RDP_INPUT_PDU *pdu)  /* Process data PDU */
818    static void
819    process_data_pdu(STREAM s)
820  {  {
821          BOOL res = True;          uint8 data_pdu_type;
         int i;  
822    
823          res = res ? lsb_io_uint16(s, &pdu->num_events) : False;          in_uint8s(s, 8);        /* shareid, pad, streamid, length */
824          res = res ? lsb_io_uint16(s, &pdu->pad       ) : False;          in_uint8(s, data_pdu_type);
825            in_uint8s(s, 3);        /* compress_type, compress_len */
         if (pdu->num_events > RDP_MAX_EVENTS)  
         {  
                 fprintf(stderr, "Too many events in one PDU\n");  
                 return False;  
         }  
826    
827          for (i = 0; i < pdu->num_events; i++)          switch (data_pdu_type)
828          {          {
829                  res = res ? rdp_io_input_event(s, &pdu->event[i]) : False;                  case RDP_DATA_PDU_UPDATE:
830          }                          process_update_pdu(s);
831                            break;
832    
833          return res;                  case RDP_DATA_PDU_POINTER:
834  }                          process_pointer_pdu(s);
835                            break;
836    
837  BOOL rdp_io_font_info(STREAM s, RDP_FONT_INFO *font)                  case RDP_DATA_PDU_BELL:
838  {                          ui_bell();
839          BOOL res = True;                          break;
840    
841          res = res ? prs_io_uint8s(s,  font->name, 32 ) : False;                  case RDP_DATA_PDU_LOGON:
842          res = res ? lsb_io_uint16(s, &font->flags    ) : False;                          DEBUG(("Received Logon PDU\n"));
843          res = res ? lsb_io_uint16(s, &font->width    ) : False;                          /* User logged on */
844          res = res ? lsb_io_uint16(s, &font->height   ) : False;                          break;
         res = res ? lsb_io_uint16(s, &font->xaspect  ) : False;  
         res = res ? lsb_io_uint16(s, &font->yaspect  ) : False;  
         res = res ? lsb_io_uint32(s, &font->signature) : False;  
         res = res ? lsb_io_uint16(s, &font->codepage ) : False;  
         res = res ? lsb_io_uint16(s, &font->ascent   ) : False;  
845    
846          return res;                  default:
847                            unimpl("data PDU %d\n", data_pdu_type);
848            }
849  }  }
850    
851  BOOL rdp_io_font_pdu(STREAM s, RDP_FONT_PDU *pdu)  /* Process incoming packets */
852    BOOL
853    rdp_main_loop(void)
854  {  {
855          BOOL res = True;          uint8 type;
856          int i;          STREAM s;
   
         res = res ? lsb_io_uint16(s, &pdu->num_fonts ) : False;  
         res = res ? lsb_io_uint16(s, &pdu->unknown1  ) : False;  
         res = res ? lsb_io_uint16(s, &pdu->unknown2  ) : False;  
         res = res ? lsb_io_uint16(s, &pdu->entry_size) : False;  
   
         if (pdu->num_fonts > RDP_MAX_FONTS)  
         {  
                 fprintf(stderr, "Too many fonts in one PDU\n");  
                 return False;  
         }  
857    
858          for (i = 0; i < pdu->num_fonts; i++)          while ((s = rdp_recv(&type)) != NULL)
859          {          {
860                  res = res ? rdp_io_font_info(s, &pdu->font[i]) : False;                  switch (type)
861          }                  {
862                            case RDP_PDU_DEMAND_ACTIVE:
863                                    process_demand_active(s);
864                                    break;
865    
866          return res;                          case RDP_PDU_DEACTIVATE:
867  }                                  DEBUG(("RDP_PDU_DEACTIVATE\n"));
868                                    return True;
869                                    break;
870    
871  BOOL rdp_io_update_pdu(STREAM s, RDP_UPDATE_PDU *pdu)                          case RDP_PDU_DATA:
872  {                                  process_data_pdu(s);
873          BOOL res = True;                                  break;
874    
875          res = res ? lsb_io_uint16(s, &pdu->update_type) : False;                          case 0:
876          res = res ? lsb_io_uint16(s, &pdu->pad        ) : False;                                  break;
877    
878          return res;                          default:
879                                    unimpl("PDU %d\n", type);
880                    }
881            }
882            return False;
883  }  }
884    
885  BOOL rdp_io_secondary_order(STREAM s, RDP_SECONDARY_ORDER *rso)  /* Establish a connection up to the RDP layer */
886    BOOL
887    rdp_connect(char *server, uint32 flags, char *domain, char *password,
888                char *command, char *directory)
889  {  {
890          BOOL res = True;          if (use_rdp5)
891                    channels_init();
892    
893          res = res ? lsb_io_uint16(s, &rso->length) : False;          if (!sec_connect(server, username))
894          res = res ? lsb_io_uint16(s, &rso->flags ) : False;                  return False;
         res = res ? prs_io_uint8 (s, &rso->type  ) : False;  
895    
896          return res;          rdp_send_logon_info(flags, domain, username, password, command, directory);
897            return True;
898  }  }
899    
900  BOOL rdp_io_bitmap_header(STREAM s, RDP_BITMAP_HEADER *rdh)  /* Disconnect from the RDP layer */
901    void
902    rdp_disconnect(void)
903  {  {
904          BOOL res = True;          sec_disconnect();
   
         res = res ? prs_io_uint8 (s, &rdh->cache_id  ) : False;  
         res = res ? prs_io_uint8 (s, &rdh->pad1      ) : False;  
         res = res ? prs_io_uint8 (s, &rdh->width     ) : False;  
         res = res ? prs_io_uint8 (s, &rdh->height    ) : False;  
         res = res ? prs_io_uint8 (s, &rdh->bpp       ) : False;  
         res = res ? lsb_io_uint16(s, &rdh->bufsize   ) : False;  
         res = res ? lsb_io_uint16(s, &rdh->cache_idx ) : False;  
         res = res ? lsb_io_uint16(s, &rdh->pad2      ) : False;  
         res = res ? lsb_io_uint16(s, &rdh->size      ) : False;  
         res = res ? lsb_io_uint16(s, &rdh->row_size  ) : False;  
         res = res ? lsb_io_uint16(s, &rdh->final_size) : False;  
   
         return res;  
905  }  }

Legend:
Removed from v.4  
changed lines
  Added in v.424

  ViewVC Help
Powered by ViewVC 1.1.26