/[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 437 by jsorg71, Mon Jul 28 21:41:12 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 36  extern char hostname[16]; Line 37  extern char hostname[16];
37  extern int width;  extern int width;
38  extern int height;  extern int 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;
43    extern int 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;
50  static RC4_KEY rc4_encrypt_key;  static RC4_KEY rc4_encrypt_key;
51    static RSA *server_public_key;
52    
53  static uint8 sec_sign_key[16];  static uint8 sec_sign_key[16];
54  static uint8 sec_decrypt_key[16];  static uint8 sec_decrypt_key[16];
# Line 50  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;
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,
64   * 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 149  sec_generate_keys(uint8 * client_key, ui
149          }          }
150          else          else
151          {          {
152                  DEBUG(("128-bit encryption enabled\n"));                  DEBUG(("rc_4_key_size == %d, 128-bit encryption enabled\n", rc4_key_size));
153                  rc4_key_len = 16;                  rc4_key_len = 16;
154          }          }
155    
# Line 251  sec_encrypt(uint8 * data, int length) Line 260  sec_encrypt(uint8 * data, int length)
260  }  }
261    
262  /* Decrypt data using RC4 */  /* Decrypt data using RC4 */
263  static void  void
264  sec_decrypt(uint8 * data, int length)  sec_decrypt(uint8 * data, int length)
265  {  {
266          static int use_count;          static int use_count;
# Line 285  reverse(uint8 * p, int len) Line 294  reverse(uint8 * p, int len)
294  static void  static void
295  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)
296  {  {
297          BN_CTX ctx;          BN_CTX *ctx;
298          BIGNUM mod, exp, x, y;          BIGNUM mod, exp, x, y;
299          uint8 inr[SEC_MODULUS_SIZE];          uint8 inr[SEC_MODULUS_SIZE];
300          int outlen;          int outlen;
# Line 295  sec_rsa_encrypt(uint8 * out, uint8 * in, Line 304  sec_rsa_encrypt(uint8 * out, uint8 * in,
304          memcpy(inr, in, len);          memcpy(inr, in, len);
305          reverse(inr, len);          reverse(inr, len);
306    
307          BN_CTX_init(&ctx);          ctx = BN_CTX_new();
308          BN_init(&mod);          BN_init(&mod);
309          BN_init(&exp);          BN_init(&exp);
310          BN_init(&x);          BN_init(&x);
# Line 304  sec_rsa_encrypt(uint8 * out, uint8 * in, Line 313  sec_rsa_encrypt(uint8 * out, uint8 * in,
313          BN_bin2bn(modulus, SEC_MODULUS_SIZE, &mod);          BN_bin2bn(modulus, SEC_MODULUS_SIZE, &mod);
314          BN_bin2bn(exponent, SEC_EXPONENT_SIZE, &exp);          BN_bin2bn(exponent, SEC_EXPONENT_SIZE, &exp);
315          BN_bin2bn(inr, len, &x);          BN_bin2bn(inr, len, &x);
316          BN_mod_exp(&y, &x, &exp, &mod, &ctx);          BN_mod_exp(&y, &x, &exp, &mod, ctx);
317          outlen = BN_bn2bin(&y, out);          outlen = BN_bn2bin(&y, out);
318          reverse(out, outlen);          reverse(out, outlen);
319          if (outlen < SEC_MODULUS_SIZE)          if (outlen < SEC_MODULUS_SIZE)
# Line 314  sec_rsa_encrypt(uint8 * out, uint8 * in, Line 323  sec_rsa_encrypt(uint8 * out, uint8 * in,
323          BN_clear_free(&x);          BN_clear_free(&x);
324          BN_free(&exp);          BN_free(&exp);
325          BN_free(&mod);          BN_free(&mod);
326          BN_CTX_free(&ctx);          BN_CTX_free(ctx);
327  }  }
328    
329  /* Initialise secure transport packet */  /* Initialise secure transport packet */
# Line 324  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 334  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 358  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 384  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;
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 393  sec_out_mcs_data(STREAM s) Line 416  sec_out_mcs_data(STREAM s)
416          out_uint8(s, 0x7c);          out_uint8(s, 0x7c);
417          out_uint16_be(s, 1);          out_uint16_be(s, 1);
418    
419          out_uint16_be(s, (158 | 0x8000));       /* remaining length */          out_uint16_be(s, (length | 0x8000));    /* remaining length */
420    
421          out_uint16_be(s, 8);    /* length? */          out_uint16_be(s, 8);    /* length? */
422          out_uint16_be(s, 16);          out_uint16_be(s, 16);
# Line 402  sec_out_mcs_data(STREAM s) Line 425  sec_out_mcs_data(STREAM s)
425          out_uint8(s, 0);          out_uint8(s, 0);
426    
427          out_uint32_le(s, 0x61637544);   /* "Duca" ?! */          out_uint32_le(s, 0x61637544);   /* "Duca" ?! */
428          out_uint16_be(s, (144 | 0x8000));       /* remaining length */          out_uint16_be(s, ((length - 14) | 0x8000));     /* remaining length */
429    
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, 136);  /* length */          out_uint16_le(s, 212);  /* length */
433          out_uint16_le(s, 1);          out_uint16_le(s, 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, width);
436          out_uint16_le(s, height);          out_uint16_le(s, 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);
440          out_uint32_le(s, 419);  /* client build? we are 419 compatible :-) */          out_uint32_le(s, 2600); /* Client build. We are now 2600 compatible :-) */
441    
442          /* Unicode name of client, padded to 32 bytes */          /* Unicode name of client, padded to 32 bytes */
443          rdp_out_unistr(s, hostname, hostlen);          rdp_out_unistr(s, hostname, hostlen);
# Line 425  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          out_uint16_le(s, 0xca01);          switch (server_bpp)
452          out_uint16(s, 0);          {
453                    case 8:
454                            out_uint16_le(s, 0xca01);
455                            break;
456                    case 15:
457                            out_uint16_le(s, 0xca02);
458                            break;
459                    case 16:
460                            out_uint16_le(s, 0xca03);
461                            break;
462                    case 24:
463                            out_uint16_le(s, 0xca04);
464                            break;
465            }
466            out_uint16_le(s, 1);
467    
468            out_uint32(s, 0);
469            out_uint8(s, server_bpp);
470            out_uint16_le(s, 0x0700);
471            out_uint8(s, 0);
472            out_uint32_le(s, 1);
473            out_uint8s(s, 64);      /* End of client info */
474    
475            out_uint16_le(s, SEC_TAG_CLI_4);
476            out_uint16_le(s, 12);
477            out_uint32_le(s, 9);
478            out_uint32(s, 0);
479    
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, 8);    /* 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 */
485    
486            DEBUG_RDP5(("g_num_channels is %d\n", g_num_channels));
487            if (g_num_channels > 0)
488            {
489                    out_uint16_le(s, SEC_TAG_CLI_CHANNELS);
490                    out_uint16_le(s, g_num_channels * 12 + 8);      /* length */
491                    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  }  }
502    
# Line 463  sec_parse_public_key(STREAM s, uint8 ** Line 528  sec_parse_public_key(STREAM s, uint8 **
528          return s_check(s);          return s_check(s);
529  }  }
530    
531    static BOOL
532    sec_parse_x509_key(X509 * cert)
533    {
534            EVP_PKEY *epk = NULL;
535            /* By some reason, Microsoft sets the OID of the Public RSA key to
536               the oid for "MD5 with RSA Encryption" instead of "RSA Encryption"
537    
538               Kudos to Richard Levitte for the following (. intiutive .)
539               lines of code that resets the OID and let's us extract the key. */
540            if (OBJ_obj2nid(cert->cert_info->key->algor->algorithm) == NID_md5WithRSAEncryption)
541            {
542                    DEBUG_RDP5(("Re-setting algorithm type to RSA in server certificate\n"));
543                    cert->cert_info->key->algor->algorithm = OBJ_nid2obj(NID_rsaEncryption);
544            }
545            epk = X509_get_pubkey(cert);
546            if (NULL == epk)
547            {
548                    error("Failed to extract public key from certificate\n");
549                    return False;
550            }
551    
552            server_public_key = (RSA *) epk->pkey.ptr;
553    
554            return True;
555    }
556    
557    
558  /* Parse a crypto information structure */  /* Parse a crypto information structure */
559  static BOOL  static BOOL
560  sec_parse_crypt_info(STREAM s, uint32 * rc4_key_size,  sec_parse_crypt_info(STREAM s, uint32 * rc4_key_size,
561                       uint8 ** server_random, uint8 ** modulus, uint8 ** exponent)                       uint8 ** server_random, uint8 ** modulus, uint8 ** exponent)
562  {  {
563          uint32 crypt_level, random_len, rsa_info_len;          uint32 crypt_level, random_len, rsa_info_len;
564            uint32 cacert_len, cert_len, flags;
565            X509 *cacert, *server_cert;
566          uint16 tag, length;          uint16 tag, length;
567          uint8 *next_tag, *end;          uint8 *next_tag, *end;
568    
569          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 */
570          in_uint32_le(s, crypt_level);   /* 1 = low, 2 = medium, 3 = high */          in_uint32_le(s, crypt_level);   /* 1 = low, 2 = medium, 3 = high */
571          if (crypt_level == 0)   /* no encryptation */          if (crypt_level == 0)   /* no encryption */
572                  return False;                  return False;
573          in_uint32_le(s, random_len);          in_uint32_le(s, random_len);
574          in_uint32_le(s, rsa_info_len);          in_uint32_le(s, rsa_info_len);
575    
576          if (random_len != SEC_RANDOM_SIZE)          if (random_len != SEC_RANDOM_SIZE)
577          {          {
578                  error("random len %d\n", random_len);                  error("random len %d, expected %d\n", random_len, SEC_RANDOM_SIZE);
579                  return False;                  return False;
580          }          }
581    
# Line 492  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_uint8s(s, 12);       /* unknown */          in_uint32_le(s, flags); /* 1 = RDP4-style, 0x80000002 = X.509 */
590            if (flags & 1)
591            {
592                    DEBUG_RDP5(("We're going for the RDP4-style encryption\n"));
593                    in_uint8s(s, 8);        /* unknown */
594    
595                    while (s->p < end)
596                    {
597                            in_uint16_le(s, tag);
598                            in_uint16_le(s, length);
599    
600                            next_tag = s->p + length;
601    
602                            switch (tag)
603                            {
604                                    case SEC_TAG_PUBKEY:
605                                            if (!sec_parse_public_key(s, modulus, exponent))
606                                                    return False;
607                                            DEBUG_RDP5(("Got Public key, RDP4-style\n"));
608    
609                                            break;
610    
611                                    case SEC_TAG_KEYSIG:
612                                            /* Is this a Microsoft key that we just got? */
613                                            /* Care factor: zero! */
614                                            /* Actually, it would probably be a good idea to check if the public key is signed with this key, and then store this
615                                               key as a known key of the hostname. This would prevent some MITM-attacks. */
616                                            break;
617    
618                                    default:
619                                            unimpl("crypt tag 0x%x\n", tag);
620                            }
621    
622          while (s->p < end)                          s->p = next_tag;
623                    }
624            }
625            else
626          {          {
627                  in_uint16_le(s, tag);                  DEBUG_RDP5(("We're going for the RDP5-style encryption\n"));
628                  in_uint16_le(s, length);                  in_uint8s(s, 4);        /* Number of certificates */
629    
630                  next_tag = s->p + length;                  /* Do da funky X.509 stuffy
631    
632                  switch (tag)                     "How did I find out about this?  I looked up and saw a
633                       bright light and when I came to I had a scar on my forehead
634                       and knew about X.500"
635                       - Peter Gutman in a early version of
636                       http://www.cs.auckland.ac.nz/~pgut001/pubs/x509guide.txt
637                     */
638    
639                    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);
642                    /* Note: We don't need to move s->p here - d2i_X509 is
643                       "kind" enough to do it for us */
644                    if (NULL == cacert)
645                  {                  {
646                          case SEC_TAG_PUBKEY:                          error("Couldn't load CA Certificate from server\n");
647                                  if (!sec_parse_public_key(s, modulus, exponent))                          return False;
648                                          return False;                  }
649    
650                                  break;                  /* Currently, we don't use the CA Certificate.
651                       FIXME:
652                       *) Verify the server certificate (server_cert) with the
653                       CA certificate.
654                       *) Store the CA Certificate with the hostname of the
655                       server we are connecting to as key, and compare it
656                       when we connect the next time, in order to prevent
657                       MITM-attacks.
658                     */
659    
660                    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);
663                    if (NULL == server_cert)
664                    {
665                            error("Couldn't load Certificate from server\n");
666                            return False;
667                    }
668    
669                          case SEC_TAG_KEYSIG:                  in_uint8s(s, 16);       /* Padding */
                                 /* Is this a Microsoft key that we just got? */  
                                 /* Care factor: zero! */  
                                 break;  
670    
671                          default:                  /* Note: Verifying the server certificate must be done here,
672                                  unimpl("crypt tag 0x%x\n", tag);                     before sec_parse_public_key since we'll have to apply
673                  }                     serious violence to the key after this */
674    
675                  s->p = next_tag;                  if (!sec_parse_x509_key(server_cert))
676                    {
677                            DEBUG_RDP5(("Didn't parse X509 correctly\n"));
678                            return False;
679                    }
680                    return True;    /* There's some garbage here we don't care about */
681          }          }
   
682          return s_check_end(s);          return s_check_end(s);
683  }  }
684    
# Line 531  sec_process_crypt_info(STREAM s) Line 689  sec_process_crypt_info(STREAM s)
689          uint8 *server_random, *modulus, *exponent;          uint8 *server_random, *modulus, *exponent;
690          uint8 client_random[SEC_RANDOM_SIZE];          uint8 client_random[SEC_RANDOM_SIZE];
691          uint32 rc4_key_size;          uint32 rc4_key_size;
692            uint8 inr[SEC_MODULUS_SIZE];
693    
694          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))
695            {
696                    DEBUG(("Failed to parse crypt info\n"));
697                  return;                  return;
698            }
699    
700            DEBUG(("Generating client random\n"));
701          /* Generate a client random, and hence determine encryption keys */          /* Generate a client random, and hence determine encryption keys */
702            // This is what the MS client do:
703            memset(inr, 0, SEC_RANDOM_SIZE);
704            /*  *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          sec_rsa_encrypt(sec_crypted_random, client_random, SEC_RANDOM_SIZE, modulus, exponent);          if (NULL != server_public_key)
714            {                       /* Which means we should use
715                                       RDP5-style encryption */
716    
717                    memcpy(inr + SEC_RANDOM_SIZE, client_random, SEC_RANDOM_SIZE);
718                    reverse(inr + SEC_RANDOM_SIZE, SEC_RANDOM_SIZE);
719    
720                    RSA_public_encrypt(SEC_MODULUS_SIZE,
721                                       inr, sec_crypted_random, server_public_key, RSA_NO_PADDING);
722    
723                    reverse(sec_crypted_random, SEC_MODULUS_SIZE);
724    
725            }
726            else
727            {                       /* RDP4-style encryption */
728                    sec_rsa_encrypt(sec_crypted_random,
729                                    client_random, SEC_RANDOM_SIZE, modulus, exponent);
730            }
731          sec_generate_keys(client_random, server_random, rc4_key_size);          sec_generate_keys(client_random, server_random, rc4_key_size);
732  }  }
733    
734  /* Process connect response data blob */  
735    /* Process SRV_INFO, find RDP version supported by server */
736  static void  static void
737    sec_process_srv_info(STREAM s)
738    {
739            in_uint16_le(s, server_rdp_version);
740            DEBUG_RDP5(("Server RDP version is %d\n", server_rdp_version));
741            if (1 == server_rdp_version)
742                    use_rdp5 = 0;
743    }
744    
745    
746    /* Process connect response data blob */
747    void
748  sec_process_mcs_data(STREAM s)  sec_process_mcs_data(STREAM s)
749  {  {
750          uint16 tag, length;          uint16 tag, length;
751          uint8 *next_tag;          uint8 *next_tag;
752          uint8 len;          uint8 len;
753    
754          in_uint8s(s, 21);       /* header */          in_uint8s(s, 21);       /* header (T.124 stuff, probably) */
755          in_uint8(s, len);          in_uint8(s, len);
756          if (len & 0x80)          if (len & 0x80)
757                  in_uint8(s, len);                  in_uint8(s, len);
# Line 567  sec_process_mcs_data(STREAM s) Line 769  sec_process_mcs_data(STREAM s)
769                  switch (tag)                  switch (tag)
770                  {                  {
771                          case SEC_TAG_SRV_INFO:                          case SEC_TAG_SRV_INFO:
772                          case SEC_TAG_SRV_3:                                  sec_process_srv_info(s);
773                                  break;                                  break;
774    
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 587  STREAM Line 795  STREAM
795  sec_recv(void)  sec_recv(void)
796  {  {
797          uint32 sec_flags;          uint32 sec_flags;
798            uint16 channel;
799          STREAM s;          STREAM s;
800    
801          while ((s = mcs_recv()) != 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    
807                            if (sec_flags & SEC_ENCRYPT)
808                            {
809                                    in_uint8s(s, 8);        /* signature */
810                                    sec_decrypt(s->p, s->end - s->p);
811                            }
812    
813                          if (sec_flags & SEC_LICENCE_NEG)                          if (sec_flags & SEC_LICENCE_NEG)
814                          {                          {
815                                  licence_process(s);                                  licence_process(s);
816                                  continue;                                  continue;
817                          }                          }
818                    }
819    
820                          if (sec_flags & SEC_ENCRYPT)                  if (channel != MCS_GLOBAL_CHANNEL)
821                          {                  {
822                                  in_uint8s(s, 8);        /* signature */                          channel_process(s, channel);
823                                  sec_decrypt(s->p, s->end - s->p);                          continue;
                         }  
824                  }                  }
825    
826                  return s;                  return s;
# Line 616  sec_recv(void) Line 831  sec_recv(void)
831    
832  /* Establish a secure connection */  /* Establish a secure connection */
833  BOOL  BOOL
834  sec_connect(char *server)  sec_connect(char *server, char *username)
835  {  {
836          struct stream mcs_data;          struct stream mcs_data;
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 = 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))          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);
850          return True;          return True;
851  }  }
852    

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

  ViewVC Help
Powered by ViewVC 1.1.26