/[rdesktop]/sourceforge.net/trunk/rdesktop/secure.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/secure.c

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

revision 376 by jsorg71, Mon May 19 21:36:33 2003 UTC revision 447 by jsorg71, Thu Aug 21 23:23:15 2003 UTC
# Line 34  Line 34 
34  #endif  #endif
35    
36  extern char hostname[16];  extern char hostname[16];
37  extern int width;  extern int g_width;
38  extern int height;  extern int g_height;
39  extern int keylayout;  extern int keylayout;
40  extern BOOL encryption;  extern BOOL g_encryption;
41  extern BOOL licence_issued;  extern BOOL g_licence_issued;
42  extern BOOL use_rdp5;  extern BOOL g_use_rdp5;
43  extern int server_bpp;  extern int g_server_bpp;
44    extern uint16 mcs_userid;
45    extern VCHANNEL g_channels[];
46    extern unsigned int g_num_channels;
47    
48  static int rc4_key_len;  static int rc4_key_len;
49  static RC4_KEY rc4_decrypt_key;  static RC4_KEY rc4_decrypt_key;
# Line 54  static uint8 sec_decrypt_update_key[16]; Line 57  static uint8 sec_decrypt_update_key[16];
57  static uint8 sec_encrypt_update_key[16];  static uint8 sec_encrypt_update_key[16];
58  static uint8 sec_crypted_random[SEC_MODULUS_SIZE];  static uint8 sec_crypted_random[SEC_MODULUS_SIZE];
59    
60  uint16 server_rdp_version = 0;  uint16 g_server_rdp_version = 0;
61    
62  /*  /*
63   * General purpose 48-byte transformation, using two 32-byte salts (generally,   * General purpose 48-byte transformation, using two 32-byte salts (generally,
# Line 330  sec_init(uint32 flags, int maxlen) Line 333  sec_init(uint32 flags, int maxlen)
333          int hdrlen;          int hdrlen;
334          STREAM s;          STREAM s;
335    
336          if (!licence_issued)          if (!g_licence_issued)
337                  hdrlen = (flags & SEC_ENCRYPT) ? 12 : 4;                  hdrlen = (flags & SEC_ENCRYPT) ? 12 : 4;
338          else          else
339                  hdrlen = (flags & SEC_ENCRYPT) ? 12 : 0;                  hdrlen = (flags & SEC_ENCRYPT) ? 12 : 0;
# Line 340  sec_init(uint32 flags, int maxlen) Line 343  sec_init(uint32 flags, int maxlen)
343          return s;          return s;
344  }  }
345    
346  /* Transmit secure transport packet */  /* Transmit secure transport packet over specified channel */
347  void  void
348  sec_send(STREAM s, uint32 flags)  sec_send_to_channel(STREAM s, uint32 flags, uint16 channel)
349  {  {
350          int datalen;          int datalen;
351    
352          s_pop_layer(s, sec_hdr);          s_pop_layer(s, sec_hdr);
353          if (!licence_issued || (flags & SEC_ENCRYPT))          if (!g_licence_issued || (flags & SEC_ENCRYPT))
354                  out_uint32_le(s, flags);                  out_uint32_le(s, flags);
355    
356          if (flags & SEC_ENCRYPT)          if (flags & SEC_ENCRYPT)
# Line 364  sec_send(STREAM s, uint32 flags) Line 367  sec_send(STREAM s, uint32 flags)
367                  sec_encrypt(s->p + 8, datalen);                  sec_encrypt(s->p + 8, datalen);
368          }          }
369    
370          mcs_send(s);          mcs_send_to_channel(s, channel);
371    }
372    
373    /* Transmit secure transport packet */
374    
375    void
376    sec_send(STREAM s, uint32 flags)
377    {
378            sec_send_to_channel(s, flags, MCS_GLOBAL_CHANNEL);
379  }  }
380    
381    
382  /* Transfer the client random to the server */  /* Transfer the client random to the server */
383  static void  static void
384  sec_establish_key(void)  sec_establish_key(void)
# Line 390  static void Line 402  static void
402  sec_out_mcs_data(STREAM s)  sec_out_mcs_data(STREAM s)
403  {  {
404          int hostlen = 2 * strlen(hostname);          int hostlen = 2 * strlen(hostname);
405          int length = 158 + 76 + 12 + 4 + 20;          int length = 158 + 76 + 12 + 4;
406            unsigned int i;
407    
408            if (g_num_channels > 0)
409                    length += g_num_channels * 12 + 8;
410    
411          if (hostlen > 30)          if (hostlen > 30)
412                  hostlen = 30;                  hostlen = 30;
# Line 414  sec_out_mcs_data(STREAM s) Line 430  sec_out_mcs_data(STREAM s)
430          /* Client information */          /* Client information */
431          out_uint16_le(s, SEC_TAG_CLI_INFO);          out_uint16_le(s, SEC_TAG_CLI_INFO);
432          out_uint16_le(s, 212);  /* length */          out_uint16_le(s, 212);  /* length */
433          out_uint16_le(s, use_rdp5 ? 4 : 1);     /* RDP version. 1 == RDP4, 4 == RDP5. */          out_uint16_le(s, g_use_rdp5 ? 4 : 1);   /* RDP version. 1 == RDP4, 4 == RDP5. */
434          out_uint16_le(s, 8);          out_uint16_le(s, 8);
435          out_uint16_le(s, width);          out_uint16_le(s, g_width);
436          out_uint16_le(s, height);          out_uint16_le(s, g_height);
437          out_uint16_le(s, 0xca01);          out_uint16_le(s, 0xca01);
438          out_uint16_le(s, 0xaa03);          out_uint16_le(s, 0xaa03);
439          out_uint32_le(s, keylayout);          out_uint32_le(s, keylayout);
# Line 432  sec_out_mcs_data(STREAM s) Line 448  sec_out_mcs_data(STREAM s)
448          out_uint32_le(s, 12);          out_uint32_le(s, 12);
449          out_uint8s(s, 64);      /* reserved? 4 + 12 doublewords */          out_uint8s(s, 64);      /* reserved? 4 + 12 doublewords */
450    
451          switch (server_bpp)          switch (g_server_bpp)
452          {          {
453                  case 8:                  case 8:
454                          out_uint16_le(s, 0xca01);                          out_uint16_le(s, 0xca01);
# Line 450  sec_out_mcs_data(STREAM s) Line 466  sec_out_mcs_data(STREAM s)
466          out_uint16_le(s, 1);          out_uint16_le(s, 1);
467    
468          out_uint32(s, 0);          out_uint32(s, 0);
469          out_uint8(s, server_bpp);          out_uint8(s, g_server_bpp);
470          out_uint16_le(s, 0x0700);          out_uint16_le(s, 0x0700);
471          out_uint8(s, 0);          out_uint8(s, 0);
472          out_uint32_le(s, 1);          out_uint32_le(s, 1);
# Line 464  sec_out_mcs_data(STREAM s) Line 480  sec_out_mcs_data(STREAM s)
480          /* Client encryption settings */          /* Client encryption settings */
481          out_uint16_le(s, SEC_TAG_CLI_CRYPT);          out_uint16_le(s, SEC_TAG_CLI_CRYPT);
482          out_uint16_le(s, 12);   /* length */          out_uint16_le(s, 12);   /* length */
483          out_uint32_le(s, encryption ? 0x3 : 0); /* encryption supported, 128-bit supported */          out_uint32_le(s, g_encryption ? 0x3 : 0);       /* encryption supported, 128-bit supported */
484          out_uint32(s, 0);       /* Unknown */          out_uint32(s, 0);       /* Unknown */
485    
486          out_uint16_le(s, SEC_TAG_CLI_CHANNELS);          DEBUG_RDP5(("g_num_channels is %d\n", g_num_channels));
487          out_uint16_le(s, 20);   /* length */          if (g_num_channels > 0)
488          out_uint32_le(s, 1);    /* number of virtual channels */          {
489          out_uint8p(s, "cliprdr", 8);    /* name padded to 8(?) */                  out_uint16_le(s, SEC_TAG_CLI_CHANNELS);
490          out_uint16(s, 0);                  out_uint16_le(s, g_num_channels * 12 + 8);      /* length */
491          out_uint16_le(s, 0xc0a0);       /* Flags. Rumours tell this is documented in MSDN. */                  out_uint32_le(s, g_num_channels);       /* number of virtual channels */
492                    for (i = 0; i < g_num_channels; i++)
493                    {
494                            DEBUG_RDP5(("Requesting channel %s\n", g_channels[i].name));
495                            out_uint8a(s, g_channels[i].name, 8);
496                            out_uint32_be(s, g_channels[i].flags);
497                    }
498            }
499    
500          s_mark_end(s);          s_mark_end(s);
501  }  }
# Line 563  sec_parse_crypt_info(STREAM s, uint32 * Line 586  sec_parse_crypt_info(STREAM s, uint32 *
586          if (end > s->end)          if (end > s->end)
587                  return False;                  return False;
588    
589          in_uint32_le(s, flags); /* 1 = RDP4-style, 0x80000002 = X.509 */          in_uint32_le(s, flags); /* 1 = RDP4-style, 0x80000002 = X.509 */
590          if (flags & 1)          if (flags & 1)
591          {          {
592                  DEBUG_RDP5(("We're going for the RDP4-style encryption\n"));                  DEBUG_RDP5(("We're going for the RDP4-style encryption\n"));
# Line 614  sec_parse_crypt_info(STREAM s, uint32 * Line 637  sec_parse_crypt_info(STREAM s, uint32 *
637                   */                   */
638    
639                  in_uint32_le(s, cacert_len);                  in_uint32_le(s, cacert_len);
640                    DEBUG_RDP5(("CA Certificate length is %d\n", cacert_len));
641                  cacert = d2i_X509(NULL, &(s->p), cacert_len);                  cacert = d2i_X509(NULL, &(s->p), cacert_len);
642                  /* Note: We don't need to move s->p here - d2i_X509 is                  /* Note: We don't need to move s->p here - d2i_X509 is
643                     "kind" enough to do it for us */                     "kind" enough to do it for us */
# Line 634  sec_parse_crypt_info(STREAM s, uint32 * Line 658  sec_parse_crypt_info(STREAM s, uint32 *
658                   */                   */
659    
660                  in_uint32_le(s, cert_len);                  in_uint32_le(s, cert_len);
661                    DEBUG_RDP5(("Certificate length is %d\n", cert_len));
662                  server_cert = d2i_X509(NULL, &(s->p), cert_len);                  server_cert = d2i_X509(NULL, &(s->p), cert_len);
663                  if (NULL == server_cert)                  if (NULL == server_cert)
664                  {                  {
# Line 674  sec_process_crypt_info(STREAM s) Line 699  sec_process_crypt_info(STREAM s)
699    
700          DEBUG(("Generating client random\n"));          DEBUG(("Generating client random\n"));
701          /* Generate a client random, and hence determine encryption keys */          /* Generate a client random, and hence determine encryption keys */
         generate_random(inr);  
702          // This is what the MS client do:          // This is what the MS client do:
703          //      memset(inr, 0, SEC_RANDOM_SIZE);          memset(inr, 0, SEC_RANDOM_SIZE);
704          // *ARIGL!*          /*  *ARIGL!* Plaintext attack, anyone?
705               I tried doing:
706               generate_random(inr);
707               ..but that generates connection errors now and then (yes,
708               "now and then". Something like 0 to 3 attempts needed before a
709               successful connection. Nice. Not!
710             */
711    
712          generate_random(client_random);          generate_random(client_random);
713          if (NULL != server_public_key)          if (NULL != server_public_key)
714          {                       /* Which means we should use          {                       /* Which means we should use
# Line 705  sec_process_crypt_info(STREAM s) Line 736  sec_process_crypt_info(STREAM s)
736  static void  static void
737  sec_process_srv_info(STREAM s)  sec_process_srv_info(STREAM s)
738  {  {
739          in_uint16_le(s, server_rdp_version);          in_uint16_le(s, g_server_rdp_version);
740          DEBUG_RDP5(("Server RDP version is %d\n", server_rdp_version));          DEBUG_RDP5(("Server RDP version is %d\n", g_server_rdp_version));
741            if (1 == g_server_rdp_version)
742                    g_use_rdp5 = 0;
743  }  }
744    
745    
# Line 739  sec_process_mcs_data(STREAM s) Line 772  sec_process_mcs_data(STREAM s)
772                                  sec_process_srv_info(s);                                  sec_process_srv_info(s);
773                                  break;                                  break;
774    
                         case SEC_TAG_SRV_3:  
                                 break;  
   
775                          case SEC_TAG_SRV_CRYPT:                          case SEC_TAG_SRV_CRYPT:
776                                  sec_process_crypt_info(s);                                  sec_process_crypt_info(s);
777                                  break;                                  break;
778    
779                            case SEC_TAG_SRV_CHANNELS:
780                                    /* FIXME: We should parse this information and
781                                       use it to map RDP5 channels to MCS
782                                       channels */
783                                    break;
784    
785                          default:                          default:
786                                  unimpl("response tag 0x%x\n", tag);                                  unimpl("response tag 0x%x\n", tag);
787                  }                  }
# Line 764  sec_recv(void) Line 800  sec_recv(void)
800    
801          while ((s = mcs_recv(&channel)) != NULL)          while ((s = mcs_recv(&channel)) != NULL)
802          {          {
803                  if (encryption || !licence_issued)                  if (g_encryption || !g_licence_issued)
804                  {                  {
805                          in_uint32_le(s, sec_flags);                          in_uint32_le(s, sec_flags);
806    
                         if (sec_flags & SEC_LICENCE_NEG)  
                         {  
                                 if (sec_flags & SEC_ENCRYPT) {  
                                         DEBUG_RDP5(("Encrypted license detected\n"));  
                                 }  
                                 licence_process(s);  
                                 continue;  
                         }  
   
807                          if (sec_flags & SEC_ENCRYPT)                          if (sec_flags & SEC_ENCRYPT)
808                          {                          {
809                                  in_uint8s(s, 8);        /* signature */                                  in_uint8s(s, 8);        /* signature */
810                                  sec_decrypt(s->p, s->end - s->p);                                  sec_decrypt(s->p, s->end - s->p);
811                          }                          }
812    
813                            if (sec_flags & SEC_LICENCE_NEG)
814                            {
815                                    licence_process(s);
816                                    continue;
817                            }
818                  }                  }
819    
820                  if (MCS_GLOBAL_CHANNEL == channel)                  if (channel != MCS_GLOBAL_CHANNEL)
821                  {                  {
822                          return s;                          channel_process(s, channel);
823                            continue;
824                  }                  }
                 else  
                         rdp5_process_channel(s, channel);  
825    
826                    return s;
827          }          }
828    
829          return NULL;          return NULL;
# Line 804  sec_connect(char *server, char *username Line 837  sec_connect(char *server, char *username
837    
838          /* We exchange some RDP data during the MCS-Connect */          /* We exchange some RDP data during the MCS-Connect */
839          mcs_data.size = 512;          mcs_data.size = 512;
840          mcs_data.p = mcs_data.data = (uint8*)xmalloc(mcs_data.size);          mcs_data.p = mcs_data.data = (uint8 *) xmalloc(mcs_data.size);
841          sec_out_mcs_data(&mcs_data);          sec_out_mcs_data(&mcs_data);
842    
843          if (!mcs_connect(server, &mcs_data, username))          if (!mcs_connect(server, &mcs_data, username))
844                  return False;                  return False;
845    
846          //      sec_process_mcs_data(&mcs_data);          //      sec_process_mcs_data(&mcs_data);
847          if (encryption)          if (g_encryption)
848                  sec_establish_key();                  sec_establish_key();
849          xfree(mcs_data.data);          xfree(mcs_data.data);
850          return True;          return True;

Legend:
Removed from v.376  
changed lines
  Added in v.447

  ViewVC Help
Powered by ViewVC 1.1.26