# HG changeset patch # User Yu Taninari # Date 1320637696 -32400 # Node ID 00e031baf06501d45063ee160c04be03262a50b1 # Parent 950ffe24f72e26943a8cd2773b92b90fbeaf1ed8# Parent 1f583d6e0d1a25628eb7bfa415bc18930f2f9495 merge diff -r 950ffe24f72e -r 00e031baf065 src/myVncProxy/MulticastQueue.java --- 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; diff -r 950ffe24f72e -r 00e031baf065 src/myVncProxy/MyRfbProto.java --- 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); } diff -r 950ffe24f72e -r 00e031baf065 src/test/Rfb.java --- /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); + } + + + +} diff -r 950ffe24f72e -r 00e031baf065 src/test/VncClientTest.java --- /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); + } + +} diff -r 950ffe24f72e -r 00e031baf065 src/test/VncServerTest.java --- /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(); + } + + + + + + } +}