/[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 357 by forsberg, Fri Mar 28 12:55:25 2003 UTC revision 419 by forsberg, Wed Jun 11 07:12:18 2003 UTC
# Line 38  extern int width; Line 38  extern int width;
38  extern int height;  extern int height;
39  extern int keylayout;  extern int keylayout;
40  extern BOOL encryption;  extern BOOL encryption;
41  extern BOOL licence_issued;  extern BOOL g_licence_issued;
42  extern BOOL use_rdp5;  extern BOOL use_rdp5;
43  extern int server_bpp;  extern int server_bpp;
44    extern uint16 mcs_userid;
45    
46  static int rc4_key_len;  static int rc4_key_len;
47  static RC4_KEY rc4_decrypt_key;  static RC4_KEY rc4_decrypt_key;
# Line 330  sec_init(uint32 flags, int maxlen) Line 331  sec_init(uint32 flags, int maxlen)
331          int hdrlen;          int hdrlen;
332          STREAM s;          STREAM s;
333    
334          if (!licence_issued)          if (!g_licence_issued)
335                  hdrlen = (flags & SEC_ENCRYPT) ? 12 : 4;                  hdrlen = (flags & SEC_ENCRYPT) ? 12 : 4;
336          else          else
337                  hdrlen = (flags & SEC_ENCRYPT) ? 12 : 0;                  hdrlen = (flags & SEC_ENCRYPT) ? 12 : 0;
# Line 340  sec_init(uint32 flags, int maxlen) Line 341  sec_init(uint32 flags, int maxlen)
341          return s;          return s;
342  }  }
343    
344  /* Transmit secure transport packet */  /* Transmit secure transport packet over specified channel */
345  void  void
346  sec_send(STREAM s, uint32 flags)  sec_send_to_channel(STREAM s, uint32 flags, uint16 channel)
347  {  {
348          int datalen;          int datalen;
349    
350          s_pop_layer(s, sec_hdr);          s_pop_layer(s, sec_hdr);
351          if (!licence_issued || (flags & SEC_ENCRYPT))          if (!g_licence_issued || (flags & SEC_ENCRYPT))
352                  out_uint32_le(s, flags);                  out_uint32_le(s, flags);
353    
354          if (flags & SEC_ENCRYPT)          if (flags & SEC_ENCRYPT)
# Line 364  sec_send(STREAM s, uint32 flags) Line 365  sec_send(STREAM s, uint32 flags)
365                  sec_encrypt(s->p + 8, datalen);                  sec_encrypt(s->p + 8, datalen);
366          }          }
367    
368          mcs_send(s);          mcs_send_to_channel(s, channel);
369    }
370    
371    /* Transmit secure transport packet */
372    
373    void
374    sec_send(STREAM s, uint32 flags)
375    {
376            sec_send_to_channel(s, flags, MCS_GLOBAL_CHANNEL);
377  }  }
378    
379    
380  /* Transfer the client random to the server */  /* Transfer the client random to the server */
381  static void  static void
382  sec_establish_key(void)  sec_establish_key(void)
# Line 389  sec_establish_key(void) Line 399  sec_establish_key(void)
399  static void  static void
400  sec_out_mcs_data(STREAM s)  sec_out_mcs_data(STREAM s)
401  {  {
402            uint16 num_channels = get_num_channels();
403          int hostlen = 2 * strlen(hostname);          int hostlen = 2 * strlen(hostname);
404          int length = 158 + 76 + 12 + 4 + 20;          int length = 158 + 76 + 12 + 4 + (CHANNEL_TAGDATA_SIZE * num_channels);
405            uint16 i;
406            rdp5_channel *channel;
407    
408            if (0 < num_channels)
409            {
410                    length += +4 + 4;
411            }
412    
413          if (hostlen > 30)          if (hostlen > 30)
414                  hostlen = 30;                  hostlen = 30;
# Line 447  sec_out_mcs_data(STREAM s) Line 465  sec_out_mcs_data(STREAM s)
465                          out_uint16_le(s, 0xca04);                          out_uint16_le(s, 0xca04);
466                          break;                          break;
467          }          }
468          out_uint16(s, 1);          out_uint16_le(s, 1);
469    
470          out_uint32(s, 0);          out_uint32(s, 0);
471          out_uint8(s, server_bpp);          out_uint8(s, server_bpp);
# Line 459  sec_out_mcs_data(STREAM s) Line 477  sec_out_mcs_data(STREAM s)
477          out_uint16_le(s, SEC_TAG_CLI_4);          out_uint16_le(s, SEC_TAG_CLI_4);
478          out_uint16_le(s, 12);          out_uint16_le(s, 12);
479          out_uint32_le(s, 9);          out_uint32_le(s, 9);
480          out_uint32_le(s, 0);          out_uint32(s, 0);
481    
482          /* Client encryption settings */          /* Client encryption settings */
483          out_uint16_le(s, SEC_TAG_CLI_CRYPT);          out_uint16_le(s, SEC_TAG_CLI_CRYPT);
484          out_uint16_le(s, 12);   /* length */          out_uint16_le(s, 12);   /* length */
485          out_uint32_le(s, encryption ? 0x3 : 0); /* encryption supported, 128-bit supported */          out_uint32_le(s, encryption ? 0x3 : 0); /* encryption supported, 128-bit supported */
486          out_uint32_le(s, 0);    /* Unknown */          out_uint32(s, 0);       /* Unknown */
487    
488          out_uint16_le(s, SEC_TAG_CLI_CHANNELS);          DEBUG_RDP5(("num_channels is %d\n", num_channels));
489          out_uint16_le(s, 20);   /* length */          if (0 < num_channels)
490          out_uint32_le(s, 1);    /* number of virtual channels */          {
491          out_uint8p(s, "cliprdr", 8);    /* name padded to 8(?) */                  out_uint16_le(s, SEC_TAG_CLI_CHANNELS);
492          out_uint16(s, 0);                  out_uint16_le(s, num_channels * CHANNEL_TAGDATA_SIZE + 4 + 4);  /* length */
493          out_uint16_le(s, 0xc0a0);       /* Flags. Rumours tell this is documented in MSDN. */                  out_uint32_le(s, num_channels); /* number of virtual channels */
494                    for (i = 0; i < num_channels; i++)
495                    {
496                            channel = find_channel_by_num(i);
497                            DEBUG_RDP5(("Requesting channel %s\n", channel->name));
498                            out_uint8p(s, channel->name, 8);
499                            out_uint32_be(s, channel->channelflags);
500                    }
501            }
502    
503          s_mark_end(s);          s_mark_end(s);
504  }  }
# Line 538  sec_parse_crypt_info(STREAM s, uint32 * Line 564  sec_parse_crypt_info(STREAM s, uint32 *
564                       uint8 ** server_random, uint8 ** modulus, uint8 ** exponent)                       uint8 ** server_random, uint8 ** modulus, uint8 ** exponent)
565  {  {
566          uint32 crypt_level, random_len, rsa_info_len;          uint32 crypt_level, random_len, rsa_info_len;
567          uint32 cacert_len, cert_len;          uint32 cacert_len, cert_len, flags;
568          X509 *cacert, *server_cert;          X509 *cacert, *server_cert;
569          uint16 tag, length;          uint16 tag, length;
570          uint8 *next_tag, *end;          uint8 *next_tag, *end;
# Line 563  sec_parse_crypt_info(STREAM s, uint32 * Line 589  sec_parse_crypt_info(STREAM s, uint32 *
589          if (end > s->end)          if (end > s->end)
590                  return False;                  return False;
591    
592          if (!use_rdp5 || 1 == server_rdp_version)          in_uint32_le(s, flags); /* 1 = RDP4-style, 0x80000002 = X.509 */
593            if (flags & 1)
594          {          {
595                  DEBUG_RDP5(("We're going for the RDP4-style encryption\n"));                  DEBUG_RDP5(("We're going for the RDP4-style encryption\n"));
596                  in_uint8s(s, 12);       /* unknown */                  in_uint8s(s, 8);        /* unknown */
597    
598                  while (s->p < end)                  while (s->p < end)
599                  {                  {
# Line 598  sec_parse_crypt_info(STREAM s, uint32 * Line 625  sec_parse_crypt_info(STREAM s, uint32 *
625                          s->p = next_tag;                          s->p = next_tag;
626                  }                  }
627          }          }
628          else if (4 == server_rdp_version)          else
629          {          {
630                  DEBUG_RDP5(("We're going for the RDP5-style encryption\n"));                  DEBUG_RDP5(("We're going for the RDP5-style encryption\n"));
631                  in_uint8s(s, 8);        /* Unknown */                  in_uint8s(s, 4);        /* Number of certificates */
632    
633                  /* Do da funky X.509 stuffy                  /* Do da funky X.509 stuffy
634    
# Line 613  sec_parse_crypt_info(STREAM s, uint32 * Line 640  sec_parse_crypt_info(STREAM s, uint32 *
640                   */                   */
641    
642                  in_uint32_le(s, cacert_len);                  in_uint32_le(s, cacert_len);
643                    DEBUG_RDP5(("CA Certificate length is %d\n", cacert_len));
644                  cacert = d2i_X509(NULL, &(s->p), cacert_len);                  cacert = d2i_X509(NULL, &(s->p), cacert_len);
645                  /* 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
646                     "kind" enough to do it for us */                     "kind" enough to do it for us */
# Line 633  sec_parse_crypt_info(STREAM s, uint32 * Line 661  sec_parse_crypt_info(STREAM s, uint32 *
661                   */                   */
662    
663                  in_uint32_le(s, cert_len);                  in_uint32_le(s, cert_len);
664                    DEBUG_RDP5(("Certificate length is %d\n", cert_len));
665                  server_cert = d2i_X509(NULL, &(s->p), cert_len);                  server_cert = d2i_X509(NULL, &(s->p), cert_len);
666                  if (NULL == server_cert)                  if (NULL == server_cert)
667                  {                  {
# Line 653  sec_parse_crypt_info(STREAM s, uint32 * Line 682  sec_parse_crypt_info(STREAM s, uint32 *
682                  }                  }
683                  return True;    /* There's some garbage here we don't care about */                  return True;    /* There's some garbage here we don't care about */
684          }          }
         else  
         {  
                 error("Unknown Server RDP version %d", server_rdp_version);  
                 return False;  
         }  
685          return s_check_end(s);          return s_check_end(s);
686  }  }
687    
# Line 678  sec_process_crypt_info(STREAM s) Line 702  sec_process_crypt_info(STREAM s)
702    
703          DEBUG(("Generating client random\n"));          DEBUG(("Generating client random\n"));
704          /* Generate a client random, and hence determine encryption keys */          /* Generate a client random, and hence determine encryption keys */
         generate_random(inr);  
705          // This is what the MS client do:          // This is what the MS client do:
706          //      memset(inr, 0, SEC_RANDOM_SIZE);          memset(inr, 0, SEC_RANDOM_SIZE);
707          // *ARIGL!*          /*  *ARIGL!* Plaintext attack, anyone?
708               I tried doing:
709               generate_random(inr);
710               ..but that generates connection errors now and then (yes,
711               "now and then". Something like 0 to 3 attempts needed before a
712               successful connection. Nice. Not!
713             */
714    
715          generate_random(client_random);          generate_random(client_random);
716          if (NULL != server_public_key)          if (NULL != server_public_key)
717          {                       /* Which means we should use          {                       /* Which means we should use
# Line 744  sec_process_mcs_data(STREAM s) Line 774  sec_process_mcs_data(STREAM s)
774                                  break;                                  break;
775    
776                          case SEC_TAG_SRV_3:                          case SEC_TAG_SRV_3:
777                                    /* FIXME: We should parse this information and
778                                       use it to map RDP5 channels to MCS
779                                       channels */
780                                  break;                                  break;
781    
782                          case SEC_TAG_SRV_CRYPT:                          case SEC_TAG_SRV_CRYPT:
# Line 768  sec_recv(void) Line 801  sec_recv(void)
801    
802          while ((s = mcs_recv(&channel)) != NULL)          while ((s = mcs_recv(&channel)) != NULL)
803          {          {
804                  if (encryption || !licence_issued)                  if (encryption || !g_licence_issued)
805                  {                  {
806                          in_uint32_le(s, sec_flags);                          in_uint32_le(s, sec_flags);
807    
808                          if (sec_flags & SEC_LICENCE_NEG)                          if (sec_flags & SEC_LICENCE_NEG)
809                          {                          {
810                                  if (sec_flags & SEC_ENCRYPT) {                                  if (sec_flags & SEC_ENCRYPT)
811                                    {
812                                          DEBUG_RDP5(("Encrypted license detected\n"));                                          DEBUG_RDP5(("Encrypted license detected\n"));
813                                  }                                  }
814                                  licence_process(s);                                  licence_process(s);
815                                  continue;                                  continue;
816                          }                          }
# Line 808  sec_connect(char *server, char *username Line 842  sec_connect(char *server, char *username
842    
843          /* We exchange some RDP data during the MCS-Connect */          /* We exchange some RDP data during the MCS-Connect */
844          mcs_data.size = 512;          mcs_data.size = 512;
845          mcs_data.p = mcs_data.data = xmalloc(mcs_data.size);          mcs_data.p = mcs_data.data = (uint8 *) xmalloc(mcs_data.size);
846          sec_out_mcs_data(&mcs_data);          sec_out_mcs_data(&mcs_data);
847    
848          if (!mcs_connect(server, &mcs_data, username))          if (!mcs_connect(server, &mcs_data, username))

Legend:
Removed from v.357  
changed lines
  Added in v.419

  ViewVC Help
Powered by ViewVC 1.1.26