Bläddra i källkod

Send seq nums and b64 encode based on query string.

Query string variable 'b64encode' determine if wsproxy b64 encodes the
results. Variable 'seq_num' determines if sequence numbers are
prepended. This way, sequence numbers are only used with the flash
WebSocket proxy.
Joel Martin 15 år sedan
förälder
incheckning
07287cfd89
3 ändrade filer med 118 tillägg och 86 borttagningar
  1. 1 1
      vnc.html
  2. 88 66
      vnc.js
  3. 29 19
      wsproxy.py

+ 1 - 1
vnc.html

@@ -65,7 +65,7 @@
                     RFB.updateState('failed', "'file://' URL is incompatible with Adobe Flash");
                 } else {
                     WebSocket.__swfLocation = "include/web-socket-js/WebSocketMain.swf";
-                    RFB.force_copy = true;
+                    RFB.use_seq = true;
                     RFB.updateState('disconnected', 'Disconnected');
                 }
             }

+ 88 - 66
vnc.js

@@ -83,7 +83,7 @@ RFB = {
 
 ws        : null,  // Web Socket object
 sendID    : null,
-force_copy : false,
+use_seq   : false,
 
 version   : "RFB 003.003\n",
 state     : 'disconnected',
@@ -647,6 +647,84 @@ clientCutText: function (text) {
  * Utility routines
  */
 
+recv_message: function(e) {
+    //console.log(">> recv_message");
+    RQ = RQ.concat(Base64.decode(e.data, 0));
+
+    RFB.handle_message();
+    //console.log("<< recv_message");
+},
+
+recv_message_reorder: function(e) {
+    //console.log(">> recv_message_reorder");
+
+    var offset = e.data.indexOf(":") + 1;
+    var seq_num = parseInt(e.data.substr(0, offset-1));
+    if (RQ_seq_num == seq_num) {
+        RQ = RQ.concat(Base64.decode(e.data, offset));
+        RQ_seq_num++;
+    } else {
+        console.warn("sequence number mismatch RQ_seq_num:" + RQ_seq_num + ", seq_num:" + seq_num);
+        if (RQ_reorder.length > 20) {
+            RFB.updateState('failed', "Re-order queue too long");
+        } else {
+            RQ_reorder = RQ_reorder.concat(e.data.substr(0));
+            var i = 0;
+            while (i < RQ_reorder.length) {
+                var offset = RQ_reorder[i].indexOf(":") + 1;
+                var seq_num = parseInt(RQ_reorder[i].substr(0, offset-1));
+                console.log("Searching reorder list item " + i + ", seq_num " + seq_num);
+                if (seq_num == RQ_seq_num) {
+                    /* Remove it from reorder queue, decode it and
+                        * add it to the receive queue */
+                    console.log("Found re-ordered packet seq_num " + seq_num);
+                    RQ = RQ.concat(Base64.decode(RQ_reorder.splice(i, 1)[0], offset));
+                    RQ_seq_num++;
+                    i = 0;  // Start search again for next one
+                } else {
+                    i++;
+                }
+            }
+            
+        }
+    }
+
+    RFB.handle_message();
+    //console.log("<< recv_message_reorder");
+},
+
+handle_message: function () {
+    switch (RFB.state) {
+    case 'disconnected':
+        console.error("Got data while disconnected");
+        break;
+    case 'reset':
+        /* close and reset connection */
+        RFB.disconnect();
+        RFB.init_ws();
+        break;
+    case 'failed':
+        console.log("Giving up!");
+        RFB.disconnect();
+        break;
+    case 'normal':
+        RFB.normal_msg();
+        /*
+        while (RQ.length > 0) {
+            if (RFB.normal_msg() && RFB.state == 'normal') {
+                console.log("More to process");
+            } else {
+                break;
+            }
+        }
+        */
+        break;
+    default:
+        RFB.init_msg();
+        break;
+    }
+},
+
 send_string: function (str) {
     //console.log(">> send_string: " + str);
     RFB.send_array(str.split('').map(
@@ -828,74 +906,18 @@ updateState: function(state, statusMsg) {
 init_ws: function () {
 
     console.log(">> init_ws");
-    var uri = "ws://" + RFB.host + ":" + RFB.port;
+    var uri = "ws://" + RFB.host + ":" + RFB.port + "/?b64encode";
+    if (RFB.use_seq) {
+        uri += "&seq_num";
+    }
     console.log("connecting to " + uri);
     RFB.ws = new WebSocket(uri);
-    RFB.ws.onmessage = function(e) {
-        //console.log(">> WebSocket.onmessage");
-
-        var offset = e.data.indexOf(":") + 1;
-        var seq_num = parseInt(e.data.substr(0, offset-1));
-        if (RQ_seq_num == seq_num) {
-            RQ = RQ.concat(Base64.decode(e.data, offset));
-            RQ_seq_num++;
-        } else {
-            console.warn("sequence number mismatch RQ_seq_num:" + RQ_seq_num + ", seq_num:" + seq_num);
-            if (RQ_reorder.length > 20) {
-                RFB.updateState('failed', "Re-order queue too long");
-            } else {
-                RQ_reorder = RQ_reorder.concat(e.data.substr(0));
-                var i = 0;
-                while (i < RQ_reorder.length) {
-                    var offset = RQ_reorder[i].indexOf(":") + 1;
-                    var seq_num = parseInt(RQ_reorder[i].substr(0, offset-1));
-                    console.log("Searching reorder list item " + i + ", seq_num " + seq_num);
-                    if (seq_num == RQ_seq_num) {
-                        /* Remove it from reorder queue, decode it and
-                         * add it to the receive queue */
-                        console.log("Found re-ordered packet seq_num " + seq_num);
-                        RQ = RQ.concat(Base64.decode(RQ_reorder.splice(i, 1)[0], offset));
-                        RQ_seq_num++;
-                        i = 0;  // Start search again for next one
-                    } else {
-                        i++;
-                    }
-                }
-                
-            }
-        }
 
-        switch (RFB.state) {
-        case 'disconnected':
-            console.error("WebSocket.onmessage while disconnected");
-            break;
-        case 'reset':
-            /* close and reset connection */
-            RFB.disconnect();
-            RFB.init_ws();
-            break;
-        case 'failed':
-            console.log("Giving up!");
-            RFB.disconnect();
-            break;
-        case 'normal':
-            RFB.normal_msg();
-            /*
-            while (RQ.length > 0) {
-                if (RFB.normal_msg() && RFB.state == 'normal') {
-                    console.log("More to process");
-                } else {
-                    break;
-                }
-            }
-            */
-            break;
-        default:
-            RFB.init_msg();
-            break;
-        }
-        //console.log("<< WebSocket.onmessage");
-    };
+    if (RFB.use_seq) {
+        RFB.ws.onmessage = RFB.recv_message_reorder;
+    } else {
+        RFB.ws.onmessage = RFB.recv_message;
+    }
     RFB.ws.onopen = function(e) {
         console.log(">> WebSocket.onopen");
         RFB.updateState('ProtocolVersion', "Starting VNC handshake");

+ 29 - 19
wsproxy.py

@@ -1,11 +1,12 @@
 #!/usr/bin/python
 
-import sys, os, socket, time, traceback
+import sys, os, socket, time, traceback, re
 from base64 import b64encode, b64decode
 from select import select
 
 buffer_size = 65536
 send_seq = 0
+client_settings = {}
 
 server_handshake = """HTTP/1.1 101 Web Socket Protocol Handshake\r
 Upgrade: WebSocket\r
@@ -32,21 +33,27 @@ Traffic Legend:
 
 
 def do_handshake(client):
+    global client_settings
     handshake = client.recv(1024)
-    print "Handshake [%s]" % handshake
+    #print "Handshake [%s]" % handshake
     if handshake.startswith("<policy-file-request/>"):
-        print "Sending:", policy_response
+        print "Sending flash policy response"
         client.send(policy_response)
         client.close()
         return False
-        #handshake = client.recv(1024)
-        #if len(handshake) == 0:
-        #    raise Exception("Policy exchange failed")
-        #print "Handshake [%s]" % handshake
     req_lines = handshake.split("\r\n")
     _, path, _ = req_lines[0].split(" ")
     _, origin = req_lines[4].split(" ")
     _, host = req_lines[3].split(" ")
+
+    # Parse settings from the path
+    cvars = path.partition('?')[2].partition('#')[0].split('&')
+    for cvar in [c for c in cvars if c]:
+        name, _, value = cvar.partition('=')
+        client_settings[name] = value and value or True
+
+    print "client_settings:", client_settings
+
     client.send(server_handshake % (origin, host, path))
     return True
 
@@ -76,7 +83,7 @@ def proxy(client, target):
 
         if tqueue and target in outs:
             #print "Target send: %s" % repr(tqueue[0])
-            log.write("Target send: %s\n" % map(ord, tqueue[0]))
+            ##log.write("Target send: %s\n" % map(ord, tqueue[0]))
             dat = tqueue.pop(0)
             sent = target.send(dat)
             if sent == len(dat):
@@ -90,25 +97,28 @@ def proxy(client, target):
             sent = client.send(dat)
             if sent == len(dat):
                 traffic("<")
-                log.write("Client send: %s\n" % repr(dat))
+                ##log.write("Client send: %s\n" % repr(dat))
             else:
                 cqueue.insert(0, dat[sent:])
                 traffic("<.")
-                log.write("Client send partial: %s\n" % repr(dat[0:send]))
+                ##log.write("Client send partial: %s\n" % repr(dat[0:send]))
 
 
         if target in ins:
             buf = target.recv(buffer_size)
             if len(buf) == 0: raise Exception("Target closed")
 
-            #enc = b64encode(buf)
-            #chksum = sum([ord(c) for c in enc])
-            #cqueue.append("\x00^" + str(chksum) + "@" + enc + "$\xff")
+            ##log.write("Target recv (%d): %s\n" % (len(buf), map(ord, buf)))
 
-            cqueue.append("\x00%d:%s\xff" % (send_seq, b64encode(buf)))
-            send_seq += 1
+            if client_settings.get("b64encode"):
+                buf = b64encode(buf)
+
+            if client_settings.get("seq_num"):
+                cqueue.append("\x00%d:%s\xff" % (send_seq, buf))
+                send_seq += 1
+            else:
+                cqueue.append("\x00%s\xff" % buf)
 
-            log.write("Target recv (%d): %s\n" % (len(buf), map(ord, buf)))
             traffic("{")
 
         if client in ins:
@@ -117,7 +127,7 @@ def proxy(client, target):
 
             if buf[-1] == "\xff":
                 traffic("}")
-                log.write("Client recv (%d): %s\n" % (len(buf), repr(buf)))
+                ##log.write("Client recv (%d): %s\n" % (len(buf), repr(buf)))
                 if cpartial:
                     tqueue.extend(decode(cpartial + buf))
                     cpartial = ""
@@ -125,7 +135,7 @@ def proxy(client, target):
                     tqueue.extend(decode(buf))
             else:
                 traffic("}.")
-                log.write("Client recv partial (%d): %s\n" % (len(buf), repr(buf)))
+                ##log.write("Client recv partial (%d): %s\n" % (len(buf), repr(buf)))
                 cpartial = cpartial + buf
 
 
@@ -157,7 +167,7 @@ def start_server(listen_port, target_host, target_port):
             if tsock: tsock.close()
 
 if __name__ == '__main__':
-    log = open("ws.log", 'w')
+    ##log = open("ws.log", 'w')
     try:
         if len(sys.argv) != 4: raise
         listen_port = int(sys.argv[1])