📄 licence.java
字号:
/* Licence.java
* Component: ProperJavaRDP
*
* Revision: $Revision: 1.7 $
* Author: $Author: telliott $
* Date: $Date: 2005/09/27 14:15:39 $
*
* Copyright (c) 2005 Propero Limited
*
* Purpose: Handles request, receipt and processing of
* licences
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*
* (See gpl.txt for details of the GNU General Public License.)
*
*/
// Created on 02-Jul-2003
package net.propero.rdp;
import java.io.*;
import org.apache.log4j.Logger;
import net.propero.rdp.crypto.*;
public class Licence {
private Secure secure = null;
Licence(Secure s){
secure = s;
licence_key = new byte[16];
licence_sign_key = new byte[16];
}
private byte[] licence_key = null;
private byte[] licence_sign_key = null;
private byte[] in_token = null, in_sig = null;
static Logger logger = Logger.getLogger(Licence.class);
/* constants for the licence negotiation */
private static final int LICENCE_TOKEN_SIZE = 10;
private static final int LICENCE_HWID_SIZE = 20;
private static final int LICENCE_SIGNATURE_SIZE = 16;
/*
private static final int LICENCE_TAG_DEMAND = 0x0201;
private static final int LICENCE_TAG_AUTHREQ = 0x0202;
private static final int LICENCE_TAG_ISSUE = 0x0203;
private static final int LICENCE_TAG_REISSUE = 0x0204; // rdesktop 1.2.0
private static final int LICENCE_TAG_PRESENT = 0x0212; // rdesktop 1.2.0
private static final int LICENCE_TAG_REQUEST = 0x0213;
private static final int LICENCE_TAG_AUTHRESP = 0x0215;
private static final int LICENCE_TAG_RESULT = 0x02ff;
*/
private static final int LICENCE_TAG_DEMAND = 0x01;
private static final int LICENCE_TAG_AUTHREQ = 0x02;
private static final int LICENCE_TAG_ISSUE = 0x03;
private static final int LICENCE_TAG_REISSUE = 0x04;
private static final int LICENCE_TAG_PRESENT = 0x12;
private static final int LICENCE_TAG_REQUEST = 0x13;
private static final int LICENCE_TAG_AUTHRESP = 0x15;
private static final int LICENCE_TAG_RESULT = 0xff;
private static final int LICENCE_TAG_USER = 0x000f;
private static final int LICENCE_TAG_HOST = 0x0010;
public byte[] generate_hwid() throws UnsupportedEncodingException{
byte[] hwid = new byte[LICENCE_HWID_SIZE];
secure.setLittleEndian32(hwid, 2);
byte[] name = Options.hostname.getBytes("US-ASCII");
if (name.length > LICENCE_HWID_SIZE-4) {
System.arraycopy(name, 0, hwid, 4, LICENCE_HWID_SIZE-4);
} else {
System.arraycopy(name, 0, hwid, 4, name.length);
}
return hwid;
}
/**
* Process and handle licence data from a packet
* @param data Packet containing licence data
* @throws RdesktopException
* @throws IOException
* @throws CryptoException
*/
public void process(RdpPacket_Localised data) throws RdesktopException, IOException, CryptoException {
int tag = 0;
tag = data.get8();
data.incrementPosition(3); // version, length
switch(tag) {
case (LICENCE_TAG_DEMAND):
this.process_demand(data);
break;
case (LICENCE_TAG_AUTHREQ):
this.process_authreq(data);
break;
case (LICENCE_TAG_ISSUE):
this.process_issue(data);
break;
case (LICENCE_TAG_REISSUE):
logger.debug("Presented licence was accepted!");
break;
case (LICENCE_TAG_RESULT):
break;
default:
logger.warn("got licence tag: " + tag);
}
}
/**
* Process a demand for a licence. Find a license and transmit to server, or request new licence
* @param data Packet containing details of licence demand
* @throws UnsupportedEncodingException
* @throws RdesktopException
* @throws IOException
* @throws CryptoException
*/
public void process_demand(RdpPacket_Localised data) throws UnsupportedEncodingException, RdesktopException, IOException, CryptoException {
byte[] null_data = new byte[Secure.SEC_MODULUS_SIZE];
byte[] server_random = new byte[Secure.SEC_RANDOM_SIZE];
byte[] host = Options.hostname.getBytes("US-ASCII");
byte[] user = Options.username.getBytes("US-ASCII");
/*retrieve the server random */
data.copyToByteArray(server_random, 0, data.getPosition(), server_random.length);
data.incrementPosition(server_random.length);
/* Null client keys are currently used */
this.generate_keys(null_data, server_random, null_data);
if(!Options.built_in_licence && Options.load_licence){
byte[] licence_data = load_licence();
if ((licence_data != null) && (licence_data.length > 0)){
logger.debug("licence_data.length = "+licence_data.length);
/* Generate a signature for the HWID buffer */
byte[] hwid = generate_hwid();
byte[] signature = secure.sign(this.licence_sign_key, 16, 16, hwid, hwid.length);
/*now crypt the hwid */
RC4 rc4_licence = new RC4();
byte[] crypt_key = new byte[this.licence_key.length];
byte[] crypt_hwid = new byte[LICENCE_HWID_SIZE];
System.arraycopy(this.licence_key, 0, crypt_key, 0, this.licence_key.length);
rc4_licence.engineInitEncrypt(crypt_key);
rc4_licence.crypt(hwid, 0, LICENCE_HWID_SIZE, crypt_hwid, 0);
present(null_data, null_data, licence_data, licence_data.length, crypt_hwid, signature);
logger.debug("Presented stored licence to server!");
return;
}
}
this.send_request(null_data, null_data, user, host);
}
/**
* Handle an authorisation request, based on a licence signature (store signatures in this Licence object
* @param data Packet containing details of request
* @return True if signature is read successfully
* @throws RdesktopException
*/
public boolean parse_authreq(RdpPacket_Localised data)throws RdesktopException {
int tokenlen=0;
data.incrementPosition(6); //unknown
tokenlen = data.getLittleEndian16();
if (tokenlen != LICENCE_TOKEN_SIZE) {
throw new RdesktopException("Wrong Tokenlength!");
}
this.in_token = new byte[tokenlen];
data.copyToByteArray(this.in_token, 0, data.getPosition(), tokenlen);
data.incrementPosition(tokenlen);
this.in_sig = new byte[LICENCE_SIGNATURE_SIZE];
data.copyToByteArray(this.in_sig, 0, data.getPosition(), LICENCE_SIGNATURE_SIZE);
data.incrementPosition(LICENCE_SIGNATURE_SIZE);
if (data.getPosition() == data.getEnd()) {
return true;
} else {
return false;
}
}
/**
* Respond to authorisation request, with token, hwid and signature, send response to server
* @param token Token data
* @param crypt_hwid HWID for encryption
* @param signature Signature data
* @throws RdesktopException
* @throws IOException
* @throws CryptoException
*/
public void send_authresp(byte[] token, byte[] crypt_hwid, byte[] signature) throws RdesktopException, IOException, CryptoException {
int sec_flags = Secure.SEC_LICENCE_NEG;
int length = 58;
RdpPacket_Localised data = null;
data = secure.init(sec_flags, length + 2);
data.set8(LICENCE_TAG_AUTHRESP);
data.set8(2); // version
data.setLittleEndian16(length);
data.setLittleEndian16(1);
data.setLittleEndian16(LICENCE_TOKEN_SIZE);
data.copyFromByteArray(token, 0, data.getPosition(), LICENCE_TOKEN_SIZE);
data.incrementPosition(LICENCE_TOKEN_SIZE);
data.setLittleEndian16(1);
data.setLittleEndian16(LICENCE_HWID_SIZE);
data.copyFromByteArray(crypt_hwid, 0, data.getPosition(), LICENCE_HWID_SIZE);
data.incrementPosition(LICENCE_HWID_SIZE);
data.copyFromByteArray(signature, 0, data.getPosition(), LICENCE_SIGNATURE_SIZE);
data.incrementPosition(LICENCE_SIGNATURE_SIZE);
data.markEnd();
secure.send(data, sec_flags);
}
/**
* Present a licence to the server
* @param client_random
* @param rsa_data
* @param licence_data
* @param licence_size
* @param hwid
* @param signature
* @throws RdesktopException
* @throws IOException
* @throws CryptoException
*/
public void present(byte[] client_random, byte[] rsa_data,
byte[] licence_data, int licence_size, byte[] hwid, byte[] signature)throws RdesktopException,IOException,CryptoException{
int sec_flags = Secure.SEC_LICENCE_NEG;
int length = /* rdesktop is 16 not 20, but this must be wrong?! */
20 + Secure.SEC_RANDOM_SIZE + Secure.SEC_MODULUS_SIZE + Secure.SEC_PADDING_SIZE +
licence_size + LICENCE_HWID_SIZE + LICENCE_SIGNATURE_SIZE;
RdpPacket_Localised s = secure.init(sec_flags, length + 4);
s.set8(LICENCE_TAG_PRESENT);
s.set8(2); // version
s.setLittleEndian16(length);
s.setLittleEndian32(1);
s.setLittleEndian16(0);
s.setLittleEndian16(0x0201);
s.copyFromByteArray(client_random, 0, s.getPosition(), Secure.SEC_RANDOM_SIZE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -