⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mcs.java

📁 cygwin 是一个在windows平台上运行的unix模拟环境
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* MCS.java
 * Component: ProperJavaRDP
 * 
 * Revision: $Revision: 1.7 $
 * Author: $Author: telliott $
 * Date: $Date: 2005/09/27 14:15:39 $
 *
 * Copyright (c) 2005 Propero Limited
 *
 * Purpose: MCS 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 net.propero.rdp.rdp5.VChannels;

import org.apache.log4j.Logger;

public class MCS {
	static Logger logger = Logger.getLogger(MCS.class);
    private ISO IsoLayer=null;
    private int McsUserID;

    /* this for the MCS Layer */
    private static final int CONNECT_INITIAL = 0x7f65;
    private static final int CONNECT_RESPONSE= 0x7f66;
    
    private static final int BER_TAG_BOOLEAN = 1;
    private static final int BER_TAG_INTEGER = 2;
    private static final int BER_TAG_OCTET_STRING = 4;
    private static final int BER_TAG_RESULT = 10;
    private static final int TAG_DOMAIN_PARAMS = 0x30;

    public static final int MCS_GLOBAL_CHANNEL =1003;
    public static final int MCS_USERCHANNEL_BASE = 1001;

    private static final int EDRQ = 1;		/* Erect Domain Request */
    private static final int DPUM = 8;		/* Disconnect Provider Ultimatum */
    private static final int AURQ = 10;		/* Attach User Request */
    private static final int AUCF = 11;		/* Attach User Confirm */
    private static final int CJRQ = 14;		/* Channel Join Request */
    private static final int CJCF = 15;		/* Channel Join Confirm */
    private static final int SDRQ = 25;		/* Send Data Request */
    private static final int SDIN = 26;		/* Send Data Indication */

    private VChannels channels;

    /**
     * Initialise the MCS layer (and lower layers) with provided channels
     * @param channels Set of available MCS channels
     */
    public MCS(VChannels channels) {
        this.channels = channels;
    	IsoLayer = new ISO_Localised();
    }
    
    /**
     * Connect to a server
     * @param host Address of server
     * @param port Port to connect to on server
     * @param data Packet to use for sending connection data
     * @throws IOException
     * @throws RdesktopException
     * @throws OrderException
     * @throws CryptoException
     */
    public void connect(InetAddress host, int port, RdpPacket_Localised data)  throws IOException, RdesktopException, OrderException, CryptoException {
	logger.debug("MCS.connect");
    IsoLayer.connect(host, port);

    this.sendConnectInitial(data);
	this.receiveConnectResponse(data);

    logger.debug("connect response received");
    
	send_edrq();
	send_aurq();

	this.McsUserID=receive_aucf();
	send_cjrq(this.McsUserID+MCS_USERCHANNEL_BASE);
	receive_cjcf();
	send_cjrq(MCS_GLOBAL_CHANNEL);
	receive_cjcf();
	
	for (int i = 0; i < channels.num_channels(); i++)
	{
		send_cjrq(channels.mcs_id(i));
		receive_cjcf();
	}

    }
    
 
    /**
     * Disconnect from server
     *
     */
    public void disconnect() {
	IsoLayer.disconnect();
	//in=null;
	//out=null;
    }

    /**
     * Initialise a packet as an MCS PDU
     * @param length Desired length of PDU
     * @return
     * @throws RdesktopException
     */
    public RdpPacket_Localised init(int length) throws RdesktopException {
	RdpPacket_Localised data = IsoLayer.init(length+8);
	//data.pushLayer(RdpPacket_Localised.MCS_HEADER, 8);
	data.setHeader(RdpPacket_Localised.MCS_HEADER);
	data.incrementPosition(8);
	data.setStart(data.getPosition());
	return data;
    }
	
    /**
     * Send a packet to the global channel
     * @param buffer Packet to send
     * @throws RdesktopException
     * @throws IOException
     */
	public void send(RdpPacket_Localised buffer) throws RdesktopException, IOException {
	send_to_channel(buffer,MCS_GLOBAL_CHANNEL);
	}
	
    /**
     * Send a packet to a specified channel
     * @param buffer Packet to send to channel
     * @param channel Id of channel on which to send packet
     * @throws RdesktopException
     * @throws IOException
     */
    public void send_to_channel(RdpPacket_Localised buffer,int channel) throws RdesktopException, IOException {
	int length=0;
	buffer.setPosition(buffer.getHeader(RdpPacket_Localised.MCS_HEADER));

	length=buffer.getEnd()-buffer.getHeader(RdpPacket_Localised.MCS_HEADER)-8;
	length|=0x8000;
	
	buffer.set8((SDRQ << 2));
	buffer.setBigEndian16(this.McsUserID);
	buffer.setBigEndian16(channel);
	buffer.set8(0x70); //Flags
	buffer.setBigEndian16(length);
	IsoLayer.send(buffer);
    }

    /**
     * Receive an MCS PDU from the next channel with available data
     * @param channel ID of channel will be stored in channel[0]
     * @return Received packet
     * @throws IOException
     * @throws RdesktopException
     * @throws OrderException
     * @throws CryptoException
     */
    public RdpPacket_Localised receive(int[] channel) throws IOException, RdesktopException, OrderException, CryptoException {
    	logger.debug("receive");
    	int opcode=0, appid=0, length=0;
	RdpPacket_Localised buffer=IsoLayer.receive();
	if(buffer==null) return null;
	buffer.setHeader(RdpPacket_Localised.MCS_HEADER);
	opcode = buffer.get8();

	appid = opcode>>2;

	if (appid != SDIN) {
	    if (appid != DPUM) {
		throw new RdesktopException("Expected data got" + opcode);
	    }
	    throw new EOFException("End of transmission!");
	}

	buffer.incrementPosition(2); // Skip UserID
	channel[0] = buffer.getBigEndian16(); // Get ChannelID
	logger.debug("Channel ID = " + channel[0]);
	buffer.incrementPosition(1); // Skip Flags
	
	length=buffer.get8();
	
	if((length&0x80)!=0) {
	    buffer.incrementPosition(1);
	}
	buffer.setStart(buffer.getPosition());
	return buffer;
    }
    
    
    /**
     * send an Integer encoded according to the ISO ASN.1 Basic Encoding Rules
     * @param buffer Packet in which to store encoded value
     * @param value Integer value to store
     */
    public void sendBerInteger(RdpPacket_Localised buffer, int value) {
	
    	int len = 1;
    	
    	if(value > 0xff) len = 2;
    	
	sendBerHeader(buffer, BER_TAG_INTEGER, len);
	
	if(value > 0xff){
		buffer.setBigEndian16(value);
	}else{
		buffer.set8(value);
	}
	
    }
    
    /**
     * Determine the size of a BER header encoded for the specified tag and data length
     * @param tagval Value of tag identifying data type
     * @param length Length of data header will precede
     * @return
     */
    private int berHeaderSize(int tagval, int length){
    	int total = 0;
    	if (tagval > 0xff) {
    	    total += 2;
    	} else {
    		total += 1;
    	}
    	
    	if (length >= 0x80) {
    	    total += 3;
    	} else {
    		total += 1;
    	}
    	return total;
    }
    
    /**
     * Send a Header encoded according to the ISO ASN.1 Basic Encoding rules
     * @param buffer Packet in which to send the header
     * @param tagval Data type for header
     * @param length Length of data header precedes
     */
    public void sendBerHeader(RdpPacket_Localised buffer, int tagval, int length) {
	if (tagval > 0xff) {
	    buffer.setBigEndian16(tagval);
	} else {
	    buffer.set8(tagval);
	}
	
	if (length >= 0x80) {
	    buffer.set8(0x82);
	    buffer.setBigEndian16(length);
	} else {
	    buffer.set8(length);
	}
    }
    
    /**
     * Determine the size of a BER encoded integer with specified value
     * @param value Value of integer
     * @return Number of bytes the encoded data would occupy
     */
    private int BERIntSize(int value){
    	if(value > 0xff) return 4;
    	else return 3;
    }
    
    /**
     * Determine the size of the domain parameters, encoded according to the ISO ASN.1 Basic Encoding Rules
     * @param max_channels Maximum number of channels
     * @param max_users Maximum number of users
     * @param max_tokens Maximum number of tokens
     * @param max_pdusize Maximum size of an MCS PDU
     * @return Number of bytes the domain parameters would occupy
     */
    private int domainParamSize(int max_channels, int max_users, int max_tokens, int max_pdusize){
    	int endSize = BERIntSize(max_channels) +
		BERIntSize(max_users) +
		BERIntSize(max_tokens) +
		BERIntSize(1) +
		BERIntSize(0) +
		BERIntSize(1) +
		BERIntSize(max_pdusize) +
		BERIntSize(2);
    	return	berHeaderSize(TAG_DOMAIN_PARAMS,endSize) + endSize;
    }

    /**
     * send a DOMAIN_PARAMS structure encoded according to the ISO ASN.1
     * Basic Encoding rules
     * @param buffer Packet in which to send the structure
     * @param max_channels Maximum number of channels
     * @param max_users Maximum number of users
     * @param max_tokens Maximum number of tokens
     * @param max_pdusize Maximum size for an MCS PDU
     */
    public void sendDomainParams(RdpPacket_Localised buffer, int max_channels, int max_users, int max_tokens, int max_pdusize) {
	
    	int size =	BERIntSize(max_channels) +
					BERIntSize(max_users) +
					BERIntSize(max_tokens) +
					BERIntSize(1) +
					BERIntSize(0) +
					BERIntSize(1) +
					BERIntSize(max_pdusize) +
					BERIntSize(2);
    	
	sendBerHeader(buffer,  TAG_DOMAIN_PARAMS, size);
	sendBerInteger(buffer, max_channels);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -