/[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 207 by matthewc, Thu Sep 26 14:26:46 2002 UTC revision 419 by forsberg, Wed Jun 11 07:12:18 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 encryption and licensing     Protocol services - RDP encryption and licensing
4     Copyright (C) Matthew Chapman 1999-2002     Copyright (C) Matthew Chapman 1999-2002
# Line 25  Line 25 
25  #include <openssl/md5.h>  #include <openssl/md5.h>
26  #include <openssl/sha.h>  #include <openssl/sha.h>
27  #include <openssl/bn.h>  #include <openssl/bn.h>
28    #include <openssl/x509v3.h>
29  #else  #else
30  #include "crypto/rc4.h"  #include "crypto/rc4.h"
31  #include "crypto/md5.h"  #include "crypto/md5.h"
# Line 37  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;
43    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;
48  static RC4_KEY rc4_encrypt_key;  static RC4_KEY rc4_encrypt_key;
49    static RSA *server_public_key;
50    
51  static uint8 sec_sign_key[16];  static uint8 sec_sign_key[16];
52  static uint8 sec_decrypt_key[16];  static uint8 sec_decrypt_key[16];
# Line 50  static uint8 sec_decrypt_update_key[16]; Line 55  static uint8 sec_decrypt_update_key[16];
55  static uint8 sec_encrypt_update_key[16];  static uint8 sec_encrypt_update_key[16];
56  static uint8 sec_crypted_random[SEC_MODULUS_SIZE];  static uint8 sec_crypted_random[SEC_MODULUS_SIZE];
57    
58    uint16 server_rdp_version = 0;
59    
60  /*  /*
61   * General purpose 48-byte transformation, using two 32-byte salts (generally,   * General purpose 48-byte transformation, using two 32-byte salts (generally,
62   * a client and server salt) and a global salt value used for padding.   * a client and server salt) and a global salt value used for padding.
# Line 140  sec_generate_keys(uint8 * client_key, ui Line 147  sec_generate_keys(uint8 * client_key, ui
147          }          }
148          else          else
149          {          {
150                  DEBUG(("128-bit encryption enabled\n"));                  DEBUG(("rc_4_key_size == %d, 128-bit encryption enabled\n", rc4_key_size));
151                  rc4_key_len = 16;                  rc4_key_len = 16;
152          }          }
153    
# Line 251  sec_encrypt(uint8 * data, int length) Line 258  sec_encrypt(uint8 * data, int length)
258  }  }
259    
260  /* Decrypt data using RC4 */  /* Decrypt data using RC4 */
261  static void  void
262  sec_decrypt(uint8 * data, int length)  sec_decrypt(uint8 * data, int length)
263  {  {
264          static int use_count;          static int use_count;
# Line 285  reverse(uint8 * p, int len) Line 292  reverse(uint8 * p, int len)
292  static void  static void
293  sec_rsa_encrypt(uint8 * out, uint8 * in, int len, uint8 * modulus, uint8 * exponent)  sec_rsa_encrypt(uint8 * out, uint8 * in, int len, uint8 * modulus, uint8 * exponent)
294  {  {
295          BN_CTX ctx;          BN_CTX *ctx;
296          BIGNUM mod, exp, x, y;          BIGNUM mod, exp, x, y;
297          uint8 inr[SEC_MODULUS_SIZE];          uint8 inr[SEC_MODULUS_SIZE];
298          int outlen;          int outlen;
# Line 295  sec_rsa_encrypt(uint8 * out, uint8 * in, Line 302  sec_rsa_encrypt(uint8 * out, uint8 * in,
302          memcpy(inr, in, len);          memcpy(inr, in, len);
303          reverse(inr, len);          reverse(inr, len);
304    
305          BN_CTX_init(&ctx);          ctx = BN_CTX_new();
306          BN_init(&mod);          BN_init(&mod);
307          BN_init(&exp);          BN_init(&exp);
308          BN_init(&x);          BN_init(&x);
# Line 304  sec_rsa_encrypt(uint8 * out, uint8 * in, Line 311  sec_rsa_encrypt(uint8 * out, uint8 * in,
311          BN_bin2bn(modulus, SEC_MODULUS_SIZE, &mod);          BN_bin2bn(modulus, SEC_MODULUS_SIZE, &mod);
312          BN_bin2bn(exponent, SEC_EXPONENT_SIZE, &exp);          BN_bin2bn(exponent, SEC_EXPONENT_SIZE, &exp);
313          BN_bin2bn(inr, len, &x);          BN_bin2bn(inr, len, &x);
314          BN_mod_exp(&y, &x, &exp, &mod, &ctx);          BN_mod_exp(&y, &x, &exp, &mod, ctx);
315          outlen = BN_bn2bin(&y, out);          outlen = BN_bn2bin(&y, out);
316          reverse(out, outlen);          reverse(out, outlen);
317          if (outlen < SEC_MODULUS_SIZE)          if (outlen < SEC_MODULUS_SIZE)
# Line 314  sec_rsa_encrypt(uint8 * out, uint8 * in, Line 321  sec_rsa_encrypt(uint8 * out, uint8 * in,
321          BN_clear_free(&x);          BN_clear_free(&x);
322          BN_free(&exp);          BN_free(&exp);
323          BN_free(&mod);          BN_free(&mod);
324          BN_CTX_free(&ctx);          BN_CTX_free(ctx);
325  }  }
326    
327  /* Initialise secure transport packet */  /* Initialise secure transport packet */
# Line 324  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 334  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 358  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 383  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 + (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 393  sec_out_mcs_data(STREAM s) Line 418  sec_out_mcs_data(STREAM s)
418          out_uint8(s, 0x7c);          out_uint8(s, 0x7c);
419          out_uint16_be(s, 1);          out_uint16_be(s, 1);
420    
421          out_uint16_be(s, (158 | 0x8000));       /* remaining length */          out_uint16_be(s, (length | 0x8000));    /* remaining length */
422    
423          out_uint16_be(s, 8);    /* length? */          out_uint16_be(s, 8);    /* length? */
424          out_uint16_be(s, 16);          out_uint16_be(s, 16);
# Line 402  sec_out_mcs_data(STREAM s) Line 427  sec_out_mcs_data(STREAM s)
427          out_uint8(s, 0);          out_uint8(s, 0);
428    
429          out_uint32_le(s, 0x61637544);   /* "Duca" ?! */          out_uint32_le(s, 0x61637544);   /* "Duca" ?! */
430          out_uint16_be(s, (144 | 0x8000));       /* remaining length */          out_uint16_be(s, ((length - 14) | 0x8000));     /* remaining length */
431    
432          /* Client information */          /* Client information */
433          out_uint16_le(s, SEC_TAG_CLI_INFO);          out_uint16_le(s, SEC_TAG_CLI_INFO);
434          out_uint16_le(s, 136);  /* length */          out_uint16_le(s, 212);  /* length */
435          out_uint16_le(s, 1);          out_uint16_le(s, use_rdp5 ? 4 : 1);     /* RDP version. 1 == RDP4, 4 == RDP5. */
436          out_uint16_le(s, 8);          out_uint16_le(s, 8);
437          out_uint16_le(s, width);          out_uint16_le(s, width);
438          out_uint16_le(s, height);          out_uint16_le(s, height);
439          out_uint16_le(s, 0xca01);          out_uint16_le(s, 0xca01);
440          out_uint16_le(s, 0xaa03);          out_uint16_le(s, 0xaa03);
441          out_uint32_le(s, keylayout);          out_uint32_le(s, keylayout);
442          out_uint32_le(s, 419);  /* client build? we are 419 compatible :-) */          out_uint32_le(s, 2600); /* Client build. We are now 2600 compatible :-) */
443    
444          /* Unicode name of client, padded to 32 bytes */          /* Unicode name of client, padded to 32 bytes */
445          rdp_out_unistr(s, hostname, hostlen);          rdp_out_unistr(s, hostname, hostlen);
# Line 425  sec_out_mcs_data(STREAM s) Line 450  sec_out_mcs_data(STREAM s)
450          out_uint32_le(s, 12);          out_uint32_le(s, 12);
451          out_uint8s(s, 64);      /* reserved? 4 + 12 doublewords */          out_uint8s(s, 64);      /* reserved? 4 + 12 doublewords */
452    
453          out_uint16_le(s, 0xca01);          switch (server_bpp)
454          out_uint16(s, 0);          {
455                    case 8:
456                            out_uint16_le(s, 0xca01);
457                            break;
458                    case 15:
459                            out_uint16_le(s, 0xca02);
460                            break;
461                    case 16:
462                            out_uint16_le(s, 0xca03);
463                            break;
464                    case 24:
465                            out_uint16_le(s, 0xca04);
466                            break;
467            }
468            out_uint16_le(s, 1);
469    
470            out_uint32(s, 0);
471            out_uint8(s, server_bpp);
472            out_uint16_le(s, 0x0700);
473            out_uint8(s, 0);
474            out_uint32_le(s, 1);
475            out_uint8s(s, 64);      /* End of client info */
476    
477            out_uint16_le(s, SEC_TAG_CLI_4);
478            out_uint16_le(s, 12);
479            out_uint32_le(s, 9);
480            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, 8);    /* 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(s, 0);       /* Unknown */
487    
488            DEBUG_RDP5(("num_channels is %d\n", num_channels));
489            if (0 < num_channels)
490            {
491                    out_uint16_le(s, SEC_TAG_CLI_CHANNELS);
492                    out_uint16_le(s, num_channels * CHANNEL_TAGDATA_SIZE + 4 + 4);  /* length */
493                    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  }  }
505    
# Line 463  sec_parse_public_key(STREAM s, uint8 ** Line 531  sec_parse_public_key(STREAM s, uint8 **
531          return s_check(s);          return s_check(s);
532  }  }
533    
534    static BOOL
535    sec_parse_x509_key(X509 * cert)
536    {
537            EVP_PKEY *epk = NULL;
538            /* By some reason, Microsoft sets the OID of the Public RSA key to
539               the oid for "MD5 with RSA Encryption" instead of "RSA Encryption"
540    
541               Kudos to Richard Levitte for the following (. intiutive .)
542               lines of code that resets the OID and let's us extract the key. */
543            if (OBJ_obj2nid(cert->cert_info->key->algor->algorithm) == NID_md5WithRSAEncryption)
544            {
545                    DEBUG_RDP5(("Re-setting algorithm type to RSA in server certificate\n"));
546                    cert->cert_info->key->algor->algorithm = OBJ_nid2obj(NID_rsaEncryption);
547            }
548            epk = X509_get_pubkey(cert);
549            if (NULL == epk)
550            {
551                    error("Failed to extract public key from certificate\n");
552                    return False;
553            }
554    
555            server_public_key = (RSA *) epk->pkey.ptr;
556    
557            return True;
558    }
559    
560    
561  /* Parse a crypto information structure */  /* Parse a crypto information structure */
562  static BOOL  static BOOL
563  sec_parse_crypt_info(STREAM s, uint32 * rc4_key_size,  sec_parse_crypt_info(STREAM s, uint32 * rc4_key_size,
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, flags;
568            X509 *cacert, *server_cert;
569          uint16 tag, length;          uint16 tag, length;
570          uint8 *next_tag, *end;          uint8 *next_tag, *end;
571    
572          in_uint32_le(s, *rc4_key_size); /* 1 = 40-bit, 2 = 128-bit */          in_uint32_le(s, *rc4_key_size); /* 1 = 40-bit, 2 = 128-bit */
573          in_uint32_le(s, crypt_level);   /* 1 = low, 2 = medium, 3 = high */          in_uint32_le(s, crypt_level);   /* 1 = low, 2 = medium, 3 = high */
574          if (crypt_level == 0)   /* no encryptation */          if (crypt_level == 0)   /* no encryption */
575                  return False;                  return False;
576          in_uint32_le(s, random_len);          in_uint32_le(s, random_len);
577          in_uint32_le(s, rsa_info_len);          in_uint32_le(s, rsa_info_len);
578    
579          if (random_len != SEC_RANDOM_SIZE)          if (random_len != SEC_RANDOM_SIZE)
580          {          {
581                  error("random len %d\n", random_len);                  error("random len %d, expected %d\n", random_len, SEC_RANDOM_SIZE);
582                  return False;                  return False;
583          }          }
584    
# Line 492  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          in_uint8s(s, 12);       /* unknown */          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"));
596                    in_uint8s(s, 8);        /* unknown */
597    
598                    while (s->p < end)
599                    {
600                            in_uint16_le(s, tag);
601                            in_uint16_le(s, length);
602    
603                            next_tag = s->p + length;
604    
605                            switch (tag)
606                            {
607                                    case SEC_TAG_PUBKEY:
608                                            if (!sec_parse_public_key(s, modulus, exponent))
609                                                    return False;
610                                            DEBUG_RDP5(("Got Public key, RDP4-style\n"));
611    
612                                            break;
613    
614                                    case SEC_TAG_KEYSIG:
615                                            /* Is this a Microsoft key that we just got? */
616                                            /* Care factor: zero! */
617                                            /* Actually, it would probably be a good idea to check if the public key is signed with this key, and then store this
618                                               key as a known key of the hostname. This would prevent some MITM-attacks. */
619                                            break;
620    
621                                    default:
622                                            unimpl("crypt tag 0x%x\n", tag);
623                            }
624    
625          while (s->p < end)                          s->p = next_tag;
626                    }
627            }
628            else
629          {          {
630                  in_uint16_le(s, tag);                  DEBUG_RDP5(("We're going for the RDP5-style encryption\n"));
631                  in_uint16_le(s, length);                  in_uint8s(s, 4);        /* Number of certificates */
632    
633                  next_tag = s->p + length;                  /* Do da funky X.509 stuffy
634    
635                  switch (tag)                     "How did I find out about this?  I looked up and saw a
636                       bright light and when I came to I had a scar on my forehead
637                       and knew about X.500"
638                       - Peter Gutman in a early version of
639                       http://www.cs.auckland.ac.nz/~pgut001/pubs/x509guide.txt
640                     */
641    
642                    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);
645                    /* Note: We don't need to move s->p here - d2i_X509 is
646                       "kind" enough to do it for us */
647                    if (NULL == cacert)
648                  {                  {
649                          case SEC_TAG_PUBKEY:                          error("Couldn't load CA Certificate from server\n");
650                                  if (!sec_parse_public_key(s, modulus, exponent))                          return False;
651                                          return False;                  }
652    
653                                  break;                  /* Currently, we don't use the CA Certificate.
654                       FIXME:
655                       *) Verify the server certificate (server_cert) with the
656                       CA certificate.
657                       *) Store the CA Certificate with the hostname of the
658                       server we are connecting to as key, and compare it
659                       when we connect the next time, in order to prevent
660                       MITM-attacks.
661                     */
662    
663                    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);
666                    if (NULL == server_cert)
667                    {
668                            error("Couldn't load Certificate from server\n");
669                            return False;
670                    }
671    
672                          case SEC_TAG_KEYSIG:                  in_uint8s(s, 16);       /* Padding */
                                 /* Is this a Microsoft key that we just got? */  
                                 /* Care factor: zero! */  
                                 break;  
673    
674                          default:                  /* Note: Verifying the server certificate must be done here,
675                                  unimpl("crypt tag 0x%x\n", tag);                     before sec_parse_public_key since we'll have to apply
676                  }                     serious violence to the key after this */
677    
678                  s->p = next_tag;                  if (!sec_parse_x509_key(server_cert))
679                    {
680                            DEBUG_RDP5(("Didn't parse X509 correctly\n"));
681                            return False;
682                    }
683                    return True;    /* There's some garbage here we don't care about */
684          }          }
   
685          return s_check_end(s);          return s_check_end(s);
686  }  }
687    
# Line 531  sec_process_crypt_info(STREAM s) Line 692  sec_process_crypt_info(STREAM s)
692          uint8 *server_random, *modulus, *exponent;          uint8 *server_random, *modulus, *exponent;
693          uint8 client_random[SEC_RANDOM_SIZE];          uint8 client_random[SEC_RANDOM_SIZE];
694          uint32 rc4_key_size;          uint32 rc4_key_size;
695            uint8 inr[SEC_MODULUS_SIZE];
696    
697          if (!sec_parse_crypt_info(s, &rc4_key_size, &server_random, &modulus, &exponent))          if (!sec_parse_crypt_info(s, &rc4_key_size, &server_random, &modulus, &exponent))
698            {
699                    DEBUG(("Failed to parse crypt info\n"));
700                  return;                  return;
701            }
702    
703            DEBUG(("Generating client random\n"));
704          /* Generate a client random, and hence determine encryption keys */          /* Generate a client random, and hence determine encryption keys */
705            // This is what the MS client do:
706            memset(inr, 0, SEC_RANDOM_SIZE);
707            /*  *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          sec_rsa_encrypt(sec_crypted_random, client_random, SEC_RANDOM_SIZE, modulus, exponent);          if (NULL != server_public_key)
717            {                       /* Which means we should use
718                                       RDP5-style encryption */
719    
720                    memcpy(inr + SEC_RANDOM_SIZE, client_random, SEC_RANDOM_SIZE);
721                    reverse(inr + SEC_RANDOM_SIZE, SEC_RANDOM_SIZE);
722    
723                    RSA_public_encrypt(SEC_MODULUS_SIZE,
724                                       inr, sec_crypted_random, server_public_key, RSA_NO_PADDING);
725    
726                    reverse(sec_crypted_random, SEC_MODULUS_SIZE);
727    
728            }
729            else
730            {                       /* RDP4-style encryption */
731                    sec_rsa_encrypt(sec_crypted_random,
732                                    client_random, SEC_RANDOM_SIZE, modulus, exponent);
733            }
734          sec_generate_keys(client_random, server_random, rc4_key_size);          sec_generate_keys(client_random, server_random, rc4_key_size);
735  }  }
736    
737  /* Process connect response data blob */  
738    /* Process SRV_INFO, find RDP version supported by server */
739  static void  static void
740    sec_process_srv_info(STREAM s)
741    {
742            in_uint16_le(s, server_rdp_version);
743            DEBUG_RDP5(("Server RDP version is %d\n", server_rdp_version));
744    }
745    
746    
747    /* Process connect response data blob */
748    void
749  sec_process_mcs_data(STREAM s)  sec_process_mcs_data(STREAM s)
750  {  {
751          uint16 tag, length;          uint16 tag, length;
752          uint8 *next_tag;          uint8 *next_tag;
753          uint8 len;          uint8 len;
754    
755          in_uint8s(s, 21);       /* header */          in_uint8s(s, 21);       /* header (T.124 stuff, probably) */
756          in_uint8(s, len);          in_uint8(s, len);
757          if (len & 0x80)          if (len & 0x80)
758                  in_uint8(s, len);                  in_uint8(s, len);
# Line 567  sec_process_mcs_data(STREAM s) Line 770  sec_process_mcs_data(STREAM s)
770                  switch (tag)                  switch (tag)
771                  {                  {
772                          case SEC_TAG_SRV_INFO:                          case SEC_TAG_SRV_INFO:
773                                    sec_process_srv_info(s);
774                                    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 587  STREAM Line 796  STREAM
796  sec_recv(void)  sec_recv(void)
797  {  {
798          uint32 sec_flags;          uint32 sec_flags;
799            uint16 channel;
800          STREAM s;          STREAM s;
801    
802          while ((s = mcs_recv()) != 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)
811                                    {
812                                            DEBUG_RDP5(("Encrypted license detected\n"));
813                                    }
814                                  licence_process(s);                                  licence_process(s);
815                                  continue;                                  continue;
816                          }                          }
# Line 608  sec_recv(void) Line 822  sec_recv(void)
822                          }                          }
823                  }                  }
824    
825                  return s;                  if (MCS_GLOBAL_CHANNEL == channel)
826                    {
827                            return s;
828                    }
829                    else
830                            rdp5_process_channel(s, channel);
831    
832          }          }
833    
834          return NULL;          return NULL;
# Line 616  sec_recv(void) Line 836  sec_recv(void)
836    
837  /* Establish a secure connection */  /* Establish a secure connection */
838  BOOL  BOOL
839  sec_connect(char *server)  sec_connect(char *server, char *username)
840  {  {
841          struct stream mcs_data;          struct stream mcs_data;
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))          if (!mcs_connect(server, &mcs_data, username))
849                  return False;                  return False;
850    
851          sec_process_mcs_data(&mcs_data);          //      sec_process_mcs_data(&mcs_data);
852          if (encryption)          if (encryption)
853                  sec_establish_key();                  sec_establish_key();
854            xfree(mcs_data.data);
855          return True;          return True;
856  }  }
857    

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

  ViewVC Help
Powered by ViewVC 1.1.26