/[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 540 by astrand, Fri Oct 31 20:34:26 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 33  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 g_use_rdp5;
43    extern BOOL g_console_session;
44    extern int g_server_bpp;
45    extern uint16 mcs_userid;
46    extern VCHANNEL g_channels[];
47    extern unsigned int g_num_channels;
48    
49  static int rc4_key_len;  static int rc4_key_len;
50  static RC4_KEY rc4_decrypt_key;  static RC4_KEY rc4_decrypt_key;
51  static RC4_KEY rc4_encrypt_key;  static RC4_KEY rc4_encrypt_key;
52    static RSA *server_public_key;
53    
54  static uint8 sec_sign_key[16];  static uint8 sec_sign_key[16];
55  static uint8 sec_decrypt_key[16];  static uint8 sec_decrypt_key[16];
# Line 50  static uint8 sec_decrypt_update_key[16]; Line 58  static uint8 sec_decrypt_update_key[16];
58  static uint8 sec_encrypt_update_key[16];  static uint8 sec_encrypt_update_key[16];
59  static uint8 sec_crypted_random[SEC_MODULUS_SIZE];  static uint8 sec_crypted_random[SEC_MODULUS_SIZE];
60    
61    uint16 g_server_rdp_version = 0;
62    
63  /*  /*
64   * General purpose 48-byte transformation, using two 32-byte salts (generally,   * General purpose 48-byte transformation, using two 32-byte salts (generally,
65   * 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 150  sec_generate_keys(uint8 * client_key, ui
150          }          }
151          else          else
152          {          {
153                  DEBUG(("128-bit encryption enabled\n"));                  DEBUG(("rc_4_key_size == %d, 128-bit encryption enabled\n", rc4_key_size));
154                  rc4_key_len = 16;                  rc4_key_len = 16;
155          }          }
156    
# Line 251  sec_encrypt(uint8 * data, int length) Line 261  sec_encrypt(uint8 * data, int length)
261  }  }
262    
263  /* Decrypt data using RC4 */  /* Decrypt data using RC4 */
264  static void  void
265  sec_decrypt(uint8 * data, int length)  sec_decrypt(uint8 * data, int length)
266  {  {
267          static int use_count;          static int use_count;
# Line 285  reverse(uint8 * p, int len) Line 295  reverse(uint8 * p, int len)
295  static void  static void
296  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)
297  {  {
298          BN_CTX ctx;          BN_CTX *ctx;
299          BIGNUM mod, exp, x, y;          BIGNUM mod, exp, x, y;
300          uint8 inr[SEC_MODULUS_SIZE];          uint8 inr[SEC_MODULUS_SIZE];
301          int outlen;          int outlen;
# Line 295  sec_rsa_encrypt(uint8 * out, uint8 * in, Line 305  sec_rsa_encrypt(uint8 * out, uint8 * in,
305          memcpy(inr, in, len);          memcpy(inr, in, len);
306          reverse(inr, len);          reverse(inr, len);
307    
308          BN_CTX_init(&ctx);          ctx = BN_CTX_new();
309          BN_init(&mod);          BN_init(&mod);
310          BN_init(&exp);          BN_init(&exp);
311          BN_init(&x);          BN_init(&x);
# Line 304  sec_rsa_encrypt(uint8 * out, uint8 * in, Line 314  sec_rsa_encrypt(uint8 * out, uint8 * in,
314          BN_bin2bn(modulus, SEC_MODULUS_SIZE, &mod);          BN_bin2bn(modulus, SEC_MODULUS_SIZE, &mod);
315          BN_bin2bn(exponent, SEC_EXPONENT_SIZE, &exp);          BN_bin2bn(exponent, SEC_EXPONENT_SIZE, &exp);
316          BN_bin2bn(inr, len, &x);          BN_bin2bn(inr, len, &x);
317          BN_mod_exp(&y, &x, &exp, &mod, &ctx);          BN_mod_exp(&y, &x, &exp, &mod, ctx);
318          outlen = BN_bn2bin(&y, out);          outlen = BN_bn2bin(&y, out);
319          reverse(out, outlen);          reverse(out, outlen);
320          if (outlen < SEC_MODULUS_SIZE)          if (outlen < SEC_MODULUS_SIZE)
# Line 314  sec_rsa_encrypt(uint8 * out, uint8 * in, Line 324  sec_rsa_encrypt(uint8 * out, uint8 * in,
324          BN_clear_free(&x);          BN_clear_free(&x);
325          BN_free(&exp);          BN_free(&exp);
326          BN_free(&mod);          BN_free(&mod);
327          BN_CTX_free(&ctx);          BN_CTX_free(ctx);
328  }  }
329    
330  /* Initialise secure transport packet */  /* Initialise secure transport packet */
# Line 324  sec_init(uint32 flags, int maxlen) Line 334  sec_init(uint32 flags, int maxlen)
334          int hdrlen;          int hdrlen;
335          STREAM s;          STREAM s;
336    
337          if (!licence_issued)          if (!g_licence_issued)
338                  hdrlen = (flags & SEC_ENCRYPT) ? 12 : 4;                  hdrlen = (flags & SEC_ENCRYPT) ? 12 : 4;
339          else          else
340                  hdrlen = (flags & SEC_ENCRYPT) ? 12 : 0;                  hdrlen = (flags & SEC_ENCRYPT) ? 12 : 0;
# Line 334  sec_init(uint32 flags, int maxlen) Line 344  sec_init(uint32 flags, int maxlen)
344          return s;          return s;
345  }  }
346    
347  /* Transmit secure transport packet */  /* Transmit secure transport packet over specified channel */
348  void  void
349  sec_send(STREAM s, uint32 flags)  sec_send_to_channel(STREAM s, uint32 flags, uint16 channel)
350  {  {
351          int datalen;          int datalen;
352    
353          s_pop_layer(s, sec_hdr);          s_pop_layer(s, sec_hdr);
354          if (!licence_issued || (flags & SEC_ENCRYPT))          if (!g_licence_issued || (flags & SEC_ENCRYPT))
355                  out_uint32_le(s, flags);                  out_uint32_le(s, flags);
356    
357          if (flags & SEC_ENCRYPT)          if (flags & SEC_ENCRYPT)
# Line 358  sec_send(STREAM s, uint32 flags) Line 368  sec_send(STREAM s, uint32 flags)
368                  sec_encrypt(s->p + 8, datalen);                  sec_encrypt(s->p + 8, datalen);
369          }          }
370    
371          mcs_send(s);          mcs_send_to_channel(s, channel);
372    }
373    
374    /* Transmit secure transport packet */
375    
376    void
377    sec_send(STREAM s, uint32 flags)
378    {
379            sec_send_to_channel(s, flags, MCS_GLOBAL_CHANNEL);
380  }  }
381    
382    
383  /* Transfer the client random to the server */  /* Transfer the client random to the server */
384  static void  static void
385  sec_establish_key(void)  sec_establish_key(void)
# Line 384  static void Line 403  static void
403  sec_out_mcs_data(STREAM s)  sec_out_mcs_data(STREAM s)
404  {  {
405          int hostlen = 2 * strlen(hostname);          int hostlen = 2 * strlen(hostname);
406            int length = 158 + 76 + 12 + 4;
407            unsigned int i;
408    
409            if (g_num_channels > 0)
410                    length += g_num_channels * 12 + 8;
411    
412          if (hostlen > 30)          if (hostlen > 30)
413                  hostlen = 30;                  hostlen = 30;
# Line 393  sec_out_mcs_data(STREAM s) Line 417  sec_out_mcs_data(STREAM s)
417          out_uint8(s, 0x7c);          out_uint8(s, 0x7c);
418          out_uint16_be(s, 1);          out_uint16_be(s, 1);
419    
420          out_uint16_be(s, (158 | 0x8000));       /* remaining length */          out_uint16_be(s, (length | 0x8000));    /* remaining length */
421    
422          out_uint16_be(s, 8);    /* length? */          out_uint16_be(s, 8);    /* length? */
423          out_uint16_be(s, 16);          out_uint16_be(s, 16);
# Line 402  sec_out_mcs_data(STREAM s) Line 426  sec_out_mcs_data(STREAM s)
426          out_uint8(s, 0);          out_uint8(s, 0);
427    
428          out_uint32_le(s, 0x61637544);   /* "Duca" ?! */          out_uint32_le(s, 0x61637544);   /* "Duca" ?! */
429          out_uint16_be(s, (144 | 0x8000));       /* remaining length */          out_uint16_be(s, ((length - 14) | 0x8000));     /* remaining length */
430    
431          /* Client information */          /* Client information */
432          out_uint16_le(s, SEC_TAG_CLI_INFO);          out_uint16_le(s, SEC_TAG_CLI_INFO);
433          out_uint16_le(s, 136);  /* length */          out_uint16_le(s, 212);  /* length */
434          out_uint16_le(s, 1);          out_uint16_le(s, g_use_rdp5 ? 4 : 1);   /* RDP version. 1 == RDP4, 4 == RDP5. */
435          out_uint16_le(s, 8);          out_uint16_le(s, 8);
436          out_uint16_le(s, width);          out_uint16_le(s, g_width);
437          out_uint16_le(s, height);          out_uint16_le(s, g_height);
438          out_uint16_le(s, 0xca01);          out_uint16_le(s, 0xca01);
439          out_uint16_le(s, 0xaa03);          out_uint16_le(s, 0xaa03);
440          out_uint32_le(s, keylayout);          out_uint32_le(s, keylayout);
441          out_uint32_le(s, 419);  /* client build? we are 419 compatible :-) */          out_uint32_le(s, 2600); /* Client build. We are now 2600 compatible :-) */
442    
443          /* Unicode name of client, padded to 32 bytes */          /* Unicode name of client, padded to 32 bytes */
444          rdp_out_unistr(s, hostname, hostlen);          rdp_out_unistr(s, hostname, hostlen);
# Line 425  sec_out_mcs_data(STREAM s) Line 449  sec_out_mcs_data(STREAM s)
449          out_uint32_le(s, 12);          out_uint32_le(s, 12);
450          out_uint8s(s, 64);      /* reserved? 4 + 12 doublewords */          out_uint8s(s, 64);      /* reserved? 4 + 12 doublewords */
451    
452          out_uint16_le(s, 0xca01);          switch (g_server_bpp)
453          out_uint16(s, 0);          {
454                    case 8:
455                            out_uint16_le(s, 0xca01);
456                            break;
457                    case 15:
458                            out_uint16_le(s, 0xca02);
459                            break;
460                    case 16:
461                            out_uint16_le(s, 0xca03);
462                            break;
463                    case 24:
464                            out_uint16_le(s, 0xca04);
465                            break;
466            }
467            out_uint16_le(s, 1);
468    
469            out_uint32(s, 0);
470            out_uint8(s, g_server_bpp);
471            out_uint16_le(s, 0x0700);
472            out_uint8(s, 0);
473            out_uint32_le(s, 1);
474            out_uint8s(s, 64);      /* End of client info */
475    
476            out_uint16_le(s, SEC_TAG_CLI_4);
477            out_uint16_le(s, 12);
478            out_uint32_le(s, g_console_session ? 0xb : 9);
479            out_uint32(s, 0);
480    
481          /* Client encryption settings */          /* Client encryption settings */
482          out_uint16_le(s, SEC_TAG_CLI_CRYPT);          out_uint16_le(s, SEC_TAG_CLI_CRYPT);
483          out_uint16_le(s, 8);    /* length */          out_uint16_le(s, 12);   /* length */
484          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 */
485            out_uint32(s, 0);       /* Unknown */
486    
487            DEBUG_RDP5(("g_num_channels is %d\n", g_num_channels));
488            if (g_num_channels > 0)
489            {
490                    out_uint16_le(s, SEC_TAG_CLI_CHANNELS);
491                    out_uint16_le(s, g_num_channels * 12 + 8);      /* length */
492                    out_uint32_le(s, g_num_channels);       /* number of virtual channels */
493                    for (i = 0; i < g_num_channels; i++)
494                    {
495                            DEBUG_RDP5(("Requesting channel %s\n", g_channels[i].name));
496                            out_uint8a(s, g_channels[i].name, 8);
497                            out_uint32_be(s, g_channels[i].flags);
498                    }
499            }
500    
501          s_mark_end(s);          s_mark_end(s);
502  }  }
503    
# Line 463  sec_parse_public_key(STREAM s, uint8 ** Line 529  sec_parse_public_key(STREAM s, uint8 **
529          return s_check(s);          return s_check(s);
530  }  }
531    
532    static BOOL
533    sec_parse_x509_key(X509 * cert)
534    {
535            EVP_PKEY *epk = NULL;
536            /* By some reason, Microsoft sets the OID of the Public RSA key to
537               the oid for "MD5 with RSA Encryption" instead of "RSA Encryption"
538    
539               Kudos to Richard Levitte for the following (. intiutive .)
540               lines of code that resets the OID and let's us extract the key. */
541            if (OBJ_obj2nid(cert->cert_info->key->algor->algorithm) == NID_md5WithRSAEncryption)
542            {
543                    DEBUG_RDP5(("Re-setting algorithm type to RSA in server certificate\n"));
544                    cert->cert_info->key->algor->algorithm = OBJ_nid2obj(NID_rsaEncryption);
545            }
546            epk = X509_get_pubkey(cert);
547            if (NULL == epk)
548            {
549                    error("Failed to extract public key from certificate\n");
550                    return False;
551            }
552    
553            server_public_key = (RSA *) epk->pkey.ptr;
554    
555            return True;
556    }
557    
558    
559  /* Parse a crypto information structure */  /* Parse a crypto information structure */
560  static BOOL  static BOOL
561  sec_parse_crypt_info(STREAM s, uint32 * rc4_key_size,  sec_parse_crypt_info(STREAM s, uint32 * rc4_key_size,
562                       uint8 ** server_random, uint8 ** modulus, uint8 ** exponent)                       uint8 ** server_random, uint8 ** modulus, uint8 ** exponent)
563  {  {
564          uint32 crypt_level, random_len, rsa_info_len;          uint32 crypt_level, random_len, rsa_info_len;
565            uint32 cacert_len, cert_len, flags;
566            X509 *cacert, *server_cert;
567          uint16 tag, length;          uint16 tag, length;
568          uint8 *next_tag, *end;          uint8 *next_tag, *end;
569    
570          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 */
571          in_uint32_le(s, crypt_level);   /* 1 = low, 2 = medium, 3 = high */          in_uint32_le(s, crypt_level);   /* 1 = low, 2 = medium, 3 = high */
572          if (crypt_level == 0)   /* no encryptation */          if (crypt_level == 0)   /* no encryption */
573                  return False;                  return False;
574          in_uint32_le(s, random_len);          in_uint32_le(s, random_len);
575          in_uint32_le(s, rsa_info_len);          in_uint32_le(s, rsa_info_len);
576    
577          if (random_len != SEC_RANDOM_SIZE)          if (random_len != SEC_RANDOM_SIZE)
578          {          {
579                  error("random len %d\n", random_len);                  error("random len %d, expected %d\n", random_len, SEC_RANDOM_SIZE);
580                  return False;                  return False;
581          }          }
582    
# Line 492  sec_parse_crypt_info(STREAM s, uint32 * Line 587  sec_parse_crypt_info(STREAM s, uint32 *
587          if (end > s->end)          if (end > s->end)
588                  return False;                  return False;
589    
590          in_uint8s(s, 12);       /* unknown */          in_uint32_le(s, flags); /* 1 = RDP4-style, 0x80000002 = X.509 */
591            if (flags & 1)
592            {
593                    DEBUG_RDP5(("We're going for the RDP4-style encryption\n"));
594                    in_uint8s(s, 8);        /* unknown */
595    
596                    while (s->p < end)
597                    {
598                            in_uint16_le(s, tag);
599                            in_uint16_le(s, length);
600    
601                            next_tag = s->p + length;
602    
603                            switch (tag)
604                            {
605                                    case SEC_TAG_PUBKEY:
606                                            if (!sec_parse_public_key(s, modulus, exponent))
607                                                    return False;
608                                            DEBUG_RDP5(("Got Public key, RDP4-style\n"));
609    
610                                            break;
611    
612                                    case SEC_TAG_KEYSIG:
613                                            /* Is this a Microsoft key that we just got? */
614                                            /* Care factor: zero! */
615                                            /* Actually, it would probably be a good idea to check if the public key is signed with this key, and then store this
616                                               key as a known key of the hostname. This would prevent some MITM-attacks. */
617                                            break;
618    
619                                    default:
620                                            unimpl("crypt tag 0x%x\n", tag);
621                            }
622    
623          while (s->p < end)                          s->p = next_tag;
624                    }
625            }
626            else
627          {          {
628                  in_uint16_le(s, tag);                  DEBUG_RDP5(("We're going for the RDP5-style encryption\n"));
629                  in_uint16_le(s, length);                  in_uint8s(s, 4);        /* Number of certificates */
630    
631                  next_tag = s->p + length;                  /* Do da funky X.509 stuffy
632    
633                  switch (tag)                     "How did I find out about this?  I looked up and saw a
634                       bright light and when I came to I had a scar on my forehead
635                       and knew about X.500"
636                       - Peter Gutman in a early version of
637                       http://www.cs.auckland.ac.nz/~pgut001/pubs/x509guide.txt
638                     */
639    
640                    in_uint32_le(s, cacert_len);
641                    DEBUG_RDP5(("CA Certificate length is %d\n", cacert_len));
642                    cacert = d2i_X509(NULL, &(s->p), cacert_len);
643                    /* Note: We don't need to move s->p here - d2i_X509 is
644                       "kind" enough to do it for us */
645                    if (NULL == cacert)
646                  {                  {
647                          case SEC_TAG_PUBKEY:                          error("Couldn't load CA Certificate from server\n");
648                                  if (!sec_parse_public_key(s, modulus, exponent))                          return False;
649                                          return False;                  }
650    
651                                  break;                  /* Currently, we don't use the CA Certificate.
652                       FIXME:
653                       *) Verify the server certificate (server_cert) with the
654                       CA certificate.
655                       *) Store the CA Certificate with the hostname of the
656                       server we are connecting to as key, and compare it
657                       when we connect the next time, in order to prevent
658                       MITM-attacks.
659                     */
660    
661                    in_uint32_le(s, cert_len);
662                    DEBUG_RDP5(("Certificate length is %d\n", cert_len));
663                    server_cert = d2i_X509(NULL, &(s->p), cert_len);
664                    if (NULL == server_cert)
665                    {
666                            error("Couldn't load Certificate from server\n");
667                            return False;
668                    }
669    
670                          case SEC_TAG_KEYSIG:                  in_uint8s(s, 16);       /* Padding */
                                 /* Is this a Microsoft key that we just got? */  
                                 /* Care factor: zero! */  
                                 break;  
671    
672                          default:                  /* Note: Verifying the server certificate must be done here,
673                                  unimpl("crypt tag 0x%x\n", tag);                     before sec_parse_public_key since we'll have to apply
674                  }                     serious violence to the key after this */
675    
676                  s->p = next_tag;                  if (!sec_parse_x509_key(server_cert))
677                    {
678                            DEBUG_RDP5(("Didn't parse X509 correctly\n"));
679                            return False;
680                    }
681                    return True;    /* There's some garbage here we don't care about */
682          }          }
   
683          return s_check_end(s);          return s_check_end(s);
684  }  }
685    
# Line 531  sec_process_crypt_info(STREAM s) Line 690  sec_process_crypt_info(STREAM s)
690          uint8 *server_random, *modulus, *exponent;          uint8 *server_random, *modulus, *exponent;
691          uint8 client_random[SEC_RANDOM_SIZE];          uint8 client_random[SEC_RANDOM_SIZE];
692          uint32 rc4_key_size;          uint32 rc4_key_size;
693            uint8 inr[SEC_MODULUS_SIZE];
694    
695          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))
696            {
697                    DEBUG(("Failed to parse crypt info\n"));
698                  return;                  return;
699            }
700    
701            DEBUG(("Generating client random\n"));
702          /* Generate a client random, and hence determine encryption keys */          /* Generate a client random, and hence determine encryption keys */
703            /* This is what the MS client do: */
704            memset(inr, 0, SEC_RANDOM_SIZE);
705            /*  *ARIGL!* Plaintext attack, anyone?
706               I tried doing:
707               generate_random(inr);
708               ..but that generates connection errors now and then (yes,
709               "now and then". Something like 0 to 3 attempts needed before a
710               successful connection. Nice. Not!
711             */
712    
713          generate_random(client_random);          generate_random(client_random);
714          sec_rsa_encrypt(sec_crypted_random, client_random, SEC_RANDOM_SIZE, modulus, exponent);          if (NULL != server_public_key)
715            {                       /* Which means we should use
716                                       RDP5-style encryption */
717    
718                    memcpy(inr + SEC_RANDOM_SIZE, client_random, SEC_RANDOM_SIZE);
719                    reverse(inr + SEC_RANDOM_SIZE, SEC_RANDOM_SIZE);
720    
721                    RSA_public_encrypt(SEC_MODULUS_SIZE,
722                                       inr, sec_crypted_random, server_public_key, RSA_NO_PADDING);
723    
724                    reverse(sec_crypted_random, SEC_MODULUS_SIZE);
725    
726            }
727            else
728            {                       /* RDP4-style encryption */
729                    sec_rsa_encrypt(sec_crypted_random,
730                                    client_random, SEC_RANDOM_SIZE, modulus, exponent);
731            }
732          sec_generate_keys(client_random, server_random, rc4_key_size);          sec_generate_keys(client_random, server_random, rc4_key_size);
733  }  }
734    
735  /* Process connect response data blob */  
736    /* Process SRV_INFO, find RDP version supported by server */
737  static void  static void
738    sec_process_srv_info(STREAM s)
739    {
740            in_uint16_le(s, g_server_rdp_version);
741            DEBUG_RDP5(("Server RDP version is %d\n", g_server_rdp_version));
742            if (1 == g_server_rdp_version)
743                    g_use_rdp5 = 0;
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                          case SEC_TAG_SRV_3:                                  sec_process_srv_info(s);
774                                  break;                                  break;
775    
776                          case SEC_TAG_SRV_CRYPT:                          case SEC_TAG_SRV_CRYPT:
777                                  sec_process_crypt_info(s);                                  sec_process_crypt_info(s);
778                                  break;                                  break;
779    
780                            case SEC_TAG_SRV_CHANNELS:
781                                    /* FIXME: We should parse this information and
782                                       use it to map RDP5 channels to MCS
783                                       channels */
784                                    break;
785    
786                          default:                          default:
787                                  unimpl("response tag 0x%x\n", tag);                                  unimpl("response tag 0x%x\n", tag);
788                  }                  }
# 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 (g_encryption || !g_licence_issued)
805                  {                  {
806                          in_uint32_le(s, sec_flags);                          in_uint32_le(s, sec_flags);
807    
808                            if (sec_flags & SEC_ENCRYPT)
809                            {
810                                    in_uint8s(s, 8);        /* signature */
811                                    sec_decrypt(s->p, s->end - s->p);
812                            }
813    
814                          if (sec_flags & SEC_LICENCE_NEG)                          if (sec_flags & SEC_LICENCE_NEG)
815                          {                          {
816                                  licence_process(s);                                  licence_process(s);
817                                  continue;                                  continue;
818                          }                          }
819                    }
820    
821                          if (sec_flags & SEC_ENCRYPT)                  if (channel != MCS_GLOBAL_CHANNEL)
822                          {                  {
823                                  in_uint8s(s, 8);        /* signature */                          channel_process(s, channel);
824                                  sec_decrypt(s->p, s->end - s->p);                          continue;
                         }  
825                  }                  }
826    
827                  return s;                  return s;
# Line 616  sec_recv(void) Line 832  sec_recv(void)
832    
833  /* Establish a secure connection */  /* Establish a secure connection */
834  BOOL  BOOL
835  sec_connect(char *server)  sec_connect(char *server, char *username)
836  {  {
837          struct stream mcs_data;          struct stream mcs_data;
838    
839          /* We exchange some RDP data during the MCS-Connect */          /* We exchange some RDP data during the MCS-Connect */
840          mcs_data.size = 512;          mcs_data.size = 512;
841          mcs_data.p = mcs_data.data = xmalloc(mcs_data.size);          mcs_data.p = mcs_data.data = (uint8 *) xmalloc(mcs_data.size);
842          sec_out_mcs_data(&mcs_data);          sec_out_mcs_data(&mcs_data);
843    
844          if (!mcs_connect(server, &mcs_data))          if (!mcs_connect(server, &mcs_data, username))
845                  return False;                  return False;
846    
847          sec_process_mcs_data(&mcs_data);          /*      sec_process_mcs_data(&mcs_data); */
848          if (encryption)          if (g_encryption)
849                  sec_establish_key();                  sec_establish_key();
850            xfree(mcs_data.data);
851          return True;          return True;
852  }  }
853    

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

  ViewVC Help
Powered by ViewVC 1.1.26