changeset 186:00e031baf065

merge
author Yu Taninari <you@cr.ie.u-ryukyu.ac.jp>
date Mon, 07 Nov 2011 12:48:16 +0900
parents 950ffe24f72e (current diff) 1f583d6e0d1a (diff)
children e7cc8bcf261d
files src/myVncProxy/MyRfbProto.java
diffstat 5 files changed, 666 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/myVncProxy/MulticastQueue.java	Mon Nov 07 12:47:57 2011 +0900
+++ b/src/myVncProxy/MulticastQueue.java	Mon Nov 07 12:48:16 2011 +0900
@@ -43,7 +43,8 @@
 				}catch(InterruptedException _e){
 					continue;
 				}
-				item = node.getItem();
+//				item = node.getItem();
+				item = next.getItem();				
 				node = next;
 			} while ( item == null);
 			return item;
--- a/src/myVncProxy/MyRfbProto.java	Mon Nov 07 12:47:57 2011 +0900
+++ b/src/myVncProxy/MyRfbProto.java	Mon Nov 07 12:48:16 2011 +0900
@@ -164,9 +164,6 @@
 			throw new IOException();
 		}
 		
-		
-		
-		
 	}
 
 	/*
@@ -463,7 +460,7 @@
 
 	void sendDataToClient() throws Exception {
 		regiFramebufferUpdate();
-//		printFramebufferUpdate();
+		printFramebufferUpdate();
 		int dataLen = checkAndMark();
 		readSendData(dataLen);		
 	}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/test/Rfb.java	Mon Nov 07 12:48:16 2011 +0900
@@ -0,0 +1,438 @@
+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);
+	}
+
+	
+	
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/test/VncClientTest.java	Mon Nov 07 12:48:16 2011 +0900
@@ -0,0 +1,160 @@
+package test;
+
+import java.io.IOException;
+
+public class VncClientTest implements java.lang.Runnable {
+	String host;
+	int port;
+	Rfb rfb;
+	Thread th;
+
+	VncClientTest(String[] argv) {
+		host = argv[0];
+		port = Integer.parseInt(argv[1]);
+	}
+
+	public static void main(String[] argv) {
+		VncClientTest c = new VncClientTest(argv);
+		c.init();
+		c.startThread();
+
+	}
+
+	public void init() {
+		th = new Thread(this);
+	}
+
+	public void startThread() {
+		th.start();
+	}
+
+	public void run() {
+
+		try {
+			connectAndAuthenticate();
+			doProtocolInitialisation();
+			processNormalProtocol();
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+
+	}
+
+	void connectAndAuthenticate() throws Exception {
+		showConnectionStatus("Connecting to " + host + ", port " + port + "...");
+		rfb = new Rfb(host, port);
+		showConnectionStatus("Connected server");
+
+		rfb.readVersionMsg();
+		showConnectionStatus("RFB Server supports protocol version"
+				+ rfb.serverMajor + "." + rfb.serverMinor);
+
+		rfb.writeVersionMsg();
+		showConnectionStatus("Using RFB protocol version " + rfb.clientMajor
+				+ "." + rfb.clientMinor);
+
+		int authType = rfb.negotiateSecurity();
+		showConnectionStatus("security type is " + authType);
+
+		switch (authType) {
+		case Rfb.AuthAccess:
+			rfb.authenticationRequestAccess();
+			System.out.println("authenticateion Request right of Access");
+			break;
+		default:
+			throw new Exception("Unknown authentication scheme " + authType);
+		}
+
+	}
+
+	void doProtocolInitialisation() throws IOException {
+		rfb.writeClientInit();
+		rfb.readServerInit();
+
+		System.out.println("Desktop name is " + rfb.desktopName);
+		System.out.println("Desktop size is " + rfb.framebufferWidth + " x "
+				+ rfb.framebufferHeight);
+		setEncodings();
+
+	}
+
+	void setEncodings() throws IOException {
+		int[] encodings = new int[2];
+		int nEncodings = 0;
+
+		encodings[nEncodings++] = Rfb.EncodingZRLE;
+		encodings[nEncodings++] = Rfb.EncodingRaw;
+
+		rfb.writeSetEncodings(encodings, nEncodings);
+
+	}
+
+	void processNormalProtocol() {
+
+		try {
+			rfb.writeFramebufferUpdateRequest(0, 0, rfb.framebufferWidth,
+					rfb.framebufferHeight, false);
+
+			// main loop
+			while (true) {
+
+				int msgType = rfb.readServerMessageType();
+				System.out.println("msgType = " + msgType);
+
+				switch (msgType) {
+				case Rfb.FramebufferUpdate:
+					rfb.readFramebufferUpdate();
+					for (int i = 0; i < rfb.updateNRects; i++) {
+
+						rfb.readFramebufferUpdateRectHdr();
+						rfb.printFrameBufferUpdateRec();
+
+						switch (rfb.updateRectEncoding) {
+						case Rfb.EncodingRaw:
+							readRawEncodingData();
+							break;
+						case Rfb.EncodingZRLE:
+						case Rfb.EncodingZRLEE:
+							readZRLEData();
+							break;
+						default:
+							throw new Exception(
+									"Unknown RFB rectangle encoding "
+											+ rfb.updateRectEncoding);
+						}
+					}
+					break;
+				default:
+					throw new Exception("Unknown RFB message type " + msgType);
+				}
+				rfb.writeFramebufferUpdateRequest(0, 0, rfb.framebufferWidth,
+						rfb.framebufferHeight, true);			
+			}
+
+		} catch (IOException e) {
+			e.printStackTrace();
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+
+	}
+
+	void readRawEncodingData() throws IOException {
+		int nBytes = rfb.updateRectW * rfb.updateRectH * 4 + 16;
+		byte[] b = new byte[nBytes];
+		rfb.readFully(b);
+
+	}
+
+	void readZRLEData() throws IOException {
+		int nBytes = rfb.readU32();
+		byte[] b = new byte[nBytes];
+		rfb.readFully(b);
+
+	}
+
+	void showConnectionStatus(String msg) {
+		System.out.println(msg);
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/test/VncServerTest.java	Mon Nov 07 12:48:16 2011 +0900
@@ -0,0 +1,65 @@
+package test;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.ServerSocket;
+import java.net.Socket;
+
+public class VncServerTest implements java.lang.Runnable {
+	String host;
+	int acceptPort;
+	Rfb rfb;
+	Thread th;
+	ServerSocket sock;
+	
+	public static void main(String[] argv) {
+		VncServerTest s = new  VncServerTest(argv);
+		try {
+			s.init();
+		}catch (IOException e) {
+			e.printStackTrace();
+		}
+		s.startThread();
+
+	}
+	
+	VncServerTest(String[] argv) {
+		acceptPort = Integer.parseInt(argv[0]);
+		rfb = new Rfb();
+	}
+
+	void init() throws IOException {
+		sock = new ServerSocket(acceptPort);
+		th = new Thread(this);
+	}
+
+	void startThread() {
+		th.start();
+	}
+	
+	
+	public void run() {
+		try {
+			System.out.println("accept Port number : "+ acceptPort);
+			Socket cli = sock.accept();
+			InputStream is = cli.getInputStream();
+			OutputStream os = cli.getOutputStream();
+			
+			rfb.sendRfbVersion(os);
+			int rfbMinor = rfb.readVersionMsg(is, os);
+			rfb.sendSecurityType(os);
+			rfb.readSecType(is);
+			rfb.sendSecResult(os, is);
+			
+			
+		}catch(IOException e) {
+			e.printStackTrace();
+		}
+		
+		
+		
+		
+		
+	}
+}