/[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 340 by forsberg, Thu Mar 6 14:11:17 2003 UTC revision 351 by forsberg, Thu Mar 27 13:22:29 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-2002     Copyright (C) Matthew Chapman 1999-2002
# Line 26  extern BOOL bitmap_compression; Line 26  extern BOOL bitmap_compression;
26  extern BOOL orders;  extern BOOL orders;
27  extern BOOL encryption;  extern BOOL encryption;
28  extern BOOL desktop_save;  extern BOOL desktop_save;
29    extern BOOL use_rdp5;
30    extern uint16 server_rdp_version;
31    
32  uint8 *next_packet;  uint8 *next_packet;
33  uint32 rdp_shareid;  uint32 rdp_shareid;
34    
35  #if WITH_DEBUG  #if WITH_DEBUG
36  static uint32 packetno;  static uint32 packetno;
37  #endif  #endif
   
 /* Initialise an RDP packet */  
 static STREAM  
 rdp_init(int maxlen)  
 {  
         STREAM s;  
   
         s = sec_init(encryption ? SEC_ENCRYPT : 0, maxlen + 6);  
         s_push_layer(s, rdp_hdr, 6);  
   
         return s;  
 }  
   
 /* Send an RDP packet */  
 static void  
 rdp_send(STREAM s, uint8 pdu_type)  
 {  
         uint16 length;  
   
         s_pop_layer(s, rdp_hdr);  
         length = s->end - s->p;  
   
         out_uint16_le(s, length);  
         out_uint16_le(s, (pdu_type | 0x10));    /* Version 1 */  
         out_uint16_le(s, (mcs_userid + 1001));  
   
         sec_send(s, encryption ? SEC_ENCRYPT : 0);  
 }  
38    
39  /* Receive an RDP packet */  /* Receive an RDP packet */
40  static STREAM  static STREAM
# Line 95  rdp_recv(uint8 * type) Line 69  rdp_recv(uint8 * type)
69          *type = pdu_type & 0xf;          *type = pdu_type & 0xf;
70    
71  #if WITH_DEBUG  #if WITH_DEBUG
72          DEBUG(("RDP packet #%d, (type %x):\n", ++packetno, *type));          DEBUG(("RDP packet #%d, (type %x)\n", ++packetno, *type));
73          hexdump(next_packet, length);          //      hexdump(next_packet, length);
74  #endif /*  */  #endif /*  */
75    
76          next_packet += length;          next_packet += length;
# Line 169  rdp_send_logon_info(uint32 flags, char * Line 143  rdp_send_logon_info(uint32 flags, char *
143          uint32 sec_flags = encryption ? (SEC_LOGON_INFO | SEC_ENCRYPT) : SEC_LOGON_INFO;          uint32 sec_flags = encryption ? (SEC_LOGON_INFO | SEC_ENCRYPT) : SEC_LOGON_INFO;
144          STREAM s;          STREAM s;
145    
146          s = sec_init(sec_flags, 18 + len_domain + len_user + len_password          if (1 == server_rdp_version)
147                       + len_program + len_directory + 10);          {
148                    DEBUG_RDP5(("Sending RDP4-style Logon packet\n"));
149    
150                    s = sec_init(sec_flags, 18 + len_domain + len_user + len_password
151                                 + len_program + len_directory + 10);
152    
153                    out_uint32(s, 0);
154                    out_uint32_le(s, flags);
155                    out_uint16_le(s, len_domain);
156                    out_uint16_le(s, len_user);
157                    out_uint16_le(s, len_password);
158                    out_uint16_le(s, len_program);
159                    out_uint16_le(s, len_directory);
160                    rdp_out_unistr(s, domain, len_domain);
161                    rdp_out_unistr(s, user, len_user);
162                    rdp_out_unistr(s, password, len_password);
163                    rdp_out_unistr(s, program, len_program);
164                    rdp_out_unistr(s, directory, len_directory);
165            }
166            else
167            {
168                    DEBUG_RDP5(("Sending RDP5-style Logon packet\n"));
169                    s = sec_init(sec_flags, 12 + (flags & RDP_LOGON_AUTO ? 2 : 0) + 6 + (flags & RDP_LOGON_AUTO ? len_password : 0) + len_domain + len_user + 4 + len_program + len_directory + 30 + 2 + 60 + 32 + 20 + 32 + 20);   /* Phew! */
170    
171          out_uint32(s, 0);                  out_uint32(s, 0);
172          out_uint32_le(s, flags);                  out_uint32_le(s, flags);
173          out_uint16_le(s, len_domain);                  out_uint16_le(s, len_domain);
174          out_uint16_le(s, len_user);                  out_uint16_le(s, len_user);
175          out_uint16_le(s, len_password);                  if (flags & RDP_LOGON_AUTO)
176          out_uint16_le(s, len_program);                  {
177          out_uint16_le(s, len_directory);                          out_uint16_le(s, len_password);
178          rdp_out_unistr(s, domain, len_domain);                  }
179          rdp_out_unistr(s, user, len_user);                  out_uint16_le(s, 0);    /* Seems to be length of a 512 byte blob with
180          rdp_out_unistr(s, password, len_password);                                             completely unknown data, but hopefully we'll do
181          rdp_out_unistr(s, program, len_program);                                             with a 0 length block as well */
182          rdp_out_unistr(s, directory, len_directory);                  out_uint16_le(s, len_program);
183                    out_uint16_le(s, len_directory);
184                    if (flags & RDP_LOGON_AUTO)
185                    {
186                            rdp_out_unistr(s, password, len_password);
187                    }
188                    rdp_out_unistr(s, domain, len_domain);
189                    rdp_out_unistr(s, user, len_user);
190                    out_uint16_le(s, 0);
191                    out_uint16_le(s, 0);
192                    if (0 < len_program)
193                            rdp_out_unistr(s, program, len_program);
194                    if (0 < len_directory)
195                            rdp_out_unistr(s, directory, len_directory);
196                    out_uint8s(s, 30);      /* Some kind of client data - let's see if the server
197                                               handles zeros well.. */
198                    out_uint16_le(s, 60);
199                    rdp_out_unistr(s, "C:\\WINNT\\System32\\mstscax.dll", 58);
200                    out_uint32_be(s, 0x88ffffff);
201                    rdp_out_unistr(s, "GTB, normaltid", 2 * strlen("GTB, normaltid") - 2);
202                    out_uint8s(s, 30 - 2 * strlen("GTP, normaltid"));
203    
204                    out_uint32_le(s, 0x0a0000);
205                    out_uint32_le(s, 0x050000);
206                    out_uint32_le(s, 2);
207                    out_uint32_le(s, 0);
208                    out_uint32_le(s, 0xffffffc4);
209                    out_uint32_le(s, 0xfffffffe);
210                    out_uint32_le(s, 0x0f);
211                    out_uint32_le(s, 0);
212    
213                    rdp_out_unistr(s, "GTB, sommartid", 2 * strlen("GTB, sommartid") - 1);
214                    out_uint8s(s, 30 - 2 * strlen("GTP, sommartid"));
215    
216                    out_uint32_le(s, 0x030000);
217                    out_uint32_le(s, 0x050000);
218                    out_uint32_le(s, 2);
219                    out_uint32_le(s, 0);
220                    out_uint32_le(s, 0xffffffc4);
221                    out_uint32_le(s, 0xfffffffe);
222                    out_uint32_le(s, 0x0f);
223                    out_uint32_le(s, 0);
224    
225            }
226          s_mark_end(s);          s_mark_end(s);
227          sec_send(s, sec_flags);          sec_send(s, sec_flags);
228  }  }
# Line 270  rdp_out_general_caps(STREAM s) Line 308  rdp_out_general_caps(STREAM s)
308          out_uint16_le(s, 0x200);        /* Protocol version */          out_uint16_le(s, 0x200);        /* Protocol version */
309          out_uint16(s, 0);       /* Pad */          out_uint16(s, 0);       /* Pad */
310          out_uint16(s, 0);       /* Compression types */          out_uint16(s, 0);       /* Compression types */
311          out_uint16(s, 0);       /* Pad */          out_uint16(s, use_rdp5 ? 0x40d : 0);
312            /* Pad, according to T.128. 0x40d seems to
313               trigger
314               the server to start sending RDP5 packets.
315               However, the value is 0x1d04 with W2KTSK and
316               NT4MS. Hmm.. Anyway, thankyou, Microsoft,
317               for sending such information in a padding
318               field.. */
319          out_uint16(s, 0);       /* Update capability */          out_uint16(s, 0);       /* Update capability */
320          out_uint16(s, 0);       /* Remote unshare capability */          out_uint16(s, 0);       /* Remote unshare capability */
321          out_uint16(s, 0);       /* Compression level */          out_uint16(s, 0);       /* Compression level */
# Line 433  static uint8 canned_caps[] = { Line 478  static uint8 canned_caps[] = {
478          0x02, 0x00, 0x00, 0x00          0x02, 0x00, 0x00, 0x00
479  };  };
480    
481  /* Output unknown capability set */  /* Output unknown capability sets (number 13, 12, 14 and 16) */
482  static void  static void
483  rdp_out_unknown_caps(STREAM s)  rdp_out_unknown_caps(STREAM s)
484  {  {
# Line 443  rdp_out_unknown_caps(STREAM s) Line 488  rdp_out_unknown_caps(STREAM s)
488          out_uint8p(s, canned_caps, RDP_CAPLEN_UNKNOWN - 4);          out_uint8p(s, canned_caps, RDP_CAPLEN_UNKNOWN - 4);
489  }  }
490    
491    #define RDP5_FLAG 0x0030
492  /* Send a confirm active PDU */  /* Send a confirm active PDU */
493  static void  static void
494  rdp_send_confirm_active(void)  rdp_send_confirm_active(void)
495  {  {
496          STREAM s;          STREAM s;
497            uint32 sec_flags = encryption ? (RDP5_FLAG | SEC_ENCRYPT) : RDP5_FLAG;
498          uint16 caplen =          uint16 caplen =
499                  RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +                  RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +
500                  RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +                  RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +
501                  RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +                  RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +
502                  RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE + RDP_CAPLEN_UNKNOWN + 4 /* w2k fix, why? */ ;                  RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE + RDP_CAPLEN_UNKNOWN + 4 /* w2k fix, why? */ ;
503    
504          s = rdp_init(14 + caplen + sizeof(RDP_SOURCE));          s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));
505    
506            out_uint16_le(s, 2 + 14 + caplen + sizeof(RDP_SOURCE));
507            out_uint16_le(s, (RDP_PDU_CONFIRM_ACTIVE | 0x10));      /* Version 1 */
508            out_uint16_le(s, (mcs_userid + 1001));
509    
510          out_uint32_le(s, rdp_shareid);          out_uint32_le(s, rdp_shareid);
511          out_uint16_le(s, 0x3ea);        /* userid */          out_uint16_le(s, 0x3ea);        /* userid */
# Line 477  rdp_send_confirm_active(void) Line 528  rdp_send_confirm_active(void)
528          rdp_out_unknown_caps(s);          rdp_out_unknown_caps(s);
529    
530          s_mark_end(s);          s_mark_end(s);
531          rdp_send(s, RDP_PDU_CONFIRM_ACTIVE);          sec_send(s, sec_flags);
532  }  }
533    
534  /* Respond to a demand active PDU */  /* Respond to a demand active PDU */
# Line 504  process_demand_active(STREAM s) Line 555  process_demand_active(STREAM s)
555          reset_order_state();          reset_order_state();
556  }  }
557    
558    /* Process a null system pointer PDU */
559    void
560    process_null_system_pointer_pdu(STREAM s)
561    {
562            // FIXME: We should probably set another cursor here,
563            // like the X window system base cursor or something.
564            ui_set_cursor(cache_get_cursor(0));
565    }
566    
567    /* Process a colour pointer PDU */
568    void
569    process_colour_pointer_pdu(STREAM s)
570    {
571            uint16 x, y, width, height, cache_idx, masklen, datalen;
572            uint8 *mask, *data;
573            HCURSOR cursor;
574    
575            in_uint16_le(s, cache_idx);
576            in_uint16_le(s, x);
577            in_uint16_le(s, y);
578            in_uint16_le(s, width);
579            in_uint16_le(s, height);
580            in_uint16_le(s, masklen);
581            in_uint16_le(s, datalen);
582            in_uint8p(s, data, datalen);
583            in_uint8p(s, mask, masklen);
584            cursor = ui_create_cursor(x, y, width, height, mask, data);
585            ui_set_cursor(cursor);
586            cache_put_cursor(cache_idx, cursor);
587    }
588    
589    /* Process a cached pointer PDU */
590    void
591    process_cached_pointer_pdu(STREAM s)
592    {
593            uint16 cache_idx;
594    
595            in_uint16_le(s, cache_idx);
596            ui_set_cursor(cache_get_cursor(cache_idx));
597    }
598    
599    
600  /* Process a pointer PDU */  /* Process a pointer PDU */
601  static void  static void
602  process_pointer_pdu(STREAM s)  process_pointer_pdu(STREAM s)
603  {  {
604          uint16 message_type;          uint16 message_type;
605          uint16 x, y, width, height, cache_idx, masklen, datalen;          uint16 x, y;
         uint8 *mask, *data;  
         HCURSOR cursor;  
606    
607          in_uint16_le(s, message_type);          in_uint16_le(s, message_type);
608          in_uint8s(s, 2);        /* pad */          in_uint8s(s, 2);        /* pad */
# Line 526  process_pointer_pdu(STREAM s) Line 617  process_pointer_pdu(STREAM s)
617                          break;                          break;
618    
619                  case RDP_POINTER_COLOR:                  case RDP_POINTER_COLOR:
620                          in_uint16_le(s, cache_idx);                          process_colour_pointer_pdu(s);
                         in_uint16_le(s, x);  
                         in_uint16_le(s, y);  
                         in_uint16_le(s, width);  
                         in_uint16_le(s, height);  
                         in_uint16_le(s, masklen);  
                         in_uint16_le(s, datalen);  
                         in_uint8p(s, data, datalen);  
                         in_uint8p(s, mask, masklen);  
                         cursor = ui_create_cursor(x, y, width, height, mask, data);  
                         ui_set_cursor(cursor);  
                         cache_put_cursor(cache_idx, cursor);  
621                          break;                          break;
622    
623                  case RDP_POINTER_CACHED:                  case RDP_POINTER_CACHED:
624                          in_uint16_le(s, cache_idx);                          process_cached_pointer_pdu(s);
                         ui_set_cursor(cache_get_cursor(cache_idx));  
625                          break;                          break;
626    
627                  default:                  default:
# Line 551  process_pointer_pdu(STREAM s) Line 630  process_pointer_pdu(STREAM s)
630  }  }
631    
632  /* Process bitmap updates */  /* Process bitmap updates */
633  static void  void
634  process_bitmap_updates(STREAM s)  process_bitmap_updates(STREAM s)
635  {  {
636          uint16 num_updates;          uint16 num_updates;
# Line 578  process_bitmap_updates(STREAM s) Line 657  process_bitmap_updates(STREAM s)
657                  cx = right - left + 1;                  cx = right - left + 1;
658                  cy = bottom - top + 1;                  cy = bottom - top + 1;
659    
660                  DEBUG(("UPDATE(l=%d,t=%d,r=%d,b=%d,w=%d,h=%d,cmp=%d)\n",                  DEBUG(("BITMAP_UPDATE(l=%d,t=%d,r=%d,b=%d,w=%d,h=%d,Bpp=%d,cmp=%d)\n",
661                         left, top, right, bottom, width, height, compress));                         left, top, right, bottom, width, height, Bpp, compress));
662    
663                  if (!compress)                  if (!compress)
664                  {                  {
# Line 595  process_bitmap_updates(STREAM s) Line 674  process_bitmap_updates(STREAM s)
674                          continue;                          continue;
675                  }                  }
676    
677                  in_uint8s(s, 2);        /* pad */  
678                  in_uint16_le(s, size);                  if (compress & 0x400)
679                  in_uint8s(s, 4);        /* line_size, final_size */                  {
680                            size = bufsize;
681                    }
682                    else
683                    {
684                            in_uint8s(s, 2);        /* pad */
685                            in_uint16_le(s, size);
686                            in_uint8s(s, 4);        /* line_size, final_size */
687                    }
688                  in_uint8p(s, data, size);                  in_uint8p(s, data, size);
689                  bmpdata = xmalloc(width * height * Bpp);                  bmpdata = xmalloc(width * height * Bpp);
690                  if (bitmap_decompress(bmpdata, width, height, data, size, Bpp))                  if (bitmap_decompress(bmpdata, width, height, data, size, Bpp))
691                  {                  {
692                          ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);                          ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
693                  }                  }
694                    else
695                    {
696                            DEBUG_RDP5(("Failed to decompress data\n"));
697                    }
698    
699                  xfree(bmpdata);                  xfree(bmpdata);
700          }          }
701  }  }
702    
703  /* Process a palette update */  /* Process a palette update */
704  static void  void
705  process_palette(STREAM s)  process_palette(STREAM s)
706  {  {
707          COLOURENTRY *entry;          COLOURENTRY *entry;
# Line 623  process_palette(STREAM s) Line 715  process_palette(STREAM s)
715    
716          map.colours = xmalloc(3 * map.ncolours);          map.colours = xmalloc(3 * map.ncolours);
717    
718            DEBUG(("PALETTE(c=%d)\n", map.ncolours));
719    
720          for (i = 0; i < map.ncolours; i++)          for (i = 0; i < map.ncolours; i++)
721          {          {
722                  entry = &map.colours[i];                  entry = &map.colours[i];
# Line 641  process_palette(STREAM s) Line 735  process_palette(STREAM s)
735  static void  static void
736  process_update_pdu(STREAM s)  process_update_pdu(STREAM s)
737  {  {
738          uint16 update_type;          uint16 update_type, count;
739    
740          in_uint16_le(s, update_type);          in_uint16_le(s, update_type);
741    
742          switch (update_type)          switch (update_type)
743          {          {
744                  case RDP_UPDATE_ORDERS:                  case RDP_UPDATE_ORDERS:
745                          process_orders(s);                          in_uint8s(s, 2);        /* pad */
746                            in_uint16_le(s, count);
747                            in_uint8s(s, 2);        /* pad */
748                            process_orders(s, count);
749                          break;                          break;
750    
751                  case RDP_UPDATE_BITMAP:                  case RDP_UPDATE_BITMAP:
# Line 693  process_data_pdu(STREAM s) Line 790  process_data_pdu(STREAM s)
790                          break;                          break;
791    
792                  case RDP_DATA_PDU_LOGON:                  case RDP_DATA_PDU_LOGON:
793                            DEBUG(("Received Logon PDU\n"));
794                          /* User logged on */                          /* User logged on */
795                          break;                          break;
796    
# Line 737  BOOL Line 835  BOOL
835  rdp_connect(char *server, uint32 flags, char *domain, char *password,  rdp_connect(char *server, uint32 flags, char *domain, char *password,
836              char *command, char *directory)              char *command, char *directory)
837  {  {
838          if (!sec_connect(server))          if (!sec_connect(server, username))
839                  return False;                  return False;
840    
841          rdp_send_logon_info(flags, domain, username, password, command, directory);          rdp_send_logon_info(flags, domain, username, password, command, directory);

Legend:
Removed from v.340  
changed lines
  Added in v.351

  ViewVC Help
Powered by ViewVC 1.1.26