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

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

revision 10 by matty, Tue Aug 15 10:23:24 2000 UTC revision 325 by astrand, Tue Feb 11 11:31:04 2003 UTC
# Line 1  Line 1 
1  /*  /*
2     rdesktop: A Remote Desktop Protocol client.     rdesktop: A Remote Desktop Protocol client.
3     RDP licensing negotiation     RDP licensing negotiation
4     Copyright (C) Matthew Chapman 1999-2000     Copyright (C) Matthew Chapman 1999-2002
5        
6     This program is free software; you can redistribute it and/or modify     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.     (at your option) any later version.
10      
11     This program is distributed in the hope that it will be useful,     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# Line 19  Line 19 
19  */  */
20    
21  #include "rdesktop.h"  #include "rdesktop.h"
22    
23    #ifdef WITH_OPENSSL
24    #include <openssl/rc4.h>
25    #else
26  #include "crypto/rc4.h"  #include "crypto/rc4.h"
27    #endif
28    
29  extern char username[16];  extern char username[16];
30  extern char hostname[16];  extern char hostname[16];
 extern BOOL licence;  
31    
32  static uint8 licence_key[16];  static uint8 licence_key[16];
33  static uint8 licence_sign_key[16];  static uint8 licence_sign_key[16];
34    
35    BOOL licence_issued = False;
36    
37  /* Generate a session key and RC4 keys, given client and server randoms */  /* Generate a session key and RC4 keys, given client and server randoms */
38  void licence_generate_keys(uint8 *client_key, uint8 *server_key,  static void
39                             uint8 *client_rsa)  licence_generate_keys(uint8 * client_key, uint8 * server_key, uint8 * client_rsa)
40  {  {
41          uint8 session_key[48];          uint8 session_key[48];
42          uint8 temp_hash[48];          uint8 temp_hash[48];
43    
44          /* Generate session key - two rounds of sec_hash_48 */          /* Generate session key - two rounds of sec_hash_48 */
45          sec_hash_48(temp_hash,   client_rsa, client_key, server_key, 65);          sec_hash_48(temp_hash, client_rsa, client_key, server_key, 65);
46          sec_hash_48(session_key, temp_hash,  server_key, client_key, 65);          sec_hash_48(session_key, temp_hash, server_key, client_key, 65);
47    
48          /* Store first 16 bytes of session key, for generating signatures */          /* Store first 16 bytes of session key, for generating signatures */
49          memcpy(licence_sign_key, session_key, 16);          memcpy(licence_sign_key, session_key, 16);
50    
51          /* Generate RC4 key */          /* Generate RC4 key */
52          sec_hash_16(licence_key, &session_key[16], client_key, server_key);          sec_hash_16(licence_key, &session_key[16], client_key, server_key);
53  }  }
54    
55    static void
56    licence_generate_hwid(uint8 * hwid)
57    {
58            buf_out_uint32(hwid, 2);
59            strncpy((char *) (hwid + 4), hostname, LICENCE_HWID_SIZE - 4);
60    }
61    
62    /* Present an existing licence to the server */
63    static void
64    licence_present(uint8 * client_random, uint8 * rsa_data,
65                    uint8 * licence_data, int licence_size, uint8 * hwid, uint8 * signature)
66    {
67            uint32 sec_flags = SEC_LICENCE_NEG;
68            uint16 length =
69                    16 + SEC_RANDOM_SIZE + SEC_MODULUS_SIZE + SEC_PADDING_SIZE +
70                    licence_size + LICENCE_HWID_SIZE + LICENCE_SIGNATURE_SIZE;
71            STREAM s;
72    
73            s = sec_init(sec_flags, length + 4);
74    
75            out_uint16_le(s, LICENCE_TAG_PRESENT);
76            out_uint16_le(s, length);
77    
78            out_uint32_le(s, 1);
79            out_uint16(s, 0);
80            out_uint16_le(s, 0x0201);
81    
82            out_uint8p(s, client_random, SEC_RANDOM_SIZE);
83            out_uint16(s, 0);
84            out_uint16_le(s, (SEC_MODULUS_SIZE + SEC_PADDING_SIZE));
85            out_uint8p(s, rsa_data, SEC_MODULUS_SIZE);
86            out_uint8s(s, SEC_PADDING_SIZE);
87    
88            out_uint16_le(s, 1);
89            out_uint16_le(s, licence_size);
90            out_uint8p(s, licence_data, licence_size);
91    
92            out_uint16_le(s, 1);
93            out_uint16_le(s, LICENCE_HWID_SIZE);
94            out_uint8p(s, hwid, LICENCE_HWID_SIZE);
95    
96            out_uint8p(s, signature, LICENCE_SIGNATURE_SIZE);
97    
98            s_mark_end(s);
99            sec_send(s, sec_flags);
100    }
101    
102  /* Send a licence request packet */  /* Send a licence request packet */
103  static void licence_send_request(uint8 *client_random, uint8 *rsa_data,  static void
104                                          char *user, char *host)  licence_send_request(uint8 * client_random, uint8 * rsa_data, char *user, char *host)
105  {  {
106          uint32 sec_flags = SEC_LICENCE_NEG;          uint32 sec_flags = SEC_LICENCE_NEG;
107          uint16 userlen = strlen(user) + 1;          uint16 userlen = strlen(user) + 1;
108          uint16 hostlen = strlen(host) + 1;          uint16 hostlen = strlen(host) + 1;
109          uint16 length = 120 + userlen + hostlen;          uint16 length = 128 + userlen + hostlen;
110          STREAM s;          STREAM s;
111    
112          s = sec_init(sec_flags, length + 2);          s = sec_init(sec_flags, length + 2);
# Line 62  static void licence_send_request(uint8 * Line 115  static void licence_send_request(uint8 *
115          out_uint16_le(s, length);          out_uint16_le(s, length);
116    
117          out_uint32_le(s, 1);          out_uint32_le(s, 1);
118          out_uint32_le(s, 0xff010000);          out_uint16(s, 0);
119            out_uint16_le(s, 0xff01);
120    
121          out_uint8p(s, client_random, SEC_RANDOM_SIZE);          out_uint8p(s, client_random, SEC_RANDOM_SIZE);
122          out_uint16(s, 0);          out_uint16(s, 0);
# Line 83  static void licence_send_request(uint8 * Line 137  static void licence_send_request(uint8 *
137  }  }
138    
139  /* Process a licence demand packet */  /* Process a licence demand packet */
140  static void licence_process_demand(STREAM s)  static void
141    licence_process_demand(STREAM s)
142  {  {
143          uint8 null_data[SEC_MODULUS_SIZE];          uint8 null_data[SEC_MODULUS_SIZE];
144          uint8 *server_random;          uint8 *server_random;
145            uint8 signature[LICENCE_SIGNATURE_SIZE];
146            uint8 hwid[LICENCE_HWID_SIZE];
147            uint8 *licence_data;
148            int licence_size;
149            RC4_KEY crypt_key;
150    
151          /* Retrieve the server random from the incoming packet */          /* Retrieve the server random from the incoming packet */
152          in_uint8p(s, server_random, SEC_RANDOM_SIZE);          in_uint8p(s, server_random, SEC_RANDOM_SIZE);
# Line 96  static void licence_process_demand(STREA Line 156  static void licence_process_demand(STREA
156          memset(null_data, 0, sizeof(null_data));          memset(null_data, 0, sizeof(null_data));
157          licence_generate_keys(null_data, server_random, null_data);          licence_generate_keys(null_data, server_random, null_data);
158    
159          /* Send a certificate request back to the server */          licence_size = load_licence(&licence_data);
160            if (licence_size != -1)
161            {
162                    /* Generate a signature for the HWID buffer */
163                    licence_generate_hwid(hwid);
164                    sec_sign(signature, 16, licence_sign_key, 16, hwid, sizeof(hwid));
165    
166                    /* Now encrypt the HWID */
167                    RC4_set_key(&crypt_key, 16, licence_key);
168                    RC4(&crypt_key, sizeof(hwid), hwid, hwid);
169    
170                    licence_present(null_data, null_data, licence_data, licence_size, hwid, signature);
171                    xfree(licence_data);
172                    return;
173            }
174    
175          licence_send_request(null_data, null_data, username, hostname);          licence_send_request(null_data, null_data, username, hostname);
176  }  }
177    
178  /* Send an authentication response packet */  /* Send an authentication response packet */
179  static void licence_send_authresp(uint8 *token, uint8 *crypt_hwid,  static void
180                                          uint8 *signature)  licence_send_authresp(uint8 * token, uint8 * crypt_hwid, uint8 * signature)
181  {  {
182          uint32 sec_flags = SEC_LICENCE_NEG;          uint32 sec_flags = SEC_LICENCE_NEG;
183          uint16 length = 58;          uint16 length = 58;
# Line 128  static void licence_send_authresp(uint8 Line 203  static void licence_send_authresp(uint8
203  }  }
204    
205  /* Parse an authentication request packet */  /* Parse an authentication request packet */
206  static BOOL licence_parse_authreq(STREAM s, uint8 **token, uint8 **signature)  static BOOL
207    licence_parse_authreq(STREAM s, uint8 ** token, uint8 ** signature)
208  {  {
209          uint16 tokenlen;          uint16 tokenlen;
210    
211          in_uint8s(s, 6); /* unknown: f8 3d 15 00 04 f6 */          in_uint8s(s, 6);        /* unknown: f8 3d 15 00 04 f6 */
212    
213          in_uint16_le(s, tokenlen);          in_uint16_le(s, tokenlen);
214          if (tokenlen != LICENCE_TOKEN_SIZE)          if (tokenlen != LICENCE_TOKEN_SIZE)
215          {          {
216                  ERROR("token len %d\n", tokenlen);                  error("token len %d\n", tokenlen);
217                  return False;                  return False;
218          }          }
219    
# Line 148  static BOOL licence_parse_authreq(STREAM Line 224  static BOOL licence_parse_authreq(STREAM
224  }  }
225    
226  /* Process an authentication request packet */  /* Process an authentication request packet */
227  static void licence_process_authreq(STREAM s)  static void
228    licence_process_authreq(STREAM s)
229  {  {
230          uint8 *in_token, *in_sig;          uint8 *in_token, *in_sig;
231          uint8 out_token[LICENCE_TOKEN_SIZE], decrypt_token[LICENCE_TOKEN_SIZE];          uint8 out_token[LICENCE_TOKEN_SIZE], decrypt_token[LICENCE_TOKEN_SIZE];
# Line 165  static void licence_process_authreq(STRE Line 242  static void licence_process_authreq(STRE
242          RC4_set_key(&crypt_key, 16, licence_key);          RC4_set_key(&crypt_key, 16, licence_key);
243          RC4(&crypt_key, LICENCE_TOKEN_SIZE, in_token, decrypt_token);          RC4(&crypt_key, LICENCE_TOKEN_SIZE, in_token, decrypt_token);
244    
         /* Construct HWID */  
         buf_out_uint32(hwid, 2);  
         strncpy(hwid + 4, hostname, LICENCE_HWID_SIZE - 4);  
   
245          /* Generate a signature for a buffer of token and HWID */          /* Generate a signature for a buffer of token and HWID */
246            licence_generate_hwid(hwid);
247          memcpy(sealed_buffer, decrypt_token, LICENCE_TOKEN_SIZE);          memcpy(sealed_buffer, decrypt_token, LICENCE_TOKEN_SIZE);
248          memcpy(sealed_buffer + LICENCE_TOKEN_SIZE, hwid, LICENCE_HWID_SIZE);          memcpy(sealed_buffer + LICENCE_TOKEN_SIZE, hwid, LICENCE_HWID_SIZE);
249          sec_sign(out_sig, licence_sign_key, 16,          sec_sign(out_sig, 16, licence_sign_key, 16, sealed_buffer, sizeof(sealed_buffer));
                         sealed_buffer, sizeof(sealed_buffer));  
   
         /* Deliberately break signature if licencing disabled */  
         if (!licence)  
                 memset(out_sig, 0, sizeof(out_sig));  
250    
251          /* Now encrypt the HWID */          /* Now encrypt the HWID */
252          RC4_set_key(&crypt_key, 16, licence_key);          RC4_set_key(&crypt_key, 16, licence_key);
# Line 187  static void licence_process_authreq(STRE Line 256  static void licence_process_authreq(STRE
256  }  }
257    
258  /* Process an licence issue packet */  /* Process an licence issue packet */
259  static void licence_process_issue(STREAM s)  static void
260    licence_process_issue(STREAM s)
261  {  {
262          RC4_KEY crypt_key;          RC4_KEY crypt_key;
263          uint32 length;          uint32 length;
264          uint16 check;          uint16 check;
265    
266          in_uint8s(s, 2); /* 3d 45 - unknown */          in_uint8s(s, 2);        /* 3d 45 - unknown */
267          in_uint16_le(s, length);          in_uint16_le(s, length);
268          if (!s_check_rem(s, length))          if (!s_check_rem(s, length))
269                  return;                  return;
# Line 205  static void licence_process_issue(STREAM Line 275  static void licence_process_issue(STREAM
275          if (check != 0)          if (check != 0)
276                  return;                  return;
277    
278          /* We should save the licence here */          licence_issued = True;
279          STATUS("Server issued licence.\n");          save_licence(s->p, length - 2);
280  }  }
281    
282  /* Process a licence packet */  /* Process a licence packet */
283  void licence_process(STREAM s)  void
284    licence_process(STREAM s)
285  {  {
286          uint16 tag;          uint16 tag;
287    
288          in_uint16_le(s, tag);          in_uint16_le(s, tag);
289          in_uint8s(s, 2); /* length */          in_uint8s(s, 2);        /* length */
290    
291          switch (tag)          switch (tag)
292          {          {
# Line 231  void licence_process(STREAM s) Line 302  void licence_process(STREAM s)
302                          licence_process_issue(s);                          licence_process_issue(s);
303                          break;                          break;
304    
305                    case LICENCE_TAG_REISSUE:
306                            break;
307    
308                  case LICENCE_TAG_RESULT:                  case LICENCE_TAG_RESULT:
309                          break;                          break;
310    
311                  default:                  default:
312                          NOTIMP("licence tag 0x%x\n", tag);                          unimpl("licence tag 0x%x\n", tag);
313          }          }
314  }  }

Legend:
Removed from v.10  
changed lines
  Added in v.325

  ViewVC Help
Powered by ViewVC 1.1.26