📄 iso.java
字号:
/* ISO.java
* Component: ProperJavaRDP
*
* Revision: $Revision: 1.7 $
* Author: $Author: telliott $
* Date: $Date: 2005/09/27 14:15:39 $
*
* Copyright (c) 2005 Propero Limited
*
* Purpose: ISO layer of communication
*
* 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.)
*
*/
package net.propero.rdp;
import java.io.*;
import java.net.*;
import net.propero.rdp.crypto.CryptoException;
import org.apache.log4j.Logger;
public abstract class ISO {
static Logger logger = Logger.getLogger(ISO.class);
private HexDump dump = null;
protected Socket rdpsock=null;
private DataInputStream in=null;
private DataOutputStream out=null;
/* this for the ISO Layer */
private static final int CONNECTION_REQUEST=0xE0;
private static final int CONNECTION_CONFIRM=0xD0;
private static final int DISCONNECT_REQUEST=0x80;
private static final int DATA_TRANSFER=0xF0;
private static final int ERROR=0x70;
private static final int PROTOCOL_VERSION=0x03;
private static final int EOT=0x80;
/**
* Construct ISO object, initialises hex dump
*/
public ISO() {
dump = new HexDump();
}
/**
* Initialise an ISO PDU
* @param length Desired length of PDU
* @return Packet configured as ISO PDU, ready to write at higher level
*/
public RdpPacket_Localised init(int length) {
RdpPacket_Localised data = new RdpPacket_Localised(length+7);//getMemory(length+7);
data.incrementPosition(7);
data.setStart(data.getPosition());
return data;
}
/*
protected Socket negotiateSSL(Socket sock) throws Exception{
return sock;
}*/
/**
* Create a socket for this ISO object
* @param host Address of server
* @param port Port on which to connect socket
* @throws IOException
*/
protected void doSocketConnect(InetAddress host, int port)throws IOException{
this.rdpsock = new Socket(host,port);
}
/**
* Connect to a server
* @param host Address of server
* @param port Port to connect to on server
* @throws IOException
* @throws RdesktopException
* @throws OrderException
* @throws CryptoException
*/
public void connect(InetAddress host, int port) throws IOException, RdesktopException, OrderException, CryptoException {
int[] code = new int[1];
doSocketConnect(host,port);
rdpsock.setTcpNoDelay(Options.low_latency);
// this.in = new InputStreamReader(rdpsock.getInputStream());
this.in = new DataInputStream(new BufferedInputStream(rdpsock.getInputStream()));
this.out= new DataOutputStream(new BufferedOutputStream(rdpsock.getOutputStream()));
send_connection_request();
receiveMessage(code);
if (code[0] != CONNECTION_CONFIRM) {
throw new RdesktopException("Expected CC got:" + Integer.toHexString(code[0]).toUpperCase());
}
/*if(Options.use_ssl){
try {
rdpsock = this.negotiateSSL(rdpsock);
this.in = new DataInputStream(rdpsock.getInputStream());
this.out= new DataOutputStream(rdpsock.getOutputStream());
} catch (Exception e) {
e.printStackTrace();
throw new RdesktopException("SSL negotiation failed: " + e.getMessage());
}
}*/
}
/**
* Send a self contained iso-pdu
*
* @param type one of the following CONNECT_RESPONSE, DISCONNECT_REQUEST
* @exception IOException when an I/O Error occurs
*/
private void sendMessage(int type) throws IOException {
RdpPacket_Localised buffer = new RdpPacket_Localised(11);//getMemory(11);
byte[] packet=new byte[11];
buffer.set8(PROTOCOL_VERSION); // send Version Info
buffer.set8(0); // reserved byte
buffer.setBigEndian16(11); // Length
buffer.set8(6); // Length of Header
buffer.set8(type); //where code = CR or DR
buffer.setBigEndian16(0); // Destination reference ( 0 at CC and DR)
buffer.setBigEndian16(0); // source reference should be a reasonable address we use 0
buffer.set8(0); //service class
buffer.copyToByteArray(packet, 0, 0, packet.length);
out.write(packet);
out.flush();
}
/**
* Send a packet to the server, wrapped in ISO PDU
* @param buffer Packet containing data to send to server
* @throws RdesktopException
* @throws IOException
*/
public void send(RdpPacket_Localised buffer) throws RdesktopException, IOException {
if(rdpsock == null || out==null) return;
if (buffer.getEnd() < 0) {
throw new RdesktopException("No End Mark!");
} else {
int length = buffer.getEnd();
byte[] packet = new byte[length];
//RdpPacket data = this.getMemory(length+7);
buffer.setPosition(0);
buffer.set8(PROTOCOL_VERSION); // Version
buffer.set8(0); // reserved
buffer.setBigEndian16(length); //length of packet
buffer.set8(2); //length of header
buffer.set8(DATA_TRANSFER);
buffer.set8(EOT);
buffer.copyToByteArray(packet, 0, 0, buffer.getEnd());
if(Options.debug_hexdump) dump.encode(packet, "SEND"/*System.out*/);
out.write(packet);
out.flush();
}
}
/**
* Receive a data transfer message from the server
* @return Packet containing message (as ISO PDU)
* @throws IOException
* @throws RdesktopException
* @throws OrderException
* @throws CryptoException
*/
public RdpPacket_Localised receive() throws IOException, RdesktopException, OrderException, CryptoException {
int[] type = new int[1];
RdpPacket_Localised buffer = receiveMessage(type);
if(buffer==null) return null;
if (type[0] != DATA_TRANSFER) {
throw new RdesktopException("Expected DT got:" + type[0]);
}
return buffer;
}
/**
* Receive a specified number of bytes from the server, and store in a packet
* @param p Packet to append data to, null results in a new packet being created
* @param length Length of data to read
* @return Packet containing read data, appended to original data if provided
* @throws IOException
*/
private RdpPacket_Localised tcp_recv(RdpPacket_Localised p, int length) throws IOException{
logger.debug("ISO.tcp_recv");
RdpPacket_Localised buffer = null;
byte [] packet = new byte[length];
in.readFully(packet,0,length);
// try{ }
// catch(IOException e){ logger.warn("IOException: " + e.getMessage()); return null; }
if(Options.debug_hexdump) dump.encode(packet, "RECEIVE" /*System.out*/);
if(p == null){
buffer = new RdpPacket_Localised(length);
buffer.copyFromByteArray(packet, 0, 0, packet.length);
buffer.markEnd(length);
buffer.setStart(buffer.getPosition());
}else{
buffer = new RdpPacket_Localised((p.getEnd() - p.getStart()) + length);
buffer.copyFromPacket(p,p.getStart(),0,p.getEnd());
buffer.copyFromByteArray(packet, 0, p.getEnd(), packet.length);
buffer.markEnd(p.size() + packet.length);
buffer.setPosition(p.getPosition());
buffer.setStart(0);
}
return buffer;
}
/**
* Receive a message from the server
* @param type Array containing message type, stored in type[0]
* @return Packet object containing data of message
* @throws IOException
* @throws RdesktopException
* @throws OrderException
* @throws CryptoException
*/
private RdpPacket_Localised receiveMessage(int[] type) throws IOException, RdesktopException, OrderException, CryptoException {
logger.debug("ISO.receiveMessage");
RdpPacket_Localised s = null;
int length, version;
next_packet:
while(true){
logger.debug("next_packet");
s = tcp_recv(null,4);
if(s == null) return null;
version = s.get8();
if(version == 3){
s.incrementPosition(1); // pad
length = s.getBigEndian16();
}else{
length = s.get8();
if((length & 0x80) != 0){
length &= ~0x80;
length = (length << 8) + s.get8();
}
}
s = tcp_recv(s, length - 4);
if(s == null) return null;
if((version & 3) == 0){
logger.debug("Processing rdp5 packet");
Common.rdp.rdp5_process(s, (version & 0x80) != 0);
continue next_packet;
}else break;
}
s.get8();
type[0] = s.get8();
if(type[0] == DATA_TRANSFER){
logger.debug("Data Transfer Packet");
s.incrementPosition(1); // eot
return s;
}
s.incrementPosition(5); // dst_ref, src_ref, class
return s;
}
/**
* Disconnect from an RDP session, closing all sockets
*/
public void disconnect() {
if (rdpsock == null) return;
try {
sendMessage(DISCONNECT_REQUEST);
if(in!=null) in.close();
if(out!=null) out.close();
if(rdpsock!=null) rdpsock.close();
} catch(IOException e) {
in=null;
out=null;
rdpsock=null;
return;
}
in=null;
out=null;
rdpsock=null;
}
/**
* Send the server a connection request, detailing client protocol version
* @throws IOException
*/
void send_connection_request() throws IOException{
String uname = Options.username;
if(uname.length() > 9) uname = uname.substring(0,9);
int length = 11 + (Options.username.length() > 0 ? ("Cookie: mstshash=".length() + uname.length() + 2) : 0) + 8;
RdpPacket_Localised buffer = new RdpPacket_Localised(length);
byte[] packet=new byte[length];
buffer.set8(PROTOCOL_VERSION); // send Version Info
buffer.set8(0); // reserved byte
buffer.setBigEndian16(length); // Length
buffer.set8(length-5); // Length of Header
buffer.set8(CONNECTION_REQUEST);
buffer.setBigEndian16(0); // Destination reference ( 0 at CC and DR)
buffer.setBigEndian16(0); // source reference should be a reasonable address we use 0
buffer.set8(0); //service class
if(Options.username.length() > 0){
logger.debug("Including username");
buffer.out_uint8p("Cookie: mstshash=","Cookie: mstshash=".length());
buffer.out_uint8p(uname,uname.length());
buffer.set8(0x0d); // unknown
buffer.set8(0x0a); // unknown
}
/*
// Authentication request?
buffer.setLittleEndian16(0x01);
buffer.setLittleEndian16(0x08);
// Do we try to use SSL?
buffer.set8(Options.use_ssl? 0x01 : 0x00);
buffer.incrementPosition(3);
*/
buffer.copyToByteArray(packet, 0, 0, packet.length);
out.write(packet);
out.flush();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -