view src/test/Rfb.java @ 182:8a0e30e527e7

add test/Rfb.java test/VncClient.java test/VncServer.java
author e085711
date Tue, 25 Oct 2011 04:51:23 +0900
parents
children
line wrap: on
line source

package test;

import java.io.*;
import java.net.Socket;

import myVncProxy.MyRfbProto;


public class Rfb {

	// Rfb protocol version
	final static String versionMsg_3_3 = "RFB 003.003\n",
	versionMsg_3_7 = "RFB 003.007\n", versionMsg_3_8 = "RFB 003.008\n",
	versionMsg_3_855 = "RFB 003.855\n", versionMsg_3_889 = "RFB 003.889\n";

	// Security types
	final static int SecTypeInvalid = 0, SecTypeNone = 1, SecTypeVncAuth = 2,
			SecTypeTight = 16, SecTypeReqAccess = 32;

	// Supported authentication types
	final static int AuthNone = 1, AuthVNC = 2;
	final static int AuthAccess = 32; // OS X

	// VNC authentication results
	final static int VncAuthOK = 0, VncAuthFailed = 1, VncAuthTooMany = 2;

	// Standard client-to-server messages
	final static int SetPixelFormat = 0, FixColourMapEntries = 1,
			SetEncodings = 2, FramebufferUpdateRequest = 3, KeyboardEvent = 4,
			PointerEvent = 5, ClientCutText = 6;

	// Supported encodings and pseudo-encodings
	final static int EncodingRaw = 0, EncodingCopyRect = 1, EncodingRRE = 2,
 			EncodingCoRRE = 4, EncodingHextile = 5, EncodingZlib = 6,
			EncodingTight = 7, EncodingZRLEE = 15, EncodingZRLE = 16;

	// Standard server-to-client messages
	final static int FramebufferUpdate = 0, SetColourMapEntries = 1, Bell = 2,
			ServerCutText = 3;

	
	int serverMajor, serverMinor;
	int clientMajor, clientMinor;


	String desktopName;
	int framebufferWidth, framebufferHeight;
	int bitsPerPixel, depth;
	boolean bigEndian, trueColour;
	int redMax, greenMax, blueMax, redShift, greenShift, blueShift;
	
	
	String host;
	int port;
	Socket sock;
	OutputStream os;
	DataInputStream is;
	long numBytesRead = 0;
	
	Rfb(String h, int p) throws IOException {
		host = h;
		port = p;
		sock = new Socket(host, port);
		
		is = new DataInputStream(new BufferedInputStream(sock.getInputStream(),
				16384));
		os = sock.getOutputStream();
	}
	Rfb() {
		
	}

	
	//
	// Read server's protocol version message
	//

	void readVersionMsg() throws Exception {

		byte[] b = new byte[12];

		readFully(b);

		if ((b[0] != 'R') || (b[1] != 'F') || (b[2] != 'B') || (b[3] != ' ')
				|| (b[4] < '0') || (b[4] > '9') || (b[5] < '0') || (b[5] > '9')
				|| (b[6] < '0') || (b[6] > '9') || (b[7] != '.')
				|| (b[8] < '0') || (b[8] > '9') || (b[9] < '0') || (b[9] > '9')
				|| (b[10] < '0') || (b[10] > '9') || (b[11] != '\n')) {
			throw new Exception("Host " + host + " port " + port
					+ " is not an RFB server");
		}

		serverMajor = (b[4] - '0') * 100 + (b[5] - '0') * 10 + (b[6] - '0');
		serverMinor = (b[8] - '0') * 100 + (b[9] - '0') * 10 + (b[10] - '0');

		if (serverMajor < 3) {
			throw new Exception(
					"RFB server does not support protocol version 3");
		}
	}
	
	void writeVersionMsg() throws IOException {
		clientMajor = 3;
		if (serverMinor == 889) {
			clientMinor = 889;
			os.write(versionMsg_3_889.getBytes());
		}else if (serverMinor == 855) {
			clientMinor = 855;
			os.write(versionMsg_3_855.getBytes());
		} else if (serverMajor > 3 || serverMinor >= 8) {
			clientMinor = 8;
			os.write(versionMsg_3_8.getBytes());
		} else if (serverMinor >= 7) {
			clientMinor = 7;
			os.write(versionMsg_3_7.getBytes());
		} else {
			clientMinor = 3;
			os.write(versionMsg_3_3.getBytes());
		}
		
	}
	
	//
	// Negotiate the authentication scheme.
	//

	int negotiateSecurity() throws Exception {
		return selectSecurityType();
	}

	int selectSecurityType() throws Exception {
		int secType = SecTypeInvalid;

		// Read the list of secutiry types.
		int nSecTypes = readU8();
		if (nSecTypes == 0) {
			return SecTypeInvalid; // should never be executed
		}
		byte[] secTypes = new byte[nSecTypes];
		readFully(secTypes);

		System.out.println("Security types: ");
		for(int i=0; i < nSecTypes; i++){
			System.out.print(secTypes[i]+" ");
		}
		System.out.println();

		// Find first supported security type.
		for (int i = 0; i < nSecTypes; i++) {
			if (secTypes[i] == SecTypeNone || secTypes[i] == SecTypeVncAuth 
				|| secTypes[i] == SecTypeReqAccess ) {
				secType = secTypes[i];
				break;
			}
		}
		
		if (secType == SecTypeInvalid) {
			throw new Exception("Server did not offer supported security type");
		} else {
			os.write(secType);
		}
		
		
		return secType;
		
	}
	
	void authenticationRequestAccess() throws IOException {
		byte[] headBuf = new byte[2];
		is.read(headBuf);
		if(headBuf[1] == 2) {
			byte[] b = new byte[258];
			is.read(b);

			byte[] outBuf = new byte[256];
			os.write(outBuf);
			os.flush();
		}else if(headBuf[1] == 23) {
			byte[] b = new byte[130];
			is.read(b);
			byte[] outBuf = new byte[192];
			os.write(outBuf);
			os.flush();
		}
/*
		byte[] b = new byte[260];
		is.read(b);
		
		byte[] outBuf = new byte[256];
		os.write(outBuf);
		os.flush();
*/


		int result = readU32();
		if(result != 0) {
			System.out.println("faild authentication  ");
			throw new IOException();
		}
		
	}
	
	

	//
	// Write the client initialisation message
	//
	void writeClientInit() throws IOException {
		/**
		 * shared flag
		 */
			os.write(1);
//			os.write(0);
	}
	
	void readServerInit() throws IOException {

		framebufferWidth = readU16();
		framebufferHeight = readU16();
		bitsPerPixel = readU8();
		depth = readU8();
		bigEndian = (readU8() != 0);
		trueColour = (readU8() != 0);
		redMax = readU16();
		greenMax = readU16();
		blueMax = readU16();
		redShift = readU8();
		greenShift = readU8();
		blueShift = readU8();
		byte[] pad = new byte[3];
		readFully(pad);
		int nameLength = readU32();
		byte[] name = new byte[nameLength];
		readFully(name);
		desktopName = new String(name);
	}
	
	//
	// Write a SetEncodings message
	//

	void writeSetEncodings(int[] encs, int len) throws IOException {
		byte[] b = new byte[4 + 4 * len];

		b[0] = (byte) SetEncodings;
		b[2] = (byte) ((len >> 8) & 0xff);
		b[3] = (byte) (len & 0xff);

		for (int i = 0; i < len; i++) {
			b[4 + 4 * i] = (byte) ((encs[i] >> 24) & 0xff);
			b[5 + 4 * i] = (byte) ((encs[i] >> 16) & 0xff);
			b[6 + 4 * i] = (byte) ((encs[i] >> 8) & 0xff);
			b[7 + 4 * i] = (byte) (encs[i] & 0xff);
		}

		os.write(b);
	}
	
	//
	// Write a FramebufferUpdateRequest message
	//

	void writeFramebufferUpdateRequest(int x, int y, int w, int h,
			boolean incremental) throws IOException {
		byte[] b = new byte[10];

		b[0] = (byte) FramebufferUpdateRequest;
		b[1] = (byte) (incremental ? 1 : 0);
		b[2] = (byte) ((x >> 8) & 0xff);
		b[3] = (byte) (x & 0xff);
		b[4] = (byte) ((y >> 8) & 0xff);
		b[5] = (byte) (y & 0xff);
		b[6] = (byte) ((w >> 8) & 0xff);
		b[7] = (byte) (w & 0xff);
		b[8] = (byte) ((h >> 8) & 0xff);
		b[9] = (byte) (h & 0xff);

		os.write(b);
	}

	//
	// Read a FramebufferUpdate message
	//

	int updateNRects;
	void readFramebufferUpdate() throws IOException {
		skipBytes(1);
		updateNRects = readU16();
	}

	
	//
	// Read the server message type
	//

	int readServerMessageType() throws IOException {
		int msgType = readU8();
		return msgType;
	}
	
	// Read a FramebufferUpdate rectangle header

	int updateRectX, updateRectY, updateRectW, updateRectH, updateRectEncoding;
	void readFramebufferUpdateRectHdr() throws Exception {
		updateRectX = readU16();
		updateRectY = readU16();
		updateRectW = readU16();
		updateRectH = readU16();
		updateRectEncoding = readU32();

	}
	void printFrameBufferUpdateRec() {
		System.out.println("updateRectX " + updateRectX );
		System.out.println("updateRectY " + updateRectY );
		System.out.println("updateRectW " + updateRectW );
		System.out.println("updateRectH " + updateRectH );
		System.out.println("updateRectEncoding " + updateRectEncoding );
		
	}

	public void readFully(byte b[]) throws IOException {
		readFully(b, 0, b.length);
	}

	public void readFully(byte b[], int off, int len) throws IOException {
		is.readFully(b, off, len);
		numBytesRead += len;
	}

	
	final int skipBytes(int n) throws IOException {
		int r = is.skipBytes(n);
		numBytesRead += r;
		return r;
	}

	final int readU8() throws IOException {
		int r = is.readUnsignedByte();
		numBytesRead++;

		return r;
	}

	final int readU16() throws IOException {
		int r = is.readUnsignedShort();
		numBytesRead += 2;
		return r;
	}

	final int readU32() throws IOException {
		int r = is.readInt();
		numBytesRead += 4;
		return r;
	}
	
	
	void sendRfbVersion(OutputStream os) throws IOException {
		os.write(versionMsg_3_889.getBytes());
	}
	
	int readVersionMsg(InputStream is, OutputStream os) throws IOException {

		byte[] b = new byte[12];

		is.read(b);

		if ((b[0] != 'R') || (b[1] != 'F') || (b[2] != 'B') || (b[3] != ' ')
				|| (b[4] < '0') || (b[4] > '9') || (b[5] < '0') || (b[5] > '9')
				|| (b[6] < '0') || (b[6] > '9') || (b[7] != '.')
				|| (b[8] < '0') || (b[8] > '9') || (b[9] < '0') || (b[9] > '9')
				|| (b[10] < '0') || (b[10] > '9') || (b[11] != '\n')) {
			throw new IOException("Host " + host + " port " + port
					+ " is not an RFB server");
		}

		int rfbMajor = (b[4] - '0') * 100 + (b[5] - '0') * 10 + (b[6] - '0');
		int rfbMinor = (b[8] - '0') * 100 + (b[9] - '0') * 10 + (b[10] - '0');

		if (rfbMajor < 3) {
			throw new IOException(
			"RFB server does not support protocol version 3");
		}
		return rfbMinor;
	}

	void sendSecurityType(OutputStream os) throws IOException {

		byte[] b = {30, 31, 32, 35};
		os.write((byte)b.length);
		os.write(b);
		os.flush();

/*
		// number-of-security-types
		os.write(1);
		// security-types
		// 1:None
		os.write(1);
*/		
		
		/*
 		os.write(4);
		os.write(30);
		os.write(31);
		os.write(32);
		os.write(35);
		os.flush();
*/		
	}
	

	void readSecType(InputStream is) throws IOException {
		byte[] b = new byte[1];
		is.read(b);
	}

	
	void sendSecResult(OutputStream os, InputStream is) throws IOException {

		// lion, or 10.6.8+
//		byte[] outBuf = {0, 2, 0, -128, -1, -1, -1, -1, -1, -1, -1, -1, -55, 15, -38, -94, 33, 104, -62, 52, -60, -58, 98, -117, -128, -36, 28, -47, 41, 2, 78, 8, -118, 103, -52, 116, 2, 11, -66, -90, 59, 19, -101, 34, 81, 74, 8, 121, -114, 52, 4, -35, -17, -107, 25, -77, -51, 58, 67, 27, 48, 43, 10, 109, -14, 95, 20, 55, 79, -31, 53, 109, 109, 81, -62, 69, -28, -123, -75, 118, 98, 94, 126, -58, -12, 76, 66, -23, -90, 55, -19, 107, 11, -1, 92, -74, -12, 6, -73, -19, -18, 56, 107, -5, 90, -119, -97, -91, -82, -97, 36, 17, 124, 75, 31, -26, 73, 40, 102, 81, -20, -26, 83, -127, -1, -1, -1, -1, -1, -1, -1, -1, -13, -111, -67, 127, 91, -65, -76, -19, -97, 71, -33, 122, -32, -40, 56, -31, 45, 121, 64, -118, -82, -74, 2, 14, 111, -108, 1, -12, -17, 116, 82, 106, -107, -35, -97, 81, -94, 47, -61, 127, -2, -33, -89, -121, 111, -38, 17, -5, -10, 87, 105, -68, 124, 118, -68, 57, 34, -66, -53, 48, -101, 119, 13, -92, 96, 38, -43, -6, -113, -49, 87, 79, 45, -35, -59, 21, 108, 35, -49, 84, -127, -99, 23, 63, -70, 113, -81, 101, 127, 95, -114, -99, 66, 69, -15, -123, -107, -91, 15, 1, -57, -56, -56, -92, -100, 115, 63, 108, -115, 50, -111, -24, -117, 115, -62, -111, -128, 71, 81, 106, 98, -48, -89, 20, 40, 115, 57, 53};
		
		// ver 10.6.7
		byte[] outBuf = {0, 23, 0, 64, -8, 40, 59, -17, -42, -32, -57, -77, -102, 121, -24, 3, 31, 11, 108, -36, 92, 92, 65, 45, -72, -72, -63, 12, -43, 84, -33, -16, -31, 97, -38, -12, -11, 119, 52, -22, 12, -85, -14, -59, 11, 119, -63, -108, 109, 43, 56, 126, 65, -42, 115, 122, 93, 73, 86, -22, 61, 55, 15, -69, 54, -88, 40, -41, 86, 2, -66, -67, 18, -51, -85, 87, 41, -99, 79, 71, -14, -64, 34, 39, 72, -61, -17, -69, -117, -45, 49, -63, 80, -88, 8, -69, 106, -10, 61, -89, -8, -72, 113, -103, -93, 54, -71, 45, -117, 37, -42, 49, 66, -51, 21, 89, -109, -20, -22, 37, 108, 31, 65, 43, -73, 23, 112, -52, 70, 100, -75, -115};
		os.write(outBuf);

		
		byte[] inBuf = new byte[300];
		is.read(inBuf);
		
		
		// 
		os.write(0);
	}

	
	
}