Package com.lixia.rdp

Source Code of com.lixia.rdp.ISO

/* ISO.java
* Component: ProperJavaRDP
*
* Revision: $Revision: 1.1.1.1 $
* Author: $Author: suvarov $
* Date: $Date: 2007/03/08 00:26:21 $
*
* Copyright (c) 2005 Propero Limited
*
* Purpose: ISO layer of communication
*/
package com.lixia.rdp;

import com.alssoftrd.utils.RDPConnection;
import java.io.*;
import java.net.*;

import com.lixia.rdp.crypto.CryptoException;
import com.lixia.rdp.Package.RdpPackage;
import com.lixia.uag.websocket.LocalHttpTunnel;


public abstract class ISO {

//    static Logger logger = Logger.getLogger("ISO");

    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 RdpPackage init(int length) {
        RdpPackage data = new RdpPackage(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 {
        int timeout_ms = 3000; // timeout in milliseconds

        if (RDPConnection.conf.http_mode && RDPConnection.conf.http_server != null) {
            LocalHttpTunnel tunnel = new LocalHttpTunnel(RDPConnection.conf.http_server,
                    new InetSocketAddress(host, port),
                    RDPConnection.conf.username,
                    RDPConnection.conf.password,
                    RDPConnection.conf.command);
            SocketAddress endpoint = tunnel.createTunnel();
            if (endpoint != null) {
                this.rdpsock = new Socket();
                rdpsock.connect(endpoint, timeout_ms);
            } else {
                throw new IOException("failed to create tunnel!");
            }
        } else {
            rdpsock = new Socket();
            rdpsock.connect(new InetSocketAddress(host, port), timeout_ms);
        }
    }

    /**
     * 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(RDPConnection.conf.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());
        }
    }

    /**
     * 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 {
        RdpPackage buffer = new RdpPackage(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(RdpPackage 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 (RDPConnection.conf.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 RdpPackage receive() throws IOException, RdesktopException, OrderException, CryptoException {
        int[] type = new int[1];
        RdpPackage 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 RdpPackage tcp_recv(RdpPackage p, int length) throws IOException {
        RdpPackage buffer;
        byte[] packet = new byte[length];
        in.readFully(packet, 0, length);
        // try{ }
        // catch(IOException e){ logger.warn("IOException: " + e.getMessage()); return null;  }
        if (RDPConnection.conf.debug_hexdump) {
            dump.encode(packet, "RECEIVE" /*System.out*/);
        }
        if (p == null) {
            buffer = new RdpPackage(length);
            buffer.copyFromByteArray(packet, 0, 0, packet.length);
            buffer.markEnd(length);
            buffer.setStart(buffer.getPosition());
        } else {
            buffer = new RdpPackage((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 RdpPackage receiveMessage(int[] type) throws IOException, RdesktopException, OrderException, CryptoException {
        RdpPackage s = null;
        int length, version;

        next_packet:
        while (true) {
            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) {
                RDPConnection.conf.rdp.rdp5_process(s, (version & 0x80) != 0);
                continue next_packet;
            } else {
                break;
            }
        }
        s.get8();
        type[0] = s.get8();

        if (type[0] == DATA_TRANSFER) {
            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 = RDPConnection.conf.username;
        if (uname.length() > 9) {
            uname = uname.substring(0, 9);
        }
        int length = 11 + (RDPConnection.conf.username.length() > 0 ? ("Cookie: mstshash="
                .length()
                + uname.length() + 2) : 0) + 8;
        RdpPackage buffer = new RdpPackage(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 (RDPConnection.conf.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(RDPConnection.conf.use_ssl? 0x01 : 0x00);
         buffer.incrementPosition(3);
         */
        buffer.copyToByteArray(packet, 0, 0, packet.length);
        out.write(packet);
        out.flush();
    }
}
TOP

Related Classes of com.lixia.rdp.ISO

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.