📄 licence.java
字号:
s.incrementPosition(Secure.SEC_RANDOM_SIZE);
s.setLittleEndian16(0);
s.setLittleEndian16((Secure.SEC_MODULUS_SIZE + Secure.SEC_PADDING_SIZE));
s.copyFromByteArray(rsa_data, 0, s.getPosition(), Secure.SEC_MODULUS_SIZE);
s.incrementPosition(Secure.SEC_MODULUS_SIZE);
s.incrementPosition(Secure.SEC_PADDING_SIZE);
s.setLittleEndian16(1);
s.setLittleEndian16(licence_size);
s.copyFromByteArray(licence_data, 0, s.getPosition(), licence_size);
s.incrementPosition(licence_size);
s.setLittleEndian16(1);
s.setLittleEndian16(LICENCE_HWID_SIZE);
s.copyFromByteArray(hwid, 0, s.getPosition(), LICENCE_HWID_SIZE);
s.incrementPosition(LICENCE_HWID_SIZE);
s.copyFromByteArray(signature, 0, s.getPosition(), LICENCE_SIGNATURE_SIZE);
s.incrementPosition(LICENCE_SIGNATURE_SIZE);
s.markEnd();
secure.send(s, sec_flags);
}
/**
* Process an authorisation request
* @param data Packet containing request details
* @throws RdesktopException
* @throws UnsupportedEncodingException
* @throws IOException
* @throws CryptoException
*/
public void process_authreq(RdpPacket_Localised data) throws RdesktopException, UnsupportedEncodingException, IOException, CryptoException{
byte[] out_token = new byte[LICENCE_TOKEN_SIZE];
byte[] decrypt_token = new byte[LICENCE_TOKEN_SIZE];
byte[] crypt_hwid = new byte[LICENCE_HWID_SIZE];
byte[] sealed_buffer = new byte[LICENCE_TOKEN_SIZE + LICENCE_HWID_SIZE];
byte[] out_sig = new byte[LICENCE_SIGNATURE_SIZE];
RC4 rc4_licence = new RC4();
byte[] crypt_key = null;
/* parse incoming packet and save encrypted token */
if (parse_authreq(data)!=true) {
throw new RdesktopException("Authentication Request was corrupt!");
}
System.arraycopy(this.in_token, 0, out_token, 0, LICENCE_TOKEN_SIZE);
/* decrypt token. It should read TEST in Unicode */
crypt_key = new byte[this.licence_key.length];
System.arraycopy(this.licence_key, 0, crypt_key, 0, this.licence_key.length);
rc4_licence.engineInitDecrypt(crypt_key);
rc4_licence.crypt(this.in_token, 0, LICENCE_TOKEN_SIZE, decrypt_token, 0);
/*construct HWID */
byte[] hwid = this.generate_hwid();
/* generate signature for a buffer of token and HWId */
System.arraycopy(decrypt_token, 0, sealed_buffer, 0, LICENCE_TOKEN_SIZE);
System.arraycopy(hwid, 0, sealed_buffer, LICENCE_TOKEN_SIZE, LICENCE_HWID_SIZE);
out_sig = secure.sign(this.licence_sign_key, 16, 16, sealed_buffer, sealed_buffer.length);
/* deliberately break signature if licencing disabled */
if (! Constants.licence) {
out_sig = new byte[LICENCE_SIGNATURE_SIZE]; // set to 0
}
/*now crypt the hwid */
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);
this.send_authresp(out_token, crypt_hwid, out_sig);
}
/**
* Handle a licence issued by the server, save to disk if Options.save_licence
* @param data Packet containing issued licence
* @throws CryptoException
*/
public void process_issue(RdpPacket_Localised data)throws CryptoException {
int length = 0;
int check = 0;
RC4 rc4_licence = new RC4();
byte[] key = new byte[this.licence_key.length];
System.arraycopy(this.licence_key, 0, key, 0, this.licence_key.length);
data.incrementPosition(2); //unknown
length = data.getLittleEndian16();
if ( data.getPosition() + length > data.getEnd()) {
return;
}
rc4_licence.engineInitDecrypt(key);
byte[] buffer = new byte[length];
data.copyToByteArray(buffer, 0, data.getPosition(), length);
rc4_licence.crypt(buffer, 0, length, buffer, 0);
data.copyFromByteArray(buffer, 0, data.getPosition(), length);
check = data.getLittleEndian16();
if (check!=0) {
//return;
}
secure.licenceIssued = true;
/*
data.incrementPosition(2); // in_uint8s(s, 2); // pad
// advance to fourth string
length = 0;
for (int i = 0; i < 4; i++)
{
data.incrementPosition(length); // in_uint8s(s, length);
length = data.getLittleEndian32(length); // in_uint32_le(s, length);
if (!(data.getPosition() + length <= data.getEnd()))
return;
}*/
secure.licenceIssued = true;
logger.debug("Server issued Licence");
if(Options.save_licence) save_licence(data,length-2);
}
/**
* Send a request for a new licence, or to approve a stored licence
* @param client_random
* @param rsa_data
* @param username
* @param hostname
* @throws RdesktopException
* @throws IOException
* @throws CryptoException
*/
public void send_request(byte[] client_random, byte[] rsa_data, byte[] username, byte[] hostname) throws RdesktopException, IOException, CryptoException {
int sec_flags = Secure.SEC_LICENCE_NEG;
int userlen = (username.length == 0 ? 0 : username.length+1);
int hostlen = (hostname.length == 0 ? 0 : hostname.length+1);
int length = 128 + userlen + hostlen;
RdpPacket_Localised buffer = secure.init(sec_flags, length);
buffer.set8(LICENCE_TAG_REQUEST);
buffer.set8(2); // version
buffer.setLittleEndian16(length);
buffer.setLittleEndian32(1);
if(Options.built_in_licence && (!Options.load_licence) && (!Options.save_licence)){
logger.debug("Using built-in Windows Licence");
buffer.setLittleEndian32(0x03010000);
}
else{
logger.debug("Requesting licence");
buffer.setLittleEndian32(0xff010000);
}
buffer.copyFromByteArray(client_random, 0, buffer.getPosition(), Secure.SEC_RANDOM_SIZE);
buffer.incrementPosition(Secure.SEC_RANDOM_SIZE);
buffer.setLittleEndian16(0);
buffer.setLittleEndian16(Secure.SEC_MODULUS_SIZE + Secure.SEC_PADDING_SIZE);
buffer.copyFromByteArray(rsa_data, 0, buffer.getPosition(), Secure.SEC_MODULUS_SIZE);
buffer.incrementPosition(Secure.SEC_MODULUS_SIZE);
buffer.incrementPosition(Secure.SEC_PADDING_SIZE);
buffer.setLittleEndian16(LICENCE_TAG_USER);
buffer.setLittleEndian16(userlen);
if (username.length !=0) {
buffer.copyFromByteArray(username, 0, buffer.getPosition(), userlen-1);
} else {
buffer.copyFromByteArray(username, 0, buffer.getPosition(), userlen);
}
buffer.incrementPosition(userlen);
buffer.setLittleEndian16(LICENCE_TAG_HOST);
buffer.setLittleEndian16(hostlen);
if (hostname.length !=0) {
buffer.copyFromByteArray(hostname, 0, buffer.getPosition(), hostlen-1);
} else {
buffer.copyFromByteArray(hostname, 0, buffer.getPosition(), hostlen);
}
buffer.incrementPosition(hostlen);
buffer.markEnd();
secure.send(buffer, sec_flags);
}
/**
* Load a licence from disk
* @return Raw byte data for stored licence
*/
byte[] load_licence(){
logger.debug("load_licence");
//String home = "/root"; // getenv("HOME");
return (new LicenceStore_Localised()).load_licence();
}
/**
* Save a licence to disk
* @param data Packet containing licence data
* @param length Length of licence
*/
void save_licence(RdpPacket_Localised data, int length){
logger.debug("save_licence");
int len;
int startpos = data.getPosition();
data.incrementPosition(2); // Skip first two bytes
/* Skip three strings */
for (int i = 0; i < 3; i++){
len = data.getLittleEndian32();
data.incrementPosition(len);
/* Make sure that we won't be past the end of data after
* reading the next length value
*/
if (data.getPosition() + 4 - startpos > length){
logger.warn("Error in parsing licence key.");
return;
}
}
len = data.getLittleEndian32();
logger.debug("save_licence: len="+len);
if (data.getPosition() + len - startpos > length){
logger.warn("Error in parsing licence key.");
return;
}
byte[] databytes = new byte[len];
data.copyToByteArray(databytes,0,data.getPosition(),len);
new LicenceStore_Localised().save_licence(databytes);
/*
String dirpath = Options.licence_path;//home+"/.rdesktop";
String filepath = dirpath +"/licence."+Options.hostname;
File file = new File(dirpath);
file.mkdir();
try{
FileOutputStream fd = new FileOutputStream(filepath);
// write to the licence file
byte[] databytes = new byte[len];
data.copyToByteArray(databytes,0,data.getPosition(),len);
fd.write(databytes);
fd.close();
logger.info("Stored licence at " + filepath);
}
catch(FileNotFoundException e){logger.info("save_licence: file path not valid!");}
catch(IOException e){logger.warn("IOException in save_licence");}
*/
}
/**
* Generate a set of encryption keys
* @param client_key Array in which to store client key
* @param server_key Array in which to store server key
* @param client_rsa Array in which to store RSA data
* @throws CryptoException
*/
public void generate_keys(byte[] client_key, byte[] server_key, byte[] client_rsa)throws CryptoException {
byte[] session_key = new byte[48];
byte[] temp_hash = new byte[48];
temp_hash = secure.hash48(client_rsa, client_key, server_key, 65);
session_key = secure.hash48(temp_hash, server_key, client_key, 65);
System.arraycopy(session_key, 0, this.licence_sign_key, 0, 16);
this.licence_key = secure.hash16(session_key, client_key, server_key, 16);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -