/[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 7 by matty, Fri Jul 7 09:40:03 2000 UTC revision 426 by forsberg, Thu Jun 19 11:46:30 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          uint8 type;  extern BOOL desktop_save;
29    extern BOOL use_rdp5;
30    extern uint16 server_rdp_version;
31    
32          if ((conn = mcs_connect(server)) == NULL)  uint8 *next_packet;
33                  return NULL;  uint32 rdp_shareid;
34    
35          rdp_establish_key(conn);  #if WITH_DEBUG
36          mcs_recv(conn, False); /* Server's licensing certificate */  static uint32 packetno;
37          rdp_send_cert(conn);  #endif
         mcs_recv(conn, False);  
         mcs_recv(conn, False); /* Demand active */  
   
         if (!rdp_recv_pdu(conn, &type) || (type != RDP_PDU_DEMAND_ACTIVE))  
         {  
                 fprintf(stderr, "RDP error, expected Demand Active\n");  
                 mcs_disconnect(conn);  
                 return NULL;  
         }  
   
         rdp_io_active_pdu(&conn->in, &active, RDP_PDU_DEMAND_ACTIVE);  
         rdp_send_confirm_active(conn);  
         rdp_send_synchronize(conn);  
         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  
   
         return conn;  
 }  
38    
39  void rdp_main_loop(HCONN conn)  /* Receive an RDP packet */
40    static STREAM
41    rdp_recv(uint8 * type)
42  {  {
43          RDP_DATA_HEADER hdr;          static STREAM rdp_s;
44          RDP_ORDER_STATE os;          uint16 length, pdu_type;
         uint8 type;  
45    
46          memset(&os, 0, sizeof(os));          if ((rdp_s == NULL) || (next_packet >= rdp_s->end))
   
         while (rdp_recv_pdu(conn, &type))  
47          {          {
48                  if (type != RDP_PDU_DATA)                  rdp_s = sec_recv();
49                  {                  if (rdp_s == NULL)
50                          fprintf(stderr, "Unknown PDU 0x%x\n", type);                          return NULL;
                         continue;  
                 }  
   
                 rdp_io_data_header(&conn->in, &hdr);  
51    
52                  switch (hdr.data_pdu_type)                  next_packet = rdp_s->p;
                 {  
                         case RDP_DATA_PDU_UPDATE:  
                                 process_update(conn, &os);  
                                 break;  
   
                         case RDP_DATA_PDU_POINTER:  
                                 process_pointer(conn);  
                                 break;  
   
                         default:  
                                 fprintf(stderr, "Unknown data PDU 0x%x\n",  
                                                 hdr.data_pdu_type);  
                 }  
53          }          }
54  }          else
   
 void process_memblt(HCONN conn, RDP_ORDER_STATE *os, BOOL delta)  
 {  
         HBITMAP hbitmap;  
         uint16 present;  
         lsb_io_uint16(&conn->in, &present);  
   
         if (present & 1)  
                 prs_io_uint8(&conn->in, &os->memblt.cache_id);  
   
         if (present & 2)  
                 rdp_io_coord(&conn->in, &os->memblt.x, delta);  
   
         if (present & 4)  
                 rdp_io_coord(&conn->in, &os->memblt.y, delta);  
   
         if (present & 8)  
                 rdp_io_coord(&conn->in, &os->memblt.cx, delta);  
   
         if (present & 16)  
                 rdp_io_coord(&conn->in, &os->memblt.cy, delta);  
   
         if (present & 32)  
                 prs_io_uint8(&conn->in, &os->memblt.opcode);  
   
         if (present & 256)  
                 lsb_io_uint16(&conn->in, &os->memblt.cache_idx);  
   
         if (os->memblt.opcode != 0xcc) /* SRCCOPY */  
55          {          {
56                  fprintf(stderr, "Unsupported raster operation 0x%x\n",                  rdp_s->p = next_packet;
                         os->memblt.opcode);  
                 return;  
57          }          }
58    
59          if ((os->memblt.cache_idx > NUM_ELEMENTS(conn->bmpcache))          in_uint16_le(rdp_s, length);
60              || ((hbitmap = conn->bmpcache[os->memblt.cache_idx]) == NULL))          /* 32k packets are really 8, keepalive fix */
61            if (length == 0x8000)
62          {          {
63                  fprintf(stderr, "Bitmap %d not found\n", os->memblt.cache_idx);                  next_packet += 8;
64                  return;                  *type = 0;
65                    return rdp_s;
66          }          }
67            in_uint16_le(rdp_s, pdu_type);
68            in_uint8s(rdp_s, 2);    /* userid */
69            *type = pdu_type & 0xf;
70    
71          fprintf(stderr, "MEMBLT %d:%dx%d\n", os->memblt.cache_idx,  #if WITH_DEBUG
72                                          os->memblt.x, os->memblt.y);          DEBUG(("RDP packet #%d, (type %x)\n", ++packetno, *type));
73            //      hexdump(next_packet, length);
74    #endif /*  */
75    
76          ui_paint_bitmap(conn->wnd, hbitmap, os->memblt.x, os->memblt.y);          next_packet += length;
77            return rdp_s;
78  }  }
79    
80  void process_opaque_rect(HCONN conn, RDP_ORDER_STATE *os, BOOL delta)  /* Initialise an RDP data packet */
81    static STREAM
82    rdp_init_data(int maxlen)
83  {  {
84          uint8 present;          STREAM s;
         prs_io_uint8(&conn->in, &present);  
85    
86          if (present & 1)          s = sec_init(encryption ? SEC_ENCRYPT : 0, maxlen + 18);
87                  rdp_io_coord(&conn->in, &os->opaque_rect.x, delta);          s_push_layer(s, rdp_hdr, 18);
88    
89          if (present & 2)          return s;
90                  rdp_io_coord(&conn->in, &os->opaque_rect.y, delta);  }
91    
92    /* Send an RDP data packet */
93    static void
94    rdp_send_data(STREAM s, uint8 data_pdu_type)
95    {
96            uint16 length;
97    
98          if (present & 4)          s_pop_layer(s, rdp_hdr);
99                  rdp_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                  rdp_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);
         ui_draw_rectangle(conn->wnd, os->opaque_rect.x, os->opaque_rect.y,  
                                 os->opaque_rect.cx, os->opaque_rect.cy);  
114  }  }
115    
116  void process_bmpcache(HCONN conn)  /* Output a string in Unicode */
117    void
118    rdp_out_unistr(STREAM s, char *string, int len)
119  {  {
120          RDP_BITMAP_HEADER rbh;          int i = 0, j = 0;
         HBITMAP *entry;  
         char *input, *bmpdata;  
   
         rdp_io_bitmap_header(&conn->in, &rbh);  
         fprintf(stderr, "BMPCACHE %d:%dx%d\n", rbh.cache_idx,  
                                 rbh.width, rbh.height);  
   
         input = conn->in.data + conn->in.offset;  
         conn->in.offset += rbh.size;  
 //      dump_data(conn->in.data+conn->in.offset, conn->in.rdp_offset-conn->in.offset);  
121    
122          bmpdata = malloc(rbh.width * rbh.height);          len += 2;
         if (!bitmap_decompress(bmpdata, rbh.width, rbh.height, input, rbh.size))  
         {  
                 fprintf(stderr, "Decompression failed\n");  
                 free(bmpdata);  
                 return;  
         }  
123    
124          if (rbh.cache_idx > NUM_ELEMENTS(conn->bmpcache))          while (i < len)
125          {          {
126                  fprintf(stderr, "Attempted store past end of cache");                  s->p[i++] = string[j++];
127                  return;                  s->p[i++] = 0;
128          }          }
129    
130          entry = &conn->bmpcache[rbh.cache_idx];          s->p += len;
         // if (*entry != NULL)  
         //      ui_destroy_bitmap(conn->wnd, *entry);  
   
         *entry = ui_create_bitmap(conn->wnd, rbh.width, rbh.height, bmpdata);  
         //      ui_paint_bitmap(conn->wnd, bmp, x, 0);  
         //      ui_destroy_bitmap(conn->wnd, bmp);  
131  }  }
132    
133  void process_orders(HCONN conn, RDP_ORDER_STATE *os)  /* Parse a logon info packet */
134    static void
135    rdp_send_logon_info(uint32 flags, char *domain, char *user,
136                        char *password, char *program, char *directory)
137  {  {
138          uint16 num_orders;          int len_domain = 2 * strlen(domain);
139          int processed = 0;          int len_user = 2 * strlen(user);
140          BOOL res = True;          int len_password = 2 * strlen(password);
141          BOOL delta;          int len_program = 2 * strlen(program);
142          //      unsigned char *p;          int len_directory = 2 * strlen(directory);
143            int len_ip = 2 * strlen("127.0.0.1");
144          lsb_io_uint16(&conn->in, &num_orders);          int len_dll = 2 * strlen("C:\\WINNT\\System32\\mstscax.dll");
145            int packetlen = 0;
146          conn->in.offset += 2;          uint32 sec_flags = encryption ? (SEC_LOGON_INFO | SEC_ENCRYPT) : SEC_LOGON_INFO;
147          //      p = &conn->in.data[conn->in.offset];          STREAM s;
148    
149          //      fprintf(stderr, "%02X %02X %02X %02X\n", p[0], p[1], p[2], p[3]);          if (!use_rdp5 || 1 == server_rdp_version)
   
         while ((processed < num_orders) && res)  
150          {          {
151                  uint8 order_flags;                  DEBUG_RDP5(("Sending RDP4-style Logon packet\n"));
   
                 prs_io_uint8(&conn->in, &order_flags);  
                 fprintf(stderr, "Order flags: 0x%x\n", order_flags);  
   
                 if (order_flags == 0x51) /* ?? */  
                         return;  
152    
153                  if (!(order_flags & RDP_ORDER_STANDARD))                  s = sec_init(sec_flags, 18 + len_domain + len_user + len_password
154                          return;                               + len_program + len_directory + 10);
155    
156                  if (order_flags & RDP_ORDER_SECONDARY)                  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                          RDP_SECONDARY_ORDER rso;                          out_uint16_le(s, len_password);
206    
                         rdp_io_secondary_order(&conn->in, &rso);  
                         switch (rso.type)  
                         {  
                         case RDP_ORDER_BMPCACHE:  
                                 process_bmpcache(conn);  
                                 break;  
                         default:  
                                 fprintf(stderr, "Unknown secondary order %d\n",  
                                         rso.type);  
                                 return;  
                         }  
207                  }                  }
208                    if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO))
209                    {
210                            out_uint16_le(s, 0);
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                  else
217                            out_uint16_le(s, 0);
218                    rdp_out_unistr(s, user, len_user);
219                    if (flags & RDP_LOGON_AUTO)
220                  {                  {
221                          if (order_flags & RDP_ORDER_CHANGE)                          rdp_out_unistr(s, password, len_password);
222                                  prs_io_uint8(&conn->in, &os->order_type);                  }
223                    if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO))
224                          delta = order_flags & RDP_ORDER_DELTA;                  {
225                            out_uint16_le(s, 0);
226                          switch (os->order_type)                  }
227                          {                  if (0 < len_program)
228                          case RDP_ORDER_OPAQUE_RECT:                  {
229                                  process_opaque_rect(conn, os, delta);                          rdp_out_unistr(s, program, len_program);
                                 break;  
   
                         case RDP_ORDER_MEMBLT:  
                                 process_memblt(conn, os, delta);  
                                 break;  
230    
                         default:  
                                 fprintf(stderr, "Unknown order %d\n", os->order_type);  
                                 return;  
                         }  
231                  }                  }
232                    else
233                    {
234                            out_uint16_le(s, 0);
235                    }
236                    if (0 < len_directory)
237                    {
238                            rdp_out_unistr(s, directory, len_directory);
239                    }
240                    else
241                    {
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    
                 processed++;  
         }  
 }  
254    
255  void process_palette(HCONN conn)                  out_uint32_le(s, 0x0a0000);
256  {                  out_uint32_le(s, 0x050000);
257          HCOLORMAP map;                  out_uint32_le(s, 3);
258          COLORMAP colors;                  out_uint32_le(s, 0);
259                    out_uint32_le(s, 0);
260    
261          rdp_io_colormap(&conn->in, &colors);                  rdp_out_unistr(s, "GTB, sommartid", 2 * strlen("GTB, sommartid"));
262          map = ui_create_colormap(conn->wnd, &colors);                  out_uint8s(s, 62 - 2 * strlen("GTB, sommartid"));
         ui_set_colormap(conn->wnd, map);  
         // ui_destroy_colormap(map);  
 }  
263    
264  void process_update(HCONN conn, RDP_ORDER_STATE *os)                  out_uint32_le(s, 0x30000);
265  {                  out_uint32_le(s, 0x050000);
266          RDP_UPDATE_PDU update;                  out_uint32_le(s, 2);
267                    out_uint32(s, 0);
268                    out_uint32_le(s, 0xffffffc4);
269                    out_uint32_le(s, 0xfffffffe);
270                    out_uint32_le(s, 0x0f);
271                    out_uint32(s, 0);
272    
         rdp_io_update_pdu(&conn->in, &update);  
         switch (update.update_type)  
         {  
                 case RDP_UPDATE_ORDERS:  
                         process_orders(conn, os);  
                         break;  
                 case RDP_UPDATE_PALETTE:  
                         process_palette(conn);  
                         break;  
                 case RDP_UPDATE_SYNCHRONIZE:  
                         break;  
                 default:  
                         fprintf(stderr, "Unknown update 0x%x\n",  
                                 update.update_type);  
         }  
273    
274            }
275            s_mark_end(s);
276            sec_send(s, sec_flags);
277  }  }
278    
279  void process_pointer(HCONN conn)  /* Send a control PDU */
280    static void
281    rdp_send_control(uint16 action)
282  {  {
283          RDP_POINTER ptr;          STREAM s;
   
         rdp_io_pointer(&conn->in, &ptr);  
   
         switch (ptr.message)  
         {  
                 case RDP_POINTER_MOVE:  
                         ui_move_pointer(conn->wnd, ptr.x, ptr.y);  
                         break;  
                 default:  
                         fprintf(stderr, "Unknown pointer message 0x%x\n",  
                                 ptr.message);  
         }  
 }  
284    
285  /* Work this out later. This is useless anyway when encryption is off. */          s = rdp_init_data(8);
 uint8 precanned_key_packet[] = {  
    0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x00,0x00,0x00,0x00,0x00,  
    0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6c,0x86,  
    0xf7,0x99,0xef,0x60,0xc4,0x49,0x52,0xd0,0xd8,0xea,0xb5,0x4f,0x58,0x19,  
    0x52,0x2a,0x93,0x83,0x57,0x4f,0x4e,0x04,0xde,0x96,0x51,0xab,0x13,0x20,  
    0xd8,0xe5,0x00,0x00,0x00,0x00,0x00,0x00  
 };  
286    
287  /* Create an RC4 key and transfer it to the server */          out_uint16_le(s, action);
288  void rdp_establish_key(HCONN conn)          out_uint16(s, 0);       /* userid */
289  {          out_uint32(s, 0);       /* control id */
         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  
 };  
290    
291  /* Send license certificate and related data to the server */          s_mark_end(s);
292  void rdp_send_cert(HCONN conn)          rdp_send_data(s, RDP_DATA_PDU_CONTROL);
 {  
         mcs_init_data(conn);  
         prs_io_uint8s(&conn->out, precanned_cert_packet, sizeof(precanned_cert_packet));  
         MARK_END(conn->out);  
         mcs_send_data(conn, MCS_GLOBAL_CHANNEL, True);  
293  }  }
294    
295  /* Initialise RDP transport packet */  /* Send a synchronisation PDU */
296  void rdp_init(HCONN conn)  static void
297    rdp_send_synchronise(void)
298  {  {
299          mcs_init_data(conn);          STREAM s;
         PUSH_LAYER(conn->out, rdp_offset, 6);  
 }  
300    
301  /* Transmit RDP transport packet */          s = rdp_init_data(4);
 void rdp_send(HCONN conn, uint16 pdu_type)  
 {  
         RDP_HEADER hdr;  
         int length;  
302    
303          POP_LAYER(conn->out, rdp_offset);          out_uint16_le(s, 1);    /* type */
304          length = conn->out.end - conn->out.offset;          out_uint16_le(s, 1002);
         rdp_make_header(&hdr, length, pdu_type, conn->mcs_userid);  
         rdp_io_header(&conn->out, &hdr);  
         mcs_send_data(conn, MCS_GLOBAL_CHANNEL, True);  
 }  
305    
306  /* Initialise RDP transport data packet */          s_mark_end(s);
307  void rdp_init_data(HCONN conn)          rdp_send_data(s, RDP_DATA_PDU_SYNCHRONISE);
 {  
         mcs_init_data(conn);  
         PUSH_LAYER(conn->out, rdp_offset, 18);  
308  }  }
309    
310  /* Transmit RDP transport data packet */  /* Send a single input event */
311  void rdp_send_data(HCONN conn, uint16 data_pdu_type)  void
312    rdp_send_input(uint32 time, uint16 message_type, uint16 device_flags, uint16 param1, uint16 param2)
313  {  {
314          RDP_HEADER hdr;          STREAM s;
         RDP_DATA_HEADER datahdr;  
         int length = conn->out.end - conn->out.offset;  
315    
316          POP_LAYER(conn->out, rdp_offset);          s = rdp_init_data(16);
         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);  
 }  
317    
318  void rdp_send_confirm_active(HCONN conn)          out_uint16_le(s, 1);    /* number of events */
319  {          out_uint16(s, 0);       /* pad */
         RDP_ACTIVE_PDU active;  
320    
321          rdp_init(conn);          out_uint32_le(s, time);
322          rdp_make_active_pdu(&active, 0x103ea, conn->mcs_userid);          out_uint16_le(s, message_type);
323          rdp_io_active_pdu(&conn->out, &active, RDP_PDU_CONFIRM_ACTIVE);          out_uint16_le(s, device_flags);
324          MARK_END(conn->out);          out_uint16_le(s, param1);
325          rdp_send(conn, RDP_PDU_CONFIRM_ACTIVE);          out_uint16_le(s, param2);
326    
327            s_mark_end(s);
328            rdp_send_data(s, RDP_DATA_PDU_INPUT);
329  }  }
330    
331  void rdp_send_synchronize(HCONN conn)  /* Send an (empty) font information PDU */
332    static void
333    rdp_send_fonts(uint16 seq)
334  {  {
335          RDP_SYNCHRONIZE_PDU sync;          STREAM s;
336    
337          rdp_init_data(conn);          s = rdp_init_data(8);
         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);  
 }  
338    
339  void rdp_send_control(HCONN conn, uint16 action)          out_uint16(s, 0);       /* number of fonts */
340  {          out_uint16_le(s, 0x3e); /* unknown */
341          RDP_CONTROL_PDU control;          out_uint16_le(s, seq);  /* unknown */
342            out_uint16_le(s, 0x32); /* entry size */
343    
344          rdp_init_data(conn);          s_mark_end(s);
345          rdp_make_control_pdu(&control, action);          rdp_send_data(s, RDP_DATA_PDU_FONT2);
         rdp_io_control_pdu(&conn->out, &control);  
         MARK_END(conn->out);  
         rdp_send_data(conn, RDP_DATA_PDU_CONTROL);  
346  }  }
347    
348  void rdp_send_fonts(HCONN conn, uint16 seqno)  /* Output general capability set */
349    static void
350    rdp_out_general_caps(STREAM s)
351  {  {
352          RDP_FONT_PDU fonts;          out_uint16_le(s, RDP_CAPSET_GENERAL);
353            out_uint16_le(s, RDP_CAPLEN_GENERAL);
354    
355          rdp_init_data(conn);          out_uint16_le(s, 1);    /* OS major type */
356          rdp_make_font_pdu(&fonts, seqno);          out_uint16_le(s, 3);    /* OS minor type */
357          rdp_io_font_pdu(&conn->out, &fonts);          out_uint16_le(s, 0x200);        /* Protocol version */
358          MARK_END(conn->out);          out_uint16(s, 0);       /* Pad */
359          rdp_send_data(conn, RDP_DATA_PDU_FONT2);          out_uint16(s, 0);       /* Compression types */
360            out_uint16_le(s, use_rdp5 ? 0x40d : 0);
361            /* Pad, according to T.128. 0x40d seems to
362               trigger
363               the server to start sending RDP5 packets.
364               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_send_input(HCONN conn)  /* Output bitmap capability set */
375    static void
376    rdp_out_bitmap_caps(STREAM s)
377  {  {
378          RDP_INPUT_PDU input;          out_uint16_le(s, RDP_CAPSET_BITMAP);
379            out_uint16_le(s, RDP_CAPLEN_BITMAP);
380    
381          rdp_init_data(conn);          out_uint16_le(s, 8);    /* Preferred BPP */
382          rdp_make_input_pdu(&input);          out_uint16_le(s, 1);    /* Receive 1 BPP */
383          rdp_io_input_pdu(&conn->out, &input);          out_uint16_le(s, 1);    /* Receive 4 BPP */
384          MARK_END(conn->out);          out_uint16_le(s, 1);    /* Receive 8 BPP */
385          rdp_send_data(conn, RDP_DATA_PDU_INPUT);          out_uint16_le(s, 800);  /* Desktop width */
386            out_uint16_le(s, 600);  /* Desktop height */
387            out_uint16(s, 0);       /* Pad */
388            out_uint16(s, 0);       /* Allow resize */
389            out_uint16_le(s, bitmap_compression ? 1 : 0);   /* Support compression */
390            out_uint16(s, 0);       /* Unknown */
391            out_uint16_le(s, 1);    /* Unknown */
392            out_uint16(s, 0);       /* Pad */
393  }  }
394    
395  BOOL rdp_recv_pdu(HCONN conn, uint8 *type)  /* Output order capability set */
396    static void
397    rdp_out_order_caps(STREAM s)
398  {  {
399          RDP_HEADER hdr;          uint8 order_caps[32];
400    
         conn->in.offset = conn->in.rdp_offset;  
   
         if (conn->in.offset >= conn->in.end)  
         {  
                 if (!mcs_recv(conn, False))  
                         return False;  
         }  
   
         if (!rdp_io_header(&conn->in, &hdr))  
                 return False;  
401    
402          conn->in.rdp_offset += hdr.length;          memset(order_caps, 0, 32);
403          *type = hdr.pdu_type & 0xf;          order_caps[0] = 1;      /* dest blt */
404            order_caps[1] = 1;      /* pat blt */
405            order_caps[2] = 1;      /* screen blt */
406            order_caps[3] = 1;      /* required for memblt? */
407            order_caps[8] = 1;      /* line */
408            order_caps[9] = 1;      /* line */
409            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  #if DEBUG          out_uint8s(s, 20);      /* Terminal desc, pad */
419          fprintf(stderr, "RDP packet (type %x):\n", *type);          out_uint16_le(s, 1);    /* Cache X granularity */
420          dump_data(conn->in.data+conn->in.offset, conn->in.rdp_offset-conn->in.offset);          out_uint16_le(s, 20);   /* Cache Y granularity */
421  #endif          out_uint16(s, 0);       /* Pad */
422            out_uint16_le(s, 1);    /* Max order level */
423          return True;          out_uint16_le(s, 0x147);        /* Number of fonts */
424            out_uint16_le(s, 0x2a); /* Capability flags */
425            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  /* Disconnect from the RDP layer */  /* Output bitmap cache capability set */
434  void rdp_disconnect(HCONN conn)  static void
435    rdp_out_bmpcache_caps(STREAM s)
436  {  {
437          mcs_disconnect(conn);          out_uint16_le(s, RDP_CAPSET_BMPCACHE);
438  }          out_uint16_le(s, RDP_CAPLEN_BMPCACHE);
439    
440  void rdp_make_header(RDP_HEADER *hdr, uint16 length, uint16 pdu_type,          out_uint8s(s, 24);      /* unused */
441                       uint16 userid)          out_uint16_le(s, 0x258);        /* entries */
442  {          out_uint16_le(s, 0x100);        /* max cell size */
443          hdr->length = length;          out_uint16_le(s, 0x12c);        /* entries */
444          hdr->pdu_type = pdu_type | 0x10; /* Version 1 */          out_uint16_le(s, 0x400);        /* max cell size */
445          hdr->userid = userid + 1001;          out_uint16_le(s, 0x106);        /* entries */
446            out_uint16_le(s, 0x1000);       /* max cell size */
447  }  }
448    
449  void rdp_make_data_header(RDP_DATA_HEADER *hdr, uint32 shareid,  /* Output control capability set */
450                            uint16 length, uint16 data_pdu_type)  static void
451    rdp_out_control_caps(STREAM s)
452  {  {
453          hdr->shareid = shareid;          out_uint16_le(s, RDP_CAPSET_CONTROL);
454          hdr->pad = 0;          out_uint16_le(s, RDP_CAPLEN_CONTROL);
         hdr->streamid = 1;  
         hdr->length = length - 14;  
         hdr->data_pdu_type = data_pdu_type;  
         hdr->compress_type = 0;  
         hdr->compress_len = 0;  
 }  
455    
456  void rdp_make_general_caps(RDP_GENERAL_CAPS *caps)          out_uint16(s, 0);       /* Control capabilities */
457  {          out_uint16(s, 0);       /* Remote detach */
458          caps->os_major_type = 1;          out_uint16_le(s, 2);    /* Control interest */
459          caps->os_minor_type = 3;          out_uint16_le(s, 2);    /* Detach interest */
         caps->ver_protocol = 0x200;  
460  }  }
461    
462  void rdp_make_bitmap_caps(RDP_BITMAP_CAPS *caps)  /* Output activation capability set */
463    static void
464    rdp_out_activate_caps(STREAM s)
465  {  {
466          caps->preferred_bpp = 8;          out_uint16_le(s, RDP_CAPSET_ACTIVATE);
467          caps->receive1bpp = 1;          out_uint16_le(s, RDP_CAPLEN_ACTIVATE);
468          caps->receive4bpp = 1;  
469          caps->receive8bpp = 1;          out_uint16(s, 0);       /* Help key */
470          caps->width = 640;          out_uint16(s, 0);       /* Help index key */
471          caps->height = 480;          out_uint16(s, 0);       /* Extended help key */
472          caps->compression = 1;          out_uint16(s, 0);       /* Window activate */
         caps->unknown2 = 1;  
473  }  }
474    
475  void rdp_make_order_caps(RDP_ORDER_CAPS *caps)  /* Output pointer capability set */
476    static void
477    rdp_out_pointer_caps(STREAM s)
478  {  {
479          caps->xgranularity = 1;          out_uint16_le(s, RDP_CAPSET_POINTER);
480          caps->ygranularity = 20;          out_uint16_le(s, RDP_CAPLEN_POINTER);
         caps->max_order_level = 1;  
         caps->num_fonts = 0x147;  
         caps->cap_flags = 0x2A;  
   
 //      caps->cap_flags = ORDER_CAP_NEGOTIATE | ORDER_CAP_NOSUPPORT;  
481    
482          caps->support[0] = caps->support[1] = caps->support[2]          out_uint16(s, 0);       /* Colour pointer */
483                  = caps->support[3] = caps->support[4] = caps->support[5]          out_uint16_le(s, 20);   /* Cache size */
                 = caps->support[6] = caps->support[8] = caps->support[11]  
                 = caps->support[12] = caps->support[22] = caps->support[28]  
                 = caps->support[29] = caps->support[30] = 1;  
         caps->text_cap_flags = 0x6A1;  
         caps->desk_save_size = 0x38400;  
         caps->unknown2 = 0x4E4;  
484  }  }
485    
486  void rdp_make_bmpcache_caps(RDP_BMPCACHE_CAPS *caps)  /* Output share capability set */
487    static void
488    rdp_out_share_caps(STREAM s)
489  {  {
490          caps->caches[0].entries = 0x258;          out_uint16_le(s, RDP_CAPSET_SHARE);
491          caps->caches[0].max_cell_size = 0x100;          out_uint16_le(s, RDP_CAPLEN_SHARE);
         caps->caches[1].entries = 0x12c;  
         caps->caches[1].max_cell_size = 0x400;  
         caps->caches[2].entries = 0x106;  
         caps->caches[2].max_cell_size = 0x1000;  
 }  
492    
493  void rdp_make_control_caps(RDP_CONTROL_CAPS *caps)          out_uint16(s, 0);       /* userid */
494  {          out_uint16(s, 0);       /* pad */
         caps->control_interest = 2;  
         caps->detach_interest = 2;  
495  }  }
496    
497  void rdp_make_activate_caps(RDP_ACTIVATE_CAPS *caps)  /* Output colour cache capability set */
498    static void
499    rdp_out_colcache_caps(STREAM s)
500  {  {
501  }          out_uint16_le(s, RDP_CAPSET_COLCACHE);
502            out_uint16_le(s, RDP_CAPLEN_COLCACHE);
503    
504  void rdp_make_pointer_caps(RDP_POINTER_CAPS *caps)          out_uint16_le(s, 6);    /* cache size */
505  {          out_uint16(s, 0);       /* pad */
         caps->colour_pointer = 0;  
         caps->cache_size = 20;  
506  }  }
507    
508  void rdp_make_share_caps(RDP_SHARE_CAPS *caps, uint16 userid)  static uint8 canned_caps[] = {
509  {          0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x04,
510  }          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
511            0x00, 0x00, 0x00, 0x00, 0x00,
512            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
513            0x00, 0x00, 0x00, 0x00, 0x00,
514            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
515            0x00, 0x00, 0x00, 0x00, 0x00,
516            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
517            0x00, 0x00, 0x00, 0x00, 0x00,
518            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
519            0x0C, 0x00, 0x08, 0x00, 0x01,
520            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  void rdp_make_colcache_caps(RDP_COLCACHE_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          caps->cache_size = 6;          uint8 type;
 }  
588    
589  void rdp_make_active_pdu(RDP_ACTIVE_PDU *pdu, uint32 shareid, uint16 userid)          in_uint32_le(s, rdp_shareid);
 {  
         memset(pdu, 0, sizeof(*pdu));  
         pdu->shareid = shareid;  
         pdu->userid  = 1002;  
         pdu->source_len = sizeof(RDP_SOURCE);  
         memcpy(pdu->source, RDP_SOURCE, sizeof(RDP_SOURCE));  
590    
591          pdu->caps_len = RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER          DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", rdp_shareid));
                 + 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;  
592    
593          rdp_make_general_caps (&pdu->general_caps );          rdp_send_confirm_active();
594          rdp_make_bitmap_caps  (&pdu->bitmap_caps  );          rdp_send_synchronise();
595          rdp_make_order_caps   (&pdu->order_caps   );          rdp_send_control(RDP_CTL_COOPERATE);
596          rdp_make_bmpcache_caps(&pdu->bmpcache_caps);          rdp_send_control(RDP_CTL_REQUEST_CONTROL);
597          rdp_make_control_caps (&pdu->control_caps );          rdp_recv(&type);        /* RDP_PDU_SYNCHRONIZE */
598          rdp_make_activate_caps(&pdu->activate_caps);          rdp_recv(&type);        /* RDP_CTL_COOPERATE */
599          rdp_make_pointer_caps (&pdu->pointer_caps );          rdp_recv(&type);        /* RDP_CTL_GRANT_CONTROL */
600          rdp_make_share_caps   (&pdu->share_caps, userid);          rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, 0, 0);
601          rdp_make_colcache_caps(&pdu->colcache_caps);          rdp_send_fonts(1);
602            rdp_send_fonts(2);
603            rdp_recv(&type);        /* RDP_PDU_UNKNOWN 0x28 */
604            reset_order_state();
605  }  }
606    
607  void rdp_make_control_pdu(RDP_CONTROL_PDU *pdu, uint16 action)  /* Process a null system pointer PDU */
608    void
609    process_null_system_pointer_pdu(STREAM s)
610  {  {
611          pdu->action = action;          // FIXME: We should probably set another cursor here,
612          pdu->userid = 0;          // like the X window system base cursor or something.
613          pdu->controlid = 0;          ui_set_cursor(cache_get_cursor(0));
614  }  }
615    
616  void rdp_make_synchronize_pdu(RDP_SYNCHRONIZE_PDU *pdu, uint16 userid)  /* Process a colour pointer PDU */
617    void
618    process_colour_pointer_pdu(STREAM s)
619  {  {
620          pdu->type = 1;          uint16 x, y, width, height, cache_idx, masklen, datalen;
621          pdu->userid = userid;          uint8 *mask, *data;
622  }          HCURSOR cursor;
623    
624  void rdp_make_font_pdu(RDP_FONT_PDU *pdu, uint16 seqno)          in_uint16_le(s, cache_idx);
625  {          in_uint16_le(s, x);
626          pdu->num_fonts = 0;          in_uint16_le(s, y);
627          pdu->unknown1 = 0x3e;          in_uint16_le(s, width);
628          pdu->unknown2 = seqno;          in_uint16_le(s, height);
629          pdu->entry_size = RDP_FONT_INFO_SIZE;          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  void rdp_make_input_pdu(RDP_INPUT_PDU *pdu)  /* Process a cached pointer PDU */
639    void
640    process_cached_pointer_pdu(STREAM s)
641  {  {
642          uint32 now = time(NULL);          uint16 cache_idx;
   
         pdu->num_events = 3;  
         pdu->pad = 0;  
   
         pdu->event[0].event_time = now;  
         pdu->event[0].message_type = RDP_INPUT_SYNCHRONIZE;  
         pdu->event[0].device_flags = 0;  
         pdu->event[0].mouse_x = 0;  
         pdu->event[0].mouse_y = 0;  
643    
644          pdu->event[1].event_time = now;          in_uint16_le(s, cache_idx);
645          pdu->event[1].message_type = RDP_INPUT_UNKNOWN;          ui_set_cursor(cache_get_cursor(cache_idx));
         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;  
646  }  }
647    
 BOOL rdp_io_header(STREAM s, RDP_HEADER *hdr)  
 {  
         BOOL res = True;  
   
         res = res ? lsb_io_uint16(s, &hdr->length  ) : False;  
         res = res ? lsb_io_uint16(s, &hdr->pdu_type) : False;  
         res = res ? lsb_io_uint16(s, &hdr->userid  ) : False;  
   
         return res;  
 }  
648    
649  BOOL rdp_io_data_header(STREAM s, RDP_DATA_HEADER *hdr)  /* Process a pointer PDU */
650    static void
651    process_pointer_pdu(STREAM s)
652  {  {
653          BOOL res = True;          uint16 message_type;
654            uint16 x, y;
         res = res ? lsb_io_uint32(s, &hdr->shareid      ) : False;  
         res = res ? prs_io_uint8 (s, &hdr->pad          ) : False;  
         res = res ? prs_io_uint8 (s, &hdr->streamid     ) : False;  
         res = res ? lsb_io_uint16(s, &hdr->length       ) : False;  
         res = res ? prs_io_uint8 (s, &hdr->data_pdu_type) : False;  
         res = res ? prs_io_uint8 (s, &hdr->compress_type) : False;  
         res = res ? lsb_io_uint16(s, &hdr->compress_len ) : False;  
   
         return res;  
 }  
655    
656  BOOL rdp_io_coord(STREAM s, uint16 *coord, BOOL delta)          in_uint16_le(s, message_type);
657  {          in_uint8s(s, 2);        /* pad */
         uint8 change;  
         BOOL res;  
658    
659          if (delta)          switch (message_type)
         {  
                 res = prs_io_uint8(s, &change);  
                 *coord += change;  
         }  
         else  
660          {          {
661                  res = lsb_io_uint16(s, coord);                  case RDP_POINTER_MOVE:
662          }                          in_uint16_le(s, x);
663                            in_uint16_le(s, y);
664          return res;                          if (s_check(s))
665  }                                  ui_move_pointer(x, y);
666                            break;
 BOOL rdp_io_colormap(STREAM s, COLORMAP *colors)  
 {  
         int datasize;  
667    
668          lsb_io_uint16(s, &colors->ncolors);                  case RDP_POINTER_COLOR:
669          datasize = colors->ncolors * 3;                          process_colour_pointer_pdu(s);
670                            break;
671    
672          if (datasize > sizeof(colors->colors))                  case RDP_POINTER_CACHED:
673                  return False;                          process_cached_pointer_pdu(s);
674                            break;
675    
676          memcpy(colors->colors, s->data + s->offset, datasize);                  default:
677          s->offset += datasize;                          DEBUG(("Pointer message 0x%x\n", message_type));
678          return True;          }
679  }  }
680    
681  BOOL rdp_io_general_caps(STREAM s, RDP_GENERAL_CAPS *caps)  /* Process bitmap updates */
682    void
683    process_bitmap_updates(STREAM s)
684  {  {
685          uint16 length = RDP_CAPLEN_GENERAL;          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          res = lsb_io_uint16(s, &pkt_length);          int i;
         if (pkt_length != length)  
         {  
                 fprintf(stderr, "Unrecognised capabilities size\n");  
                 return False;  
         }  
690    
691          res = res ? lsb_io_uint16(s, &caps->os_major_type ) : False;          in_uint16_le(s, num_updates);
         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;  
692    
693          res = lsb_io_uint16(s, &pkt_length);          for (i = 0; i < num_updates; i++)
         if (pkt_length != length)  
694          {          {
695                  fprintf(stderr, "Unrecognised capabilities size\n");                  in_uint16_le(s, left);
696                  return False;                  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          res = res ? lsb_io_uint16(s, &caps->preferred_bpp) : False;                  cx = right - left + 1;
707          res = res ? lsb_io_uint16(s, &caps->receive1bpp  ) : False;                  cy = bottom - top + 1;
         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;  
708    
709          res = lsb_io_uint16(s, &pkt_length);                  DEBUG(("BITMAP_UPDATE(l=%d,t=%d,r=%d,b=%d,w=%d,h=%d,Bpp=%d,cmp=%d)\n",
710          if (pkt_length != length)                         left, top, right, bottom, width, height, Bpp, compress));
         {  
                 fprintf(stderr, "Unrecognised capabilities size\n");  
                 return False;  
         }  
   
         res = res ? prs_io_uint8s(s,  caps->terminal_desc, 16) : False;  
         res = res ? lsb_io_uint32(s, &caps->pad1             ) : False;  
         res = res ? lsb_io_uint16(s, &caps->xgranularity     ) : False;  
         res = res ? lsb_io_uint16(s, &caps->ygranularity     ) : False;  
         res = res ? lsb_io_uint16(s, &caps->pad2             ) : False;  
         res = res ? lsb_io_uint16(s, &caps->max_order_level  ) : False;  
         res = res ? lsb_io_uint16(s, &caps->num_fonts        ) : False;  
         res = res ? lsb_io_uint16(s, &caps->cap_flags        ) : False;  
         res = res ? prs_io_uint8s(s,  caps->support      , 32) : False;  
         res = res ? lsb_io_uint16(s, &caps->text_cap_flags   ) : False;  
         res = res ? lsb_io_uint16(s, &caps->pad3             ) : False;  
         res = res ? lsb_io_uint32(s, &caps->pad4             ) : False;  
         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;  
711    
712          return res;                  if (!compress)
713  }                  {
714                            int y;
715                            bmpdata = (uint8 *) xmalloc(width * height * Bpp);
716                            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    
 BOOL rdp_io_bmpcache_info(STREAM s, RDP_BMPCACHE_INFO *info)  
 {  
         if (!lsb_io_uint16(s, &info->entries      ))  
                 return False;  
726    
727          if (!lsb_io_uint16(s, &info->max_cell_size))                  if (compress & 0x400)
728                  return False;                  {
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 True;                  xfree(bmpdata);
749            }
750  }  }
751    
752  BOOL rdp_io_bmpcache_caps(STREAM s, RDP_BMPCACHE_CAPS *caps)  /* Process a palette update */
753    void
754    process_palette(STREAM s)
755  {  {
756          uint16 length = RDP_CAPLEN_BMPCACHE;          COLOURENTRY *entry;
757          uint16 pkt_length = length;          COLOURMAP map;
758          BOOL res;          HCOLOURMAP hmap;
759          int i;          int i;
760    
761          res = lsb_io_uint16(s, &pkt_length);          in_uint8s(s, 2);        /* pad */
762          if (pkt_length != length)          in_uint16_le(s, map.ncolours);
763          {          in_uint8s(s, 2);        /* pad */
                 fprintf(stderr, "Unrecognised capabilities size\n");  
                 return False;  
         }  
764    
765          for (i = 0; i < 6; i++)          map.colours = (COLOURENTRY *) xmalloc(3 * map.ncolours);
                 res = res ? lsb_io_uint32(s, &caps->unused[i]) : False;  
766    
767          for (i = 0; i < 3; i++)          DEBUG(("PALETTE(c=%d)\n", map.ncolours));
                 res = res ? rdp_io_bmpcache_info(s, &caps->caches[i]) : False;  
768    
769          return res;          for (i = 0; i < map.ncolours; i++)
 }  
   
 BOOL rdp_io_control_caps(STREAM s, RDP_CONTROL_CAPS *caps)  
 {  
         uint16 length = RDP_CAPLEN_CONTROL;  
         uint16 pkt_length = length;  
         BOOL res;  
   
         res = lsb_io_uint16(s, &pkt_length);  
         if (pkt_length != length)  
770          {          {
771                  fprintf(stderr, "Unrecognised capabilities size\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);
775          }          }
776    
777          res = res ? lsb_io_uint16(s, &caps->control_caps    ) : False;          hmap = ui_create_colourmap(&map);
778          res = res ? lsb_io_uint16(s, &caps->remote_detach   ) : False;          ui_set_colourmap(hmap);
         res = res ? lsb_io_uint16(s, &caps->control_interest) : False;  
         res = res ? lsb_io_uint16(s, &caps->detach_interest ) : False;  
779    
780          return res;          xfree(map.colours);
781  }  }
782    
783  BOOL rdp_io_activate_caps(STREAM s, RDP_ACTIVATE_CAPS *caps)  /* Process an update PDU */
784    static void
785    process_update_pdu(STREAM s)
786  {  {
787          uint16 length = RDP_CAPLEN_ACTIVATE;          uint16 update_type, count;
         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;  
 }  
788    
789  BOOL rdp_io_pointer_caps(STREAM s, RDP_POINTER_CAPS *caps)          in_uint16_le(s, update_type);
 {  
         uint16 length = RDP_CAPLEN_POINTER;  
         uint16 pkt_length = length;  
         BOOL res;  
790    
791          res = lsb_io_uint16(s, &pkt_length);          switch (update_type)
         if (pkt_length != length)  
792          {          {
793                  fprintf(stderr, "Unrecognised capabilities size\n");                  case RDP_UPDATE_ORDERS:
794                  return False;                          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          res = res ? lsb_io_uint16(s, &caps->colour_pointer) : False;                  case RDP_UPDATE_BITMAP:
801          res = res ? lsb_io_uint16(s, &caps->cache_size    ) : False;                          process_bitmap_updates(s);
802                            break;
803    
804          return res;                  case RDP_UPDATE_PALETTE:
805  }                          process_palette(s);
806                            break;
807    
808  BOOL rdp_io_share_caps(STREAM s, RDP_SHARE_CAPS *caps)                  case RDP_UPDATE_SYNCHRONIZE:
809  {                          break;
         uint16 length = RDP_CAPLEN_SHARE;  
         uint16 pkt_length = length;  
         BOOL res;  
810    
811          res = lsb_io_uint16(s, &pkt_length);                  default:
812          if (pkt_length != length)                          unimpl("update %d\n", update_type);
         {  
                 fprintf(stderr, "Unrecognised capabilities size\n");  
                 return False;  
813          }          }
814    
         res = res ? lsb_io_uint16(s, &caps->userid) : False;  
         res = res ? lsb_io_uint16(s, &caps->pad   ) : False;  
   
         return res;  
815  }  }
816    
817  BOOL rdp_io_colcache_caps(STREAM s, RDP_COLCACHE_CAPS *caps)  /* Process data PDU */
818    static void
819    process_data_pdu(STREAM s)
820  {  {
821          uint16 length = RDP_CAPLEN_COLCACHE;          uint8 data_pdu_type;
         uint16 pkt_length = length;  
         BOOL res;  
822    
823          res = lsb_io_uint16(s, &pkt_length);          in_uint8s(s, 8);        /* shareid, pad, streamid, length */
824          if (pkt_length != length)          in_uint8(s, data_pdu_type);
825          {          in_uint8s(s, 3);        /* compress_type, compress_len */
                 fprintf(stderr, "Unrecognised capabilities size\n");  
                 return False;  
         }  
826    
827          res = res ? lsb_io_uint16(s, &caps->cache_size) : False;          switch (data_pdu_type)
828          res = res ? lsb_io_uint16(s, &caps->pad       ) : False;          {
829                    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  uint8 canned_caps[] = {                  case RDP_DATA_PDU_BELL:
838  0x01,0x00,0x00,0x00,0x09,0x04,0x00,0x00,0x04,                          ui_bell();
839  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,                          break;
 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  
 };  
840    
841  BOOL rdp_io_unknown_caps(STREAM s, void *caps)                  case RDP_DATA_PDU_LOGON:
842  {                          DEBUG(("Received Logon PDU\n"));
843          uint16 length = 0x58;                          /* User logged on */
844          uint16 pkt_length = length;                          break;
         BOOL res;  
845    
846          res = lsb_io_uint16(s, &pkt_length);                  default:
847          if (pkt_length != length)                          unimpl("data PDU %d\n", data_pdu_type);
         {  
                 fprintf(stderr, "Unrecognised capabilities size\n");  
                 return False;  
848          }          }
   
         res = res ? prs_io_uint8s(s, canned_caps, RDP_CAPLEN_UNKNOWN-4) : False;  
   
         return res;  
849  }  }
850    
851  BOOL rdp_io_active_pdu(STREAM s, RDP_ACTIVE_PDU *pdu, int pdutype)  /* Process incoming packets */
852    BOOL
853    rdp_main_loop(void)
854  {  {
855          uint16 capset;          uint8 type;
856          uint16 length;          STREAM s;
         BOOL res;  
         int i;  
   
         res = lsb_io_uint32(s, &pdu->shareid);  
   
         if (pdutype == RDP_PDU_CONFIRM_ACTIVE)  
                 res = res ? lsb_io_uint16(s, &pdu->userid    ) : False;  
   
         res = res ? lsb_io_uint16(s, &pdu->source_len) : False;  
         res = res ? lsb_io_uint16(s, &pdu->caps_len  ) : False;  
857    
858          if (pdu->source_len > 48)          while ((s = rdp_recv(&type)) != NULL)
859          {          {
860                  fprintf(stderr, "RDP source descriptor too long\n");                  switch (type)
                 return False;  
         }  
   
         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++)  
861                  {                  {
862                          if (!res)                          case RDP_PDU_DEMAND_ACTIVE:
863                                  return False;                                  process_demand_active(s);
   
                         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 );  
864                                  break;                                  break;
865                          case RDP_CAPSET_SHARE:  
866                                  res = rdp_io_share_caps   (s, &pdu->share_caps   );                          case RDP_PDU_DEACTIVATE:
867                                    DEBUG(("RDP_PDU_DEACTIVATE\n"));
868                                    /* We thought we could detect a clean
869                                       shutdown of the session by this
870                                       packet, but it seems Windows 2003
871                                       is sending us one of these when we
872                                       reconnect to a disconnected session
873                                       return True; */
874                                  break;                                  break;
875                          case RDP_CAPSET_COLCACHE:  
876                                  res = rdp_io_colcache_caps(s, &pdu->colcache_caps);                          case RDP_PDU_DATA:
877                                    process_data_pdu(s);
878                                  break;                                  break;
                         default:  
                                 fprintf(stderr, "Warning: Unrecognised capset %x\n",  
                                         capset);  
879    
880                                  if (!lsb_io_uint16(s, &length))                          case 0:
881                                          return False;                                  break;
882    
883                                  s->offset += (length - 4);                          default:
884                          }                                  unimpl("PDU %d\n", type);
885                  }                  }
886          }          }
887            return True;
888          return res;          /* We want to detect if we got a clean shutdown, but we
889  }          can't. Se above.  
890            return False;  */
 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;  
   
         return res;  
 }  
   
 BOOL rdp_io_synchronize_pdu(STREAM s, RDP_SYNCHRONIZE_PDU *pdu)  
 {  
         BOOL res = True;  
   
         res = res ? lsb_io_uint16(s, &pdu->type  ) : False;  
         res = res ? lsb_io_uint16(s, &pdu->userid) : False;  
   
         return res;  
 }  
   
 BOOL rdp_io_input_event(STREAM s, RDP_INPUT_EVENT *evt)  
 {  
         BOOL res = True;  
   
         res = res ? lsb_io_uint32(s, &evt->event_time)   : False;  
         res = res ? lsb_io_uint16(s, &evt->message_type) : False;  
   
         if (!res)  
                 return False;  
   
         switch (evt->message_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;  
         }  
   
         return res;  
 }  
   
 BOOL rdp_io_input_pdu(STREAM s, RDP_INPUT_PDU *pdu)  
 {  
         BOOL res = True;  
         int i;  
   
         res = res ? lsb_io_uint16(s, &pdu->num_events) : False;  
         res = res ? lsb_io_uint16(s, &pdu->pad       ) : False;  
   
         if (pdu->num_events > RDP_MAX_EVENTS)  
         {  
                 fprintf(stderr, "Too many events in one PDU\n");  
                 return False;  
         }  
   
         for (i = 0; i < pdu->num_events; i++)  
         {  
                 res = res ? rdp_io_input_event(s, &pdu->event[i]) : False;  
         }  
   
         return res;  
 }  
   
 BOOL rdp_io_font_info(STREAM s, RDP_FONT_INFO *font)  
 {  
         BOOL res = True;  
   
         res = res ? prs_io_uint8s(s,  font->name, 32 ) : False;  
         res = res ? lsb_io_uint16(s, &font->flags    ) : False;  
         res = res ? lsb_io_uint16(s, &font->width    ) : False;  
         res = res ? lsb_io_uint16(s, &font->height   ) : False;  
         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;  
   
         return res;  
891  }  }
892    
893  BOOL rdp_io_font_pdu(STREAM s, RDP_FONT_PDU *pdu)  /* Establish a connection up to the RDP layer */
894    BOOL
895    rdp_connect(char *server, uint32 flags, char *domain, char *password,
896                char *command, char *directory)
897  {  {
898          BOOL res = True;          if (use_rdp5)
899          int i;                  channels_init();
   
         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;  
900    
901          if (pdu->num_fonts > RDP_MAX_FONTS)          if (!sec_connect(server, username))
         {  
                 fprintf(stderr, "Too many fonts in one PDU\n");  
902                  return False;                  return False;
         }  
   
         for (i = 0; i < pdu->num_fonts; i++)  
         {  
                 res = res ? rdp_io_font_info(s, &pdu->font[i]) : False;  
         }  
   
         return res;  
 }  
   
 BOOL rdp_io_update_pdu(STREAM s, RDP_UPDATE_PDU *pdu)  
 {  
         BOOL res = True;  
   
         res = res ? lsb_io_uint16(s, &pdu->update_type) : False;  
         res = res ? lsb_io_uint16(s, &pdu->pad        ) : False;  
   
         return res;  
 }  
   
 BOOL rdp_io_secondary_order(STREAM s, RDP_SECONDARY_ORDER *rso)  
 {  
         BOOL res = True;  
903    
904          res = res ? lsb_io_uint16(s, &rso->length) : False;          rdp_send_logon_info(flags, domain, username, password, command, directory);
905          res = res ? lsb_io_uint16(s, &rso->flags ) : False;          return True;
         res = res ? prs_io_uint8 (s, &rso->type  ) : False;  
   
         return res;  
 }  
   
 BOOL rdp_io_bitmap_header(STREAM s, RDP_BITMAP_HEADER *rdh)  
 {  
         BOOL res = True;  
   
         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;  
906  }  }
907    
908  BOOL rdp_io_pointer(STREAM s, RDP_POINTER *ptr)  /* Disconnect from the RDP layer */
909    void
910    rdp_disconnect(void)
911  {  {
912          BOOL res = True;          sec_disconnect();
   
         res = res ? lsb_io_uint16(s, &ptr->message) : False;  
         res = res ? lsb_io_uint16(s, &ptr->pad    ) : False;  
         res = res ? lsb_io_uint16(s, &ptr->x      ) : False;  
         res = res ? lsb_io_uint16(s, &ptr->y      ) : False;  
   
         return res;  
913  }  }

Legend:
Removed from v.7  
changed lines
  Added in v.426

  ViewVC Help
Powered by ViewVC 1.1.26