/[rdesktop]/sourceforge.net/tags/RDESKTOP-1-3-1/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/tags/RDESKTOP-1-3-1/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 293 by astrand, Tue Jan 21 20:22:44 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    #ifdef SAVE_LICENCE
63    /* Present an existing licence to the server */
64    static void
65    licence_present(uint8 * client_random, uint8 * rsa_data,
66                    uint8 * licence_data, int licence_size, uint8 * hwid, uint8 * signature)
67    {
68            uint32 sec_flags = SEC_LICENCE_NEG;
69            uint16 length =
70                    16 + SEC_RANDOM_SIZE + SEC_MODULUS_SIZE + SEC_PADDING_SIZE +
71                    licence_size + LICENCE_HWID_SIZE + LICENCE_SIGNATURE_SIZE;
72            STREAM s;
73    
74            s = sec_init(sec_flags, length + 4);
75    
76            out_uint16_le(s, LICENCE_TAG_PRESENT);
77            out_uint16_le(s, length);
78    
79            out_uint32_le(s, 1);
80            out_uint16(s, 0);
81            out_uint16_le(s, 0x0201);
82    
83            out_uint8p(s, client_random, SEC_RANDOM_SIZE);
84            out_uint16(s, 0);
85            out_uint16_le(s, (SEC_MODULUS_SIZE + SEC_PADDING_SIZE));
86            out_uint8p(s, rsa_data, SEC_MODULUS_SIZE);
87            out_uint8s(s, SEC_PADDING_SIZE);
88    
89            out_uint16_le(s, 1);
90            out_uint16_le(s, licence_size);
91            out_uint8p(s, licence_data, licence_size);
92    
93            out_uint16_le(s, 1);
94            out_uint16_le(s, LICENCE_HWID_SIZE);
95            out_uint8p(s, hwid, LICENCE_HWID_SIZE);
96    
97            out_uint8p(s, signature, LICENCE_SIGNATURE_SIZE);
98    
99            s_mark_end(s);
100            sec_send(s, sec_flags);
101    }
102    #endif
103    
104  /* Send a licence request packet */  /* Send a licence request packet */
105  static void licence_send_request(uint8 *client_random, uint8 *rsa_data,  static void
106                                          char *user, char *host)  licence_send_request(uint8 * client_random, uint8 * rsa_data, char *user, char *host)
107  {  {
108          uint32 sec_flags = SEC_LICENCE_NEG;          uint32 sec_flags = SEC_LICENCE_NEG;
109          uint16 userlen = strlen(user) + 1;          uint16 userlen = strlen(user) + 1;
110          uint16 hostlen = strlen(host) + 1;          uint16 hostlen = strlen(host) + 1;
111          uint16 length = 120 + userlen + hostlen;          uint16 length = 128 + userlen + hostlen;
112          STREAM s;          STREAM s;
113    
114          s = sec_init(sec_flags, length + 2);          s = sec_init(sec_flags, length + 2);
# Line 62  static void licence_send_request(uint8 * Line 117  static void licence_send_request(uint8 *
117          out_uint16_le(s, length);          out_uint16_le(s, length);
118    
119          out_uint32_le(s, 1);          out_uint32_le(s, 1);
120          out_uint32_le(s, 0xff010000);          out_uint16(s, 0);
121            out_uint16_le(s, 0xff01);
122    
123          out_uint8p(s, client_random, SEC_RANDOM_SIZE);          out_uint8p(s, client_random, SEC_RANDOM_SIZE);
124          out_uint16(s, 0);          out_uint16(s, 0);
# Line 83  static void licence_send_request(uint8 * Line 139  static void licence_send_request(uint8 *
139  }  }
140    
141  /* Process a licence demand packet */  /* Process a licence demand packet */
142  static void licence_process_demand(STREAM s)  static void
143    licence_process_demand(STREAM s)
144  {  {
145          uint8 null_data[SEC_MODULUS_SIZE];          uint8 null_data[SEC_MODULUS_SIZE];
146          uint8 *server_random;          uint8 *server_random;
147    #ifdef SAVE_LICENCE
148            uint8 signature[LICENCE_SIGNATURE_SIZE];
149            uint8 hwid[LICENCE_HWID_SIZE];
150            uint8 *licence_data;
151            int licence_size;
152            RC4_KEY crypt_key;
153    #endif
154    
155          /* Retrieve the server random from the incoming packet */          /* Retrieve the server random from the incoming packet */
156          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 160  static void licence_process_demand(STREA
160          memset(null_data, 0, sizeof(null_data));          memset(null_data, 0, sizeof(null_data));
161          licence_generate_keys(null_data, server_random, null_data);          licence_generate_keys(null_data, server_random, null_data);
162    
163          /* Send a certificate request back to the server */  #ifdef SAVE_LICENCE
164            licence_size = load_licence(&licence_data);
165            if (licence_size != -1)
166            {
167                    /* Generate a signature for the HWID buffer */
168                    licence_generate_hwid(hwid);
169                    sec_sign(signature, 16, licence_sign_key, 16, hwid, sizeof(hwid));
170    
171                    /* Now encrypt the HWID */
172                    RC4_set_key(&crypt_key, 16, licence_key);
173                    RC4(&crypt_key, sizeof(hwid), hwid, hwid);
174    
175                    licence_present(null_data, null_data, licence_data, licence_size, hwid, signature);
176                    xfree(licence_data);
177                    return;
178            }
179    #endif
180    
181          licence_send_request(null_data, null_data, username, hostname);          licence_send_request(null_data, null_data, username, hostname);
182  }  }
183    
184  /* Send an authentication response packet */  /* Send an authentication response packet */
185  static void licence_send_authresp(uint8 *token, uint8 *crypt_hwid,  static void
186                                          uint8 *signature)  licence_send_authresp(uint8 * token, uint8 * crypt_hwid, uint8 * signature)
187  {  {
188          uint32 sec_flags = SEC_LICENCE_NEG;          uint32 sec_flags = SEC_LICENCE_NEG;
189          uint16 length = 58;          uint16 length = 58;
# Line 128  static void licence_send_authresp(uint8 Line 209  static void licence_send_authresp(uint8
209  }  }
210    
211  /* Parse an authentication request packet */  /* Parse an authentication request packet */
212  static BOOL licence_parse_authreq(STREAM s, uint8 **token, uint8 **signature)  static BOOL
213    licence_parse_authreq(STREAM s, uint8 ** token, uint8 ** signature)
214  {  {
215          uint16 tokenlen;          uint16 tokenlen;
216    
217          in_uint8s(s, 6); /* unknown: f8 3d 15 00 04 f6 */          in_uint8s(s, 6);        /* unknown: f8 3d 15 00 04 f6 */
218    
219          in_uint16_le(s, tokenlen);          in_uint16_le(s, tokenlen);
220          if (tokenlen != LICENCE_TOKEN_SIZE)          if (tokenlen != LICENCE_TOKEN_SIZE)
221          {          {
222                  ERROR("token len %d\n", tokenlen);                  error("token len %d\n", tokenlen);
223                  return False;                  return False;
224          }          }
225    
# Line 148  static BOOL licence_parse_authreq(STREAM Line 230  static BOOL licence_parse_authreq(STREAM
230  }  }
231    
232  /* Process an authentication request packet */  /* Process an authentication request packet */
233  static void licence_process_authreq(STREAM s)  static void
234    licence_process_authreq(STREAM s)
235  {  {
236          uint8 *in_token, *in_sig;          uint8 *in_token, *in_sig;
237          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 248  static void licence_process_authreq(STRE
248          RC4_set_key(&crypt_key, 16, licence_key);          RC4_set_key(&crypt_key, 16, licence_key);
249          RC4(&crypt_key, LICENCE_TOKEN_SIZE, in_token, decrypt_token);          RC4(&crypt_key, LICENCE_TOKEN_SIZE, in_token, decrypt_token);
250    
         /* Construct HWID */  
         buf_out_uint32(hwid, 2);  
         strncpy(hwid + 4, hostname, LICENCE_HWID_SIZE - 4);  
   
251          /* Generate a signature for a buffer of token and HWID */          /* Generate a signature for a buffer of token and HWID */
252            licence_generate_hwid(hwid);
253          memcpy(sealed_buffer, decrypt_token, LICENCE_TOKEN_SIZE);          memcpy(sealed_buffer, decrypt_token, LICENCE_TOKEN_SIZE);
254          memcpy(sealed_buffer + LICENCE_TOKEN_SIZE, hwid, LICENCE_HWID_SIZE);          memcpy(sealed_buffer + LICENCE_TOKEN_SIZE, hwid, LICENCE_HWID_SIZE);
255          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));  
256    
257          /* Now encrypt the HWID */          /* Now encrypt the HWID */
258          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 262  static void licence_process_authreq(STRE
262  }  }
263    
264  /* Process an licence issue packet */  /* Process an licence issue packet */
265  static void licence_process_issue(STREAM s)  static void
266    licence_process_issue(STREAM s)
267  {  {
268          RC4_KEY crypt_key;          RC4_KEY crypt_key;
269          uint32 length;          uint32 length;
270          uint16 check;          uint16 check;
271    
272          in_uint8s(s, 2); /* 3d 45 - unknown */          in_uint8s(s, 2);        /* 3d 45 - unknown */
273          in_uint16_le(s, length);          in_uint16_le(s, length);
274          if (!s_check_rem(s, length))          if (!s_check_rem(s, length))
275                  return;                  return;
# Line 205  static void licence_process_issue(STREAM Line 281  static void licence_process_issue(STREAM
281          if (check != 0)          if (check != 0)
282                  return;                  return;
283    
284          /* We should save the licence here */          licence_issued = True;
285          STATUS("Server issued licence.\n");  
286    #ifdef SAVE_LICENCE
287            save_licence(s->p, length - 2);
288    #endif
289  }  }
290    
291  /* Process a licence packet */  /* Process a licence packet */
292  void licence_process(STREAM s)  void
293    licence_process(STREAM s)
294  {  {
295          uint16 tag;          uint16 tag;
296    
297          in_uint16_le(s, tag);          in_uint16_le(s, tag);
298          in_uint8s(s, 2); /* length */          in_uint8s(s, 2);        /* length */
299    
300          switch (tag)          switch (tag)
301          {          {
# Line 231  void licence_process(STREAM s) Line 311  void licence_process(STREAM s)
311                          licence_process_issue(s);                          licence_process_issue(s);
312                          break;                          break;
313    
314                    case LICENCE_TAG_REISSUE:
315                            break;
316    
317                  case LICENCE_TAG_RESULT:                  case LICENCE_TAG_RESULT:
318                          break;                          break;
319    
320                  default:                  default:
321                          NOTIMP("licence tag 0x%x\n", tag);                          unimpl("licence tag 0x%x\n", tag);
322          }          }
323  }  }

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

  ViewVC Help
Powered by ViewVC 1.1.26