/[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 214 by matthewc, Sun Oct 6 13:57:39 2002 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 23  Line 23 
23    
24  extern char username[16];  extern char username[16];
25  extern char hostname[16];  extern char hostname[16];
 extern BOOL licence;  
26    
27  static uint8 licence_key[16];  static uint8 licence_key[16];
28  static uint8 licence_sign_key[16];  static uint8 licence_sign_key[16];
29    
30    BOOL licence_issued = False;
31    
32  /* Generate a session key and RC4 keys, given client and server randoms */  /* Generate a session key and RC4 keys, given client and server randoms */
33  void licence_generate_keys(uint8 *client_key, uint8 *server_key,  static void
34                             uint8 *client_rsa)  licence_generate_keys(uint8 * client_key, uint8 * server_key, uint8 * client_rsa)
35  {  {
36          uint8 session_key[48];          uint8 session_key[48];
37          uint8 temp_hash[48];          uint8 temp_hash[48];
38    
39          /* Generate session key - two rounds of sec_hash_48 */          /* Generate session key - two rounds of sec_hash_48 */
40          sec_hash_48(temp_hash,   client_rsa, client_key, server_key, 65);          sec_hash_48(temp_hash, client_rsa, client_key, server_key, 65);
41          sec_hash_48(session_key, temp_hash,  server_key, client_key, 65);          sec_hash_48(session_key, temp_hash, server_key, client_key, 65);
42    
43          /* Store first 16 bytes of session key, for generating signatures */          /* Store first 16 bytes of session key, for generating signatures */
44          memcpy(licence_sign_key, session_key, 16);          memcpy(licence_sign_key, session_key, 16);
45    
46          /* Generate RC4 key */          /* Generate RC4 key */
47          sec_hash_16(licence_key, &session_key[16], client_key, server_key);          sec_hash_16(licence_key, &session_key[16], client_key, server_key);
48  }  }
49    
50    static void
51    licence_generate_hwid(uint8 * hwid)
52    {
53            buf_out_uint32(hwid, 2);
54            strncpy((char *) (hwid + 4), hostname, LICENCE_HWID_SIZE - 4);
55    }
56    
57    #ifdef SAVE_LICENCE
58    /* Present an existing licence to the server */
59    static void
60    licence_present(uint8 * client_random, uint8 * rsa_data,
61                    uint8 * licence_data, int licence_size, uint8 * hwid, uint8 * signature)
62    {
63            uint32 sec_flags = SEC_LICENCE_NEG;
64            uint16 length =
65                    16 + SEC_RANDOM_SIZE + SEC_MODULUS_SIZE + SEC_PADDING_SIZE +
66                    licence_size + LICENCE_HWID_SIZE + LICENCE_SIGNATURE_SIZE;
67            STREAM s;
68    
69            s = sec_init(sec_flags, length + 4);
70    
71            out_uint16_le(s, LICENCE_TAG_PRESENT);
72            out_uint16_le(s, length);
73    
74            out_uint32_le(s, 1);
75            out_uint16(s, 0);
76            out_uint16_le(s, 0x0201);
77    
78            out_uint8p(s, client_random, SEC_RANDOM_SIZE);
79            out_uint16(s, 0);
80            out_uint16_le(s, (SEC_MODULUS_SIZE + SEC_PADDING_SIZE));
81            out_uint8p(s, rsa_data, SEC_MODULUS_SIZE);
82            out_uint8s(s, SEC_PADDING_SIZE);
83    
84            out_uint16_le(s, 1);
85            out_uint16_le(s, licence_size);
86            out_uint8p(s, licence_data, licence_size);
87    
88            out_uint16_le(s, 1);
89            out_uint16_le(s, LICENCE_HWID_SIZE);
90            out_uint8p(s, hwid, LICENCE_HWID_SIZE);
91    
92            out_uint8p(s, signature, LICENCE_SIGNATURE_SIZE);
93    
94            s_mark_end(s);
95            sec_send(s, sec_flags);
96    }
97    #endif
98    
99  /* Send a licence request packet */  /* Send a licence request packet */
100  static void licence_send_request(uint8 *client_random, uint8 *rsa_data,  static void
101                                          char *user, char *host)  licence_send_request(uint8 * client_random, uint8 * rsa_data, char *user, char *host)
102  {  {
103          uint32 sec_flags = SEC_LICENCE_NEG;          uint32 sec_flags = SEC_LICENCE_NEG;
104          uint16 userlen = strlen(user) + 1;          uint16 userlen = strlen(user) + 1;
105          uint16 hostlen = strlen(host) + 1;          uint16 hostlen = strlen(host) + 1;
106          uint16 length = 120 + userlen + hostlen;          uint16 length = 128 + userlen + hostlen;
107          STREAM s;          STREAM s;
108    
109          s = sec_init(sec_flags, length + 2);          s = sec_init(sec_flags, length + 2);
# Line 62  static void licence_send_request(uint8 * Line 112  static void licence_send_request(uint8 *
112          out_uint16_le(s, length);          out_uint16_le(s, length);
113    
114          out_uint32_le(s, 1);          out_uint32_le(s, 1);
115          out_uint32_le(s, 0xff010000);          out_uint16(s, 0);
116            out_uint16_le(s, 0xff01);
117    
118          out_uint8p(s, client_random, SEC_RANDOM_SIZE);          out_uint8p(s, client_random, SEC_RANDOM_SIZE);
119          out_uint16(s, 0);          out_uint16(s, 0);
# Line 83  static void licence_send_request(uint8 * Line 134  static void licence_send_request(uint8 *
134  }  }
135    
136  /* Process a licence demand packet */  /* Process a licence demand packet */
137  static void licence_process_demand(STREAM s)  static void
138    licence_process_demand(STREAM s)
139  {  {
140          uint8 null_data[SEC_MODULUS_SIZE];          uint8 null_data[SEC_MODULUS_SIZE];
141          uint8 *server_random;          uint8 *server_random;
142    #ifdef SAVE_LICENCE
143            uint8 signature[LICENCE_SIGNATURE_SIZE];
144            uint8 hwid[LICENCE_HWID_SIZE];
145            uint8 *licence_data;
146            int licence_size;
147            RC4_KEY crypt_key;
148    #endif
149    
150          /* Retrieve the server random from the incoming packet */          /* Retrieve the server random from the incoming packet */
151          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 155  static void licence_process_demand(STREA
155          memset(null_data, 0, sizeof(null_data));          memset(null_data, 0, sizeof(null_data));
156          licence_generate_keys(null_data, server_random, null_data);          licence_generate_keys(null_data, server_random, null_data);
157    
158          /* Send a certificate request back to the server */  #ifdef SAVE_LICENCE
159            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    #endif
175    
176          licence_send_request(null_data, null_data, username, hostname);          licence_send_request(null_data, null_data, username, hostname);
177  }  }
178    
179  /* Send an authentication response packet */  /* Send an authentication response packet */
180  static void licence_send_authresp(uint8 *token, uint8 *crypt_hwid,  static void
181                                          uint8 *signature)  licence_send_authresp(uint8 * token, uint8 * crypt_hwid, uint8 * signature)
182  {  {
183          uint32 sec_flags = SEC_LICENCE_NEG;          uint32 sec_flags = SEC_LICENCE_NEG;
184          uint16 length = 58;          uint16 length = 58;
# Line 128  static void licence_send_authresp(uint8 Line 204  static void licence_send_authresp(uint8
204  }  }
205    
206  /* Parse an authentication request packet */  /* Parse an authentication request packet */
207  static BOOL licence_parse_authreq(STREAM s, uint8 **token, uint8 **signature)  static BOOL
208    licence_parse_authreq(STREAM s, uint8 ** token, uint8 ** signature)
209  {  {
210          uint16 tokenlen;          uint16 tokenlen;
211    
212          in_uint8s(s, 6); /* unknown: f8 3d 15 00 04 f6 */          in_uint8s(s, 6);        /* unknown: f8 3d 15 00 04 f6 */
213    
214          in_uint16_le(s, tokenlen);          in_uint16_le(s, tokenlen);
215          if (tokenlen != LICENCE_TOKEN_SIZE)          if (tokenlen != LICENCE_TOKEN_SIZE)
216          {          {
217                  ERROR("token len %d\n", tokenlen);                  error("token len %d\n", tokenlen);
218                  return False;                  return False;
219          }          }
220    
# Line 148  static BOOL licence_parse_authreq(STREAM Line 225  static BOOL licence_parse_authreq(STREAM
225  }  }
226    
227  /* Process an authentication request packet */  /* Process an authentication request packet */
228  static void licence_process_authreq(STREAM s)  static void
229    licence_process_authreq(STREAM s)
230  {  {
231          uint8 *in_token, *in_sig;          uint8 *in_token, *in_sig;
232          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 243  static void licence_process_authreq(STRE
243          RC4_set_key(&crypt_key, 16, licence_key);          RC4_set_key(&crypt_key, 16, licence_key);
244          RC4(&crypt_key, LICENCE_TOKEN_SIZE, in_token, decrypt_token);          RC4(&crypt_key, LICENCE_TOKEN_SIZE, in_token, decrypt_token);
245    
         /* Construct HWID */  
         buf_out_uint32(hwid, 2);  
         strncpy(hwid + 4, hostname, LICENCE_HWID_SIZE - 4);  
   
246          /* Generate a signature for a buffer of token and HWID */          /* Generate a signature for a buffer of token and HWID */
247            licence_generate_hwid(hwid);
248          memcpy(sealed_buffer, decrypt_token, LICENCE_TOKEN_SIZE);          memcpy(sealed_buffer, decrypt_token, LICENCE_TOKEN_SIZE);
249          memcpy(sealed_buffer + LICENCE_TOKEN_SIZE, hwid, LICENCE_HWID_SIZE);          memcpy(sealed_buffer + LICENCE_TOKEN_SIZE, hwid, LICENCE_HWID_SIZE);
250          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));  
251    
252          /* Now encrypt the HWID */          /* Now encrypt the HWID */
253          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 257  static void licence_process_authreq(STRE
257  }  }
258    
259  /* Process an licence issue packet */  /* Process an licence issue packet */
260  static void licence_process_issue(STREAM s)  static void
261    licence_process_issue(STREAM s)
262  {  {
263          RC4_KEY crypt_key;          RC4_KEY crypt_key;
264          uint32 length;          uint32 length;
265          uint16 check;          uint16 check;
266    
267          in_uint8s(s, 2); /* 3d 45 - unknown */          in_uint8s(s, 2);        /* 3d 45 - unknown */
268          in_uint16_le(s, length);          in_uint16_le(s, length);
269          if (!s_check_rem(s, length))          if (!s_check_rem(s, length))
270                  return;                  return;
# Line 205  static void licence_process_issue(STREAM Line 276  static void licence_process_issue(STREAM
276          if (check != 0)          if (check != 0)
277                  return;                  return;
278    
279          /* We should save the licence here */          licence_issued = True;
280          STATUS("Server issued licence.\n");  
281    #ifdef SAVE_LICENCE
282            save_licence(s->p, length - 2);
283    #endif
284  }  }
285    
286  /* Process a licence packet */  /* Process a licence packet */
287  void licence_process(STREAM s)  void
288    licence_process(STREAM s)
289  {  {
290          uint16 tag;          uint16 tag;
291    
292          in_uint16_le(s, tag);          in_uint16_le(s, tag);
293          in_uint8s(s, 2); /* length */          in_uint8s(s, 2);        /* length */
294    
295          switch (tag)          switch (tag)
296          {          {
# Line 231  void licence_process(STREAM s) Line 306  void licence_process(STREAM s)
306                          licence_process_issue(s);                          licence_process_issue(s);
307                          break;                          break;
308    
309                    case LICENCE_TAG_REISSUE:
310                            break;
311    
312                  case LICENCE_TAG_RESULT:                  case LICENCE_TAG_RESULT:
313                          break;                          break;
314    
315                  default:                  default:
316                          NOTIMP("licence tag 0x%x\n", tag);                          unimpl("licence tag 0x%x\n", tag);
317          }          }
318  }  }

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

  ViewVC Help
Powered by ViewVC 1.1.26