cloudstack-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From weiz...@apache.org
Subject [16/25] add patches for leaseweb
Date Wed, 26 Jun 2013 09:30:26 GMT
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a0571d1e/patches/systemvm/debian/config/root/lswcp/utils/websocket.py
----------------------------------------------------------------------
diff --git a/patches/systemvm/debian/config/root/lswcp/utils/websocket.py b/patches/systemvm/debian/config/root/lswcp/utils/websocket.py
new file mode 100644
index 0000000..82bb56c
--- /dev/null
+++ b/patches/systemvm/debian/config/root/lswcp/utils/websocket.py
@@ -0,0 +1,925 @@
+#!/usr/bin/env python
+
+'''
+Python WebSocket library with support for "wss://" encryption.
+Copyright 2011 Joel Martin
+Licensed under LGPL version 3 (see docs/LICENSE.LGPL-3)
+
+Supports following protocol versions:
+    - http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-75
+    - http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-76
+    - http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-10
+
+You can make a cert/key with openssl using:
+openssl req -new -x509 -days 365 -nodes -out self.pem -keyout self.pem
+as taken from http://docs.python.org/dev/library/ssl.html#certificates
+
+'''
+
+import os, sys, time, errno, signal, socket, traceback, select, re
+import array, struct
+from cgi import parse_qsl
+from base64 import b64encode, b64decode
+
+# Imports that vary by python version
+
+# python 3.0 differences
+if sys.hexversion > 0x3000000:
+    b2s = lambda buf: buf.decode('latin_1')
+    s2b = lambda s: s.encode('latin_1')
+    s2a = lambda s: s
+else:
+    b2s = lambda buf: buf  # No-op
+    s2b = lambda s: s      # No-op
+    s2a = lambda s: [ord(c) for c in s]
+try:    from io import StringIO
+except: from cStringIO import StringIO
+try:    from http.server import SimpleHTTPRequestHandler
+except: from SimpleHTTPServer import SimpleHTTPRequestHandler
+try:    from urllib.parse import urlsplit
+except: from urlparse import urlsplit
+
+# python 2.6 differences
+try:    from hashlib import md5, sha1
+except: from md5 import md5; from sha import sha as sha1
+
+# python 2.5 differences
+try:
+    from struct import pack, unpack_from
+except:
+    from struct import pack
+    def unpack_from(fmt, buf, offset=0):
+        slice = buffer(buf, offset, struct.calcsize(fmt))
+        return struct.unpack(fmt, slice)
+
+# Degraded functionality if these imports are missing
+for mod, sup in [('numpy', 'HyBi protocol'), ('ssl', 'TLS/SSL/wss'),
+        ('multiprocessing', 'Multi-Processing'),
+        ('resource', 'daemonizing')]:
+    try:
+        globals()[mod] = __import__(mod)
+    except ImportError:
+        globals()[mod] = None
+        print("WARNING: no '%s' module, %s is slower or disabled" % (
+            mod, sup))
+if multiprocessing and sys.platform == 'win32':
+    # make sockets pickle-able/inheritable
+    import multiprocessing.reduction
+
+
+class WebSocketServer(object):
+    """
+    WebSockets server class.
+    Must be sub-classed with new_client method definition.
+    """
+
+    buffer_size = 65536
+
+    server_handshake_hixie = """HTTP/1.1 101 Web Socket Protocol Handshake\r
+Upgrade: WebSocket\r
+Connection: Upgrade\r
+%sWebSocket-Origin: %s\r
+%sWebSocket-Location: %s://%s%s\r
+"""
+
+    server_handshake_hybi = """HTTP/1.1 101 Switching Protocols\r
+Upgrade: websocket\r
+Connection: Upgrade\r
+Sec-WebSocket-Accept: %s\r
+"""
+
+    GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
+
+    policy_response = """<cross-domain-policy><allow-access-from domain="*" to-ports="*" /></cross-domain-policy>\n"""
+
+    class EClose(Exception):
+        pass
+
+    def __init__(self, listen_host='', listen_port=None, source_is_ipv6=False,
+            verbose=False, cert='', key='', ssl_only=None,
+            daemon=False, record='', web='',
+            run_once=False, timeout=0):
+
+        # settings
+        self.verbose        = verbose
+        self.listen_host    = listen_host
+        self.listen_port    = listen_port
+        self.ssl_only       = ssl_only
+        self.daemon         = daemon
+        self.run_once       = run_once
+        self.timeout        = timeout
+
+        self.launch_time    = time.time()
+        self.ws_connection  = False
+        self.handler_id     = 1
+
+        # Make paths settings absolute
+        self.cert = os.path.abspath(cert)
+        self.key = self.web = self.record = ''
+        if key:
+            self.key = os.path.abspath(key)
+        if web:
+            self.web = os.path.abspath(web)
+        if record:
+            self.record = os.path.abspath(record)
+
+        if self.web:
+            os.chdir(self.web)
+
+        # Sanity checks
+        if not ssl and self.ssl_only:
+            raise Exception("No 'ssl' module and SSL-only specified")
+        if self.daemon and not resource:
+            raise Exception("Module 'resource' required to daemonize")
+
+        # Show configuration
+        print("WebSocket server settings:")
+        print("  - Listen on %s:%s" % (
+                self.listen_host, self.listen_port))
+        print("  - Flash security policy server")
+        if self.web:
+            print("  - Web server. Web root: %s" % self.web)
+        if ssl:
+            if os.path.exists(self.cert):
+                print("  - SSL/TLS support")
+                if self.ssl_only:
+                    print("  - Deny non-SSL/TLS connections")
+            else:
+                print("  - No SSL/TLS support (no cert file)")
+        else:
+            print("  - No SSL/TLS support (no 'ssl' module)")
+        if self.daemon:
+            print("  - Backgrounding (daemon)")
+        if self.record:
+            print("  - Recording to '%s.*'" % self.record)
+
+    #
+    # WebSocketServer static methods
+    #
+
+    @staticmethod
+    def socket(host, port=None, connect=False, prefer_ipv6=False):
+        """ Resolve a host (and optional port) to an IPv4 or IPv6
+        address. Create a socket. Bind to it if listen is set,
+        otherwise connect to it. Return the socket.
+        """
+        flags = 0
+        if host == '':
+            host = None
+        if connect and not port:
+            raise Exception("Connect mode requires a port")
+        if not connect:
+            flags = flags | socket.AI_PASSIVE
+        addrs = socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM,
+                socket.IPPROTO_TCP, flags)
+        if not addrs:
+            raise Exception("Could resolve host '%s'" % host)
+        addrs.sort(key=lambda x: x[0])
+        if prefer_ipv6:
+            addrs.reverse()
+        sock = socket.socket(addrs[0][0], addrs[0][1])
+        if connect:
+            sock.connect(addrs[0][4])
+        else:
+            sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+            sock.bind(addrs[0][4])
+            sock.listen(100)
+        return sock
+
+    @staticmethod
+    def daemonize(keepfd=None, chdir='/'):
+        os.umask(0)
+        if chdir:
+            os.chdir(chdir)
+        else:
+            os.chdir('/')
+        os.setgid(os.getgid())  # relinquish elevations
+        os.setuid(os.getuid())  # relinquish elevations
+
+        # Double fork to daemonize
+        if os.fork() > 0: os._exit(0)  # Parent exits
+        os.setsid()                    # Obtain new process group
+        if os.fork() > 0: os._exit(0)  # Parent exits
+
+        # Signal handling
+        def terminate(a,b): os._exit(0)
+        signal.signal(signal.SIGTERM, terminate)
+        signal.signal(signal.SIGINT, signal.SIG_IGN)
+
+        # Close open files
+        maxfd = resource.getrlimit(resource.RLIMIT_NOFILE)[1]
+        if maxfd == resource.RLIM_INFINITY: maxfd = 256
+        for fd in reversed(range(maxfd)):
+            try:
+                if fd != keepfd:
+                    os.close(fd)
+            except OSError:
+                _, exc, _ = sys.exc_info()
+                if exc.errno != errno.EBADF: raise
+
+        # Redirect I/O to /dev/null
+        os.dup2(os.open(os.devnull, os.O_RDWR), sys.stdin.fileno())
+        os.dup2(os.open(os.devnull, os.O_RDWR), sys.stdout.fileno())
+        os.dup2(os.open(os.devnull, os.O_RDWR), sys.stderr.fileno())
+
+    @staticmethod
+    def unmask(buf, f):
+        pstart = f['hlen'] + 4
+        pend = pstart + f['length']
+        if numpy:
+            b = c = s2b('')
+            if f['length'] >= 4:
+                mask = numpy.frombuffer(buf, dtype=numpy.dtype('<u4'),
+                        offset=f['hlen'], count=1)
+                data = numpy.frombuffer(buf, dtype=numpy.dtype('<u4'),
+                        offset=pstart, count=int(f['length'] / 4))
+                #b = numpy.bitwise_xor(data, mask).data
+                b = numpy.bitwise_xor(data, mask).tostring()
+
+            if f['length'] % 4:
+                #print("Partial unmask")
+                mask = numpy.frombuffer(buf, dtype=numpy.dtype('B'),
+                        offset=f['hlen'], count=(f['length'] % 4))
+                data = numpy.frombuffer(buf, dtype=numpy.dtype('B'),
+                        offset=pend - (f['length'] % 4),
+                        count=(f['length'] % 4))
+                c = numpy.bitwise_xor(data, mask).tostring()
+            return b + c
+        else:
+            # Slower fallback
+            data = array.array('B')
+            mask = s2a(f['mask'])
+            data.fromstring(buf[pstart:pend])
+            for i in range(len(data)):
+                data[i] ^= mask[i % 4]
+            return data.tostring()
+
+    @staticmethod
+    def encode_hybi(buf, opcode, base64=False):
+        """ Encode a HyBi style WebSocket frame.
+        Optional opcode:
+            0x0 - continuation
+            0x1 - text frame (base64 encode buf)
+            0x2 - binary frame (use raw buf)
+            0x8 - connection close
+            0x9 - ping
+            0xA - pong
+        """
+        if base64:
+            buf = b64encode(buf)
+
+        b1 = 0x80 | (opcode & 0x0f) # FIN + opcode
+        payload_len = len(buf)
+        if payload_len <= 125:
+            header = pack('>BB', b1, payload_len)
+        elif payload_len > 125 and payload_len < 65536:
+            header = pack('>BBH', b1, 126, payload_len)
+        elif payload_len >= 65536:
+            header = pack('>BBQ', b1, 127, payload_len)
+
+        #print("Encoded: %s" % repr(header + buf))
+
+        return header + buf, len(header), 0
+
+    @staticmethod
+    def decode_hybi(buf, base64=False):
+        """ Decode HyBi style WebSocket packets.
+        Returns:
+            {'fin'          : 0_or_1,
+             'opcode'       : number,
+             'mask'         : 32_bit_number,
+             'hlen'         : header_bytes_number,
+             'length'       : payload_bytes_number,
+             'payload'      : decoded_buffer,
+             'left'         : bytes_left_number,
+             'close_code'   : number,
+             'close_reason' : string}
+        """
+
+        f = {'fin'          : 0,
+             'opcode'       : 0,
+             'mask'         : 0,
+             'hlen'         : 2,
+             'length'       : 0,
+             'payload'      : None,
+             'left'         : 0,
+             'close_code'   : None,
+             'close_reason' : None}
+
+        blen = len(buf)
+        f['left'] = blen
+
+        if blen < f['hlen']:
+            return f # Incomplete frame header
+
+        b1, b2 = unpack_from(">BB", buf)
+        f['opcode'] = b1 & 0x0f
+        f['fin'] = (b1 & 0x80) >> 7
+        has_mask = (b2 & 0x80) >> 7
+
+        f['length'] = b2 & 0x7f
+
+        if f['length'] == 126:
+            f['hlen'] = 4
+            if blen < f['hlen']:
+                return f # Incomplete frame header
+            (f['length'],) = unpack_from('>xxH', buf)
+        elif f['length'] == 127:
+            f['hlen'] = 10
+            if blen < f['hlen']:
+                return f # Incomplete frame header
+            (f['length'],) = unpack_from('>xxQ', buf)
+
+        full_len = f['hlen'] + has_mask * 4 + f['length']
+
+        if blen < full_len: # Incomplete frame
+            return f # Incomplete frame header
+
+        # Number of bytes that are part of the next frame(s)
+        f['left'] = blen - full_len
+
+        # Process 1 frame
+        if has_mask:
+            # unmask payload
+            f['mask'] = buf[f['hlen']:f['hlen']+4]
+            f['payload'] = WebSocketServer.unmask(buf, f)
+        else:
+            print("Unmasked frame: %s" % repr(buf))
+            f['payload'] = buf[(f['hlen'] + has_mask * 4):full_len]
+
+        if base64 and f['opcode'] in [1, 2]:
+            try:
+                f['payload'] = b64decode(f['payload'])
+            except:
+                print("Exception while b64decoding buffer: %s" %
+                        repr(buf))
+                raise
+
+        if f['opcode'] == 0x08:
+            if f['length'] >= 2:
+                f['close_code'] = unpack_from(">H", f['payload'])
+            if f['length'] > 3:
+                f['close_reason'] = f['payload'][2:]
+
+        return f
+
+    @staticmethod
+    def encode_hixie(buf):
+        return s2b("\x00" + b2s(b64encode(buf)) + "\xff"), 1, 1
+
+    @staticmethod
+    def decode_hixie(buf):
+        end = buf.find(s2b('\xff'))
+        return {'payload': b64decode(buf[1:end]),
+                'hlen': 1,
+                'length': end - 1,
+                'left': len(buf) - (end + 1)}
+
+
+    @staticmethod
+    def gen_md5(keys):
+        """ Generate hash value for WebSockets hixie-76. """
+        key1 = keys['Sec-WebSocket-Key1']
+        key2 = keys['Sec-WebSocket-Key2']
+        key3 = keys['key3']
+        spaces1 = key1.count(" ")
+        spaces2 = key2.count(" ")
+        num1 = int("".join([c for c in key1 if c.isdigit()])) / spaces1
+        num2 = int("".join([c for c in key2 if c.isdigit()])) / spaces2
+
+        return b2s(md5(pack('>II8s',
+            int(num1), int(num2), key3)).digest())
+
+    #
+    # WebSocketServer logging/output functions
+    #
+
+    def traffic(self, token="."):
+        """ Show traffic flow in verbose mode. """
+        if self.verbose and not self.daemon:
+            sys.stdout.write(token)
+            sys.stdout.flush()
+
+    def msg(self, msg):
+        """ Output message with handler_id prefix. """
+        if not self.daemon:
+            print("% 3d: %s" % (self.handler_id, msg))
+
+    def vmsg(self, msg):
+        """ Same as msg() but only if verbose. """
+        if self.verbose:
+            self.msg(msg)
+
+    #
+    # Main WebSocketServer methods
+    #
+    def send_frames(self, bufs=None):
+        """ Encode and send WebSocket frames. Any frames already
+        queued will be sent first. If buf is not set then only queued
+        frames will be sent. Returns the number of pending frames that
+        could not be fully sent. If returned pending frames is greater
+        than 0, then the caller should call again when the socket is
+        ready. """
+
+        tdelta = int(time.time()*1000) - self.start_time
+
+        if bufs:
+            for buf in bufs:
+                if self.version.startswith("hybi"):
+                    if self.base64:
+                        encbuf, lenhead, lentail = self.encode_hybi(
+                                buf, opcode=1, base64=True)
+                    else:
+                        encbuf, lenhead, lentail = self.encode_hybi(
+                                buf, opcode=2, base64=False)
+
+                else:
+                    encbuf, lenhead, lentail = self.encode_hixie(buf)
+
+                if self.rec:
+                    self.rec.write("%s,\n" %
+                            repr("{%s{" % tdelta
+                                + encbuf[lenhead:-lentail]))
+
+                self.send_parts.append(encbuf)
+
+        while self.send_parts:
+            # Send pending frames
+            buf = self.send_parts.pop(0)
+            sent = self.client.send(buf)
+
+            if sent == len(buf):
+                self.traffic("<")
+            else:
+                self.traffic("<.")
+                self.send_parts.insert(0, buf[sent:])
+                break
+
+        return len(self.send_parts)
+
+    def recv_frames(self):
+        """ Receive and decode WebSocket frames.
+
+        Returns:
+            (bufs_list, closed_string)
+        """
+
+        closed = False
+        bufs = []
+        tdelta = int(time.time()*1000) - self.start_time
+
+        buf = self.client.recv(self.buffer_size)
+        if len(buf) == 0:
+            closed = "Client closed abruptly"
+            return bufs, closed
+
+        if self.recv_part:
+            # Add partially received frames to current read buffer
+            buf = self.recv_part + buf
+            self.recv_part = None
+
+        while buf:
+            if self.version.startswith("hybi"):
+
+                frame = self.decode_hybi(buf, base64=self.base64)
+                #print("Received buf: %s, frame: %s" % (repr(buf), frame))
+
+                if frame['payload'] == None:
+                    # Incomplete/partial frame
+                    self.traffic("}.")
+                    if frame['left'] > 0:
+                        self.recv_part = buf[-frame['left']:]
+                    break
+                else:
+                    if frame['opcode'] == 0x8: # connection close
+                        closed = "Client closed, reason: %s - %s" % (
+                                frame['close_code'],
+                                frame['close_reason'])
+                        break
+
+            else:
+                if buf[0:2] == s2b('\xff\x00'):
+                    closed = "Client sent orderly close frame"
+                    break
+
+                elif buf[0:2] == s2b('\x00\xff'):
+                    buf = buf[2:]
+                    continue # No-op
+
+                elif buf.count(s2b('\xff')) == 0:
+                    # Partial frame
+                    self.traffic("}.")
+                    self.recv_part = buf
+                    break
+
+                frame = self.decode_hixie(buf)
+
+            self.traffic("}")
+
+            if self.rec:
+                start = frame['hlen']
+                end = frame['hlen'] + frame['length']
+                self.rec.write("%s,\n" %
+                        repr("}%s}" % tdelta + buf[start:end]))
+
+
+            bufs.append(frame['payload'])
+
+            if frame['left']:
+                buf = buf[-frame['left']:]
+            else:
+                buf = ''
+
+        return bufs, closed
+
+    def send_close(self, code=None, reason=''):
+        """ Send a WebSocket orderly close frame. """
+
+        if self.version.startswith("hybi"):
+            msg = s2b('')
+            if code != None:
+                msg = pack(">H%ds" % (len(reason)), code)
+
+            buf, h, t = self.encode_hybi(msg, opcode=0x08, base64=False)
+            self.client.send(buf)
+
+        elif self.version == "hixie-76":
+            buf = s2b('\xff\x00')
+            self.client.send(buf)
+
+        # No orderly close for 75
+
+    def do_handshake(self, sock, address):
+        """
+        do_handshake does the following:
+        - Peek at the first few bytes from the socket.
+        - If the connection is Flash policy request then answer it,
+          close the socket and return.
+        - If the connection is an HTTPS/SSL/TLS connection then SSL
+          wrap the socket.
+        - Read from the (possibly wrapped) socket.
+        - If we have received a HTTP GET request and the webserver
+          functionality is enabled, answer it, close the socket and
+          return.
+        - Assume we have a WebSockets connection, parse the client
+          handshake data.
+        - Send a WebSockets handshake server response.
+        - Return the socket for this WebSocket client.
+        """
+
+        stype = ""
+
+        ready = select.select([sock], [], [], 3)[0]
+        if not ready:
+            raise self.EClose("ignoring socket not ready")
+        # Peek, but do not read the data so that we have a opportunity
+        # to SSL wrap the socket first
+        handshake = sock.recv(1024, socket.MSG_PEEK)
+        #self.msg("Handshake [%s]" % handshake)
+
+        if handshake == "":
+            raise self.EClose("ignoring empty handshake")
+
+        elif handshake.startswith(s2b("<policy-file-request/>")):
+            # Answer Flash policy request
+            handshake = sock.recv(1024)
+            sock.send(s2b(self.policy_response))
+            raise self.EClose("Sending flash policy response")
+
+        elif handshake[0] in ("\x16", "\x80", 22, 128):
+            # SSL wrap the connection
+            if not ssl:
+                raise self.EClose("SSL connection but no 'ssl' module")
+            if not os.path.exists(self.cert):
+                raise self.EClose("SSL connection but '%s' not found"
+                                  % self.cert)
+            retsock = None
+            try:
+                retsock = ssl.wrap_socket(
+                        sock,
+                        server_side=True,
+                        certfile=self.cert,
+                        keyfile=self.key)
+            except ssl.SSLError:
+                _, x, _ = sys.exc_info()
+                if x.args[0] == ssl.SSL_ERROR_EOF:
+                    if len(x.args) > 1:
+                        raise self.EClose(x.args[1])
+                    else:
+                        raise self.EClose("Got SSL_ERROR_EOF")
+                else:
+                    raise
+
+            scheme = "wss"
+            stype = "SSL/TLS (wss://)"
+
+        elif self.ssl_only:
+            raise self.EClose("non-SSL connection received but disallowed")
+
+        else:
+            retsock = sock
+            scheme = "ws"
+            stype = "Plain non-SSL (ws://)"
+
+        wsh = WSRequestHandler(retsock, address, not self.web)
+        if wsh.last_code == 101:
+            # Continue on to handle WebSocket upgrade
+            pass
+        elif wsh.last_code == 405:
+            raise self.EClose("Normal web request received but disallowed")
+        elif wsh.last_code < 200 or wsh.last_code >= 300:
+            raise self.EClose(wsh.last_message)
+        elif self.verbose:
+            raise self.EClose(wsh.last_message)
+        else:
+            raise self.EClose("")
+
+        h = self.headers = wsh.headers
+        path = self.path = wsh.path
+
+        prot = 'WebSocket-Protocol'
+        protocols = h.get('Sec-'+prot, h.get(prot, '')).split(',')
+
+        ver = h.get('Sec-WebSocket-Version')
+        if ver:
+            # HyBi/IETF version of the protocol
+
+            # HyBi-07 report version 7
+            # HyBi-08 - HyBi-12 report version 8
+            # HyBi-13 reports version 13
+            if ver in ['7', '8', '13']:
+                self.version = "hybi-%02d" % int(ver)
+            else:
+                raise self.EClose('Unsupported protocol version %s' % ver)
+
+            key = h['Sec-WebSocket-Key']
+
+            # Choose binary if client supports it
+            if 'binary' in protocols:
+                self.base64 = False
+            elif 'base64' in protocols:
+                self.base64 = True
+            else:
+                raise self.EClose("Client must support 'binary' or 'base64' protocol")
+
+            # Generate the hash value for the accept header
+            accept = b64encode(sha1(s2b(key + self.GUID)).digest())
+
+            response = self.server_handshake_hybi % b2s(accept)
+            if self.base64:
+                response += "Sec-WebSocket-Protocol: base64\r\n"
+            else:
+                response += "Sec-WebSocket-Protocol: binary\r\n"
+            response += "\r\n"
+
+        else:
+            # Hixie version of the protocol (75 or 76)
+
+            if h.get('key3'):
+                trailer = self.gen_md5(h)
+                pre = "Sec-"
+                self.version = "hixie-76"
+            else:
+                trailer = ""
+                pre = ""
+                self.version = "hixie-75"
+
+            # We only support base64 in Hixie era
+            self.base64 = True
+
+            response = self.server_handshake_hixie % (pre,
+                    h['Origin'], pre, scheme, h['Host'], path)
+
+            if 'base64' in protocols:
+                response += "%sWebSocket-Protocol: base64\r\n" % pre
+            else:
+                self.msg("Warning: client does not report 'base64' protocol support")
+            response += "\r\n" + trailer
+
+        self.msg("%s: %s WebSocket connection" % (address[0], stype))
+        self.msg("%s: Version %s, base64: '%s'" % (address[0],
+            self.version, self.base64))
+        if self.path != '/':
+            self.msg("%s: Path: '%s'" % (address[0], self.path))
+
+
+        # Send server WebSockets handshake response
+        #self.msg("sending response [%s]" % response)
+        retsock.send(s2b(response))
+
+        # Return the WebSockets socket which may be SSL wrapped
+        return retsock
+
+
+    #
+    # Events that can/should be overridden in sub-classes
+    #
+    def started(self):
+        """ Called after WebSockets startup """
+        self.vmsg("WebSockets server started")
+
+    def poll(self):
+        """ Run periodically while waiting for connections. """
+        #self.vmsg("Running poll()")
+        pass
+
+    def fallback_SIGCHLD(self, sig, stack):
+        # Reap zombies when using os.fork() (python 2.4)
+        self.vmsg("Got SIGCHLD, reaping zombies")
+        try:
+            result = os.waitpid(-1, os.WNOHANG)
+            while result[0]:
+                self.vmsg("Reaped child process %s" % result[0])
+                result = os.waitpid(-1, os.WNOHANG)
+        except (OSError):
+            pass
+
+    def do_SIGINT(self, sig, stack):
+        self.msg("Got SIGINT, exiting")
+        sys.exit(0)
+
+    def top_new_client(self, startsock, address):
+        """ Do something with a WebSockets client connection. """
+        # Initialize per client settings
+        self.send_parts = []
+        self.recv_part  = None
+        self.base64     = False
+        self.rec        = None
+        self.start_time = int(time.time()*1000)
+
+        # handler process
+        try:
+            try:
+                self.client = self.do_handshake(startsock, address)
+
+                if self.record:
+                    # Record raw frame data as JavaScript array
+                    fname = "%s.%s" % (self.record,
+                                        self.handler_id)
+                    self.msg("opening record file: %s" % fname)
+                    self.rec = open(fname, 'w+')
+                    self.rec.write("var VNC_frame_data = [\n")
+
+                self.ws_connection = True
+                self.new_client()
+            except self.EClose:
+                _, exc, _ = sys.exc_info()
+                # Connection was not a WebSockets connection
+                if exc.args[0]:
+                    self.msg("%s: %s" % (address[0], exc.args[0]))
+            except Exception:
+                _, exc, _ = sys.exc_info()
+                self.msg("handler exception: %s" % str(exc))
+                if self.verbose:
+                    self.msg(traceback.format_exc())
+        finally:
+            if self.rec:
+                self.rec.write("'EOF']\n")
+                self.rec.close()
+
+            if self.client and self.client != startsock:
+                self.client.close()
+
+    def new_client(self):
+        """ Do something with a WebSockets client connection. """
+        raise("WebSocketServer.new_client() must be overloaded")
+
+    def start_server(self):
+        """
+        Daemonize if requested. Listen for for connections. Run
+        do_handshake() method for each connection. If the connection
+        is a WebSockets client then call new_client() method (which must
+        be overridden) for each new client connection.
+        """
+        lsock = self.socket(self.listen_host, self.listen_port)
+
+        if self.daemon:
+            self.daemonize(keepfd=lsock.fileno(), chdir=self.web)
+
+        self.started()  # Some things need to happen after daemonizing
+
+        # Allow override of SIGINT
+        signal.signal(signal.SIGINT, self.do_SIGINT)
+        if not multiprocessing:
+            # os.fork() (python 2.4) child reaper
+            signal.signal(signal.SIGCHLD, self.fallback_SIGCHLD)
+
+        while True:
+            try:
+                try:
+                    self.client = None
+                    startsock = None
+                    pid = err = 0
+
+                    time_elapsed = time.time() - self.launch_time
+                    if self.timeout and time_elapsed > self.timeout:
+                        self.msg('listener exit due to --timeout %s'
+                                % self.timeout)
+                        break
+
+                    try:
+                        self.poll()
+
+                        ready = select.select([lsock], [], [], 1)[0]
+                        if lsock in ready:
+                            startsock, address = lsock.accept()
+                        else:
+                            continue
+                    except Exception:
+                        _, exc, _ = sys.exc_info()
+                        if hasattr(exc, 'errno'):
+                            err = exc.errno
+                        elif hasattr(exc, 'args'):
+                            err = exc.args[0]
+                        else:
+                            err = exc[0]
+                        if err == errno.EINTR:
+                            self.vmsg("Ignoring interrupted syscall")
+                            continue
+                        else:
+                            raise
+
+                    if self.run_once:
+                        # Run in same process if run_once
+                        self.top_new_client(startsock, address)
+                        if self.ws_connection :
+                            self.msg('%s: exiting due to --run-once'
+                                    % address[0])
+                            break
+                    elif multiprocessing:
+                        self.vmsg('%s: new handler Process' % address[0])
+                        p = multiprocessing.Process(
+                                target=self.top_new_client,
+                                args=(startsock, address))
+                        p.start()
+                        # child will not return
+                    else:
+                        # python 2.4
+                        self.vmsg('%s: forking handler' % address[0])
+                        pid = os.fork()
+                        if pid == 0:
+                            # child handler process
+                            self.top_new_client(startsock, address)
+                            break  # child process exits
+
+                    # parent process
+                    self.handler_id += 1
+
+                except KeyboardInterrupt:
+                    _, exc, _ = sys.exc_info()
+                    print("In KeyboardInterrupt")
+                    pass
+                except SystemExit:
+                    _, exc, _ = sys.exc_info()
+                    print("In SystemExit")
+                    break
+                except Exception:
+                    _, exc, _ = sys.exc_info()
+                    self.msg("handler exception: %s" % str(exc))
+                    if self.verbose:
+                        self.msg(traceback.format_exc())
+
+            finally:
+                if startsock:
+                    startsock.close()
+
+
+# HTTP handler with WebSocket upgrade support
+class WSRequestHandler(SimpleHTTPRequestHandler):
+    def __init__(self, req, addr, only_upgrade=False):
+        self.only_upgrade = only_upgrade # only allow upgrades
+        SimpleHTTPRequestHandler.__init__(self, req, addr, object())
+
+    def do_GET(self):
+        if (self.headers.get('upgrade') and
+                self.headers.get('upgrade').lower() == 'websocket'):
+
+            if (self.headers.get('sec-websocket-key1') or
+                    self.headers.get('websocket-key1')):
+                # For Hixie-76 read out the key hash
+                self.headers.__setitem__('key3', self.rfile.read(8))
+
+            # Just indicate that an WebSocket upgrade is needed
+            self.last_code = 101
+            self.last_message = "101 Switching Protocols"
+        elif self.only_upgrade:
+            # Normal web request responses are disabled
+            self.last_code = 405
+            self.last_message = "405 Method Not Allowed"
+        else:
+            if not re.match('^\/((images|include|include\/web-socket-js)\/)?[a-zA-Z0-9_]+\.[a-zA-Z0-9_]+(\?.*)?$', self.path):
+                self.last_code = 400 
+                self.last_message = "400 Bad Request"
+                SimpleHTTPRequestHandler.send_response(self,self.last_code,self.last_message)
+            else:
+                SimpleHTTPRequestHandler.do_GET(self)
+
+    def send_response(self, code, message=None):
+        # Save the status code
+        self.last_code = code
+        SimpleHTTPRequestHandler.send_response(self, code, message)
+
+    def log_message(self, f, *args):
+        # Save instead of printing
+        self.last_message = f % args
+

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a0571d1e/patches/systemvm/debian/config/root/lswcp/utils/websockify
----------------------------------------------------------------------
diff --git a/patches/systemvm/debian/config/root/lswcp/utils/websockify b/patches/systemvm/debian/config/root/lswcp/utils/websockify
new file mode 100644
index 0000000..497d550
--- /dev/null
+++ b/patches/systemvm/debian/config/root/lswcp/utils/websockify
@@ -0,0 +1,206 @@
+#!/usr/bin/env python
+
+'''
+A WebSocket to TCP socket proxy with support for "wss://" encryption.
+Copyright 2011 Joel Martin
+Licensed under LGPL version 3 (see docs/LICENSE.LGPL-3)
+
+You can make a cert/key with openssl using:
+openssl req -new -x509 -days 365 -nodes -out self.pem -keyout self.pem
+as taken from http://docs.python.org/dev/library/ssl.html#certificates
+
+'''
+
+import socket, optparse, time, os, sys, subprocess
+from  rijndael_lsw import decrypt
+from select import select
+from websocket import WebSocketServer
+from hashlib import sha256
+from time import time
+try:    from urllib.parse import unquote_plus
+except: from urllib import unquote_plus
+
+class WebSocketProxy(WebSocketServer):
+    """
+    Proxy traffic to and from a WebSockets client to a normal TCP
+    socket server target. All traffic to/from the client is base64
+    encoded/decoded to allow binary data to be sent/received to/from
+    the target.
+    """
+
+    buffer_size = 65536
+
+    traffic_legend = """
+Traffic Legend:
+    }  - Client receive
+    }. - Client receive partial
+    {  - Target receive
+
+    >  - Target send
+    >. - Target send partial
+    <  - Client send
+    <. - Client send partial
+"""
+
+    def started(self):
+        """
+        Called after Websockets server startup (i.e. after daemonize)
+        """
+        print("  - proxy listenin on %s:%s\n" % (
+                self.listen_host, self.listen_port))
+
+    # 
+    # Routines above this point are run in the master listener
+    # process.
+    #
+
+    #
+    # Routines below this point are connection handler routines and
+    # will be run in a separate forked process for each connection.
+    #
+
+    def new_client(self):
+        """
+        Called after a new WebSocket connection has been established.
+        """
+        self.key = 'daP8TeiMJierui9euug7aiTi'
+        arguments = decrypt(self.key, self.path.lstrip('/'))
+        arguments, signature = arguments.split('|')
+        self.target_host, self.target_port, self.client_ip, self.timestamp = arguments.rsplit(':', 3)
+        
+        # Check signature
+        if sha256(self.key+arguments).hexdigest() != signature:
+            self.send_close()
+            raise self.EClose('Not accepted: Invalid signature')
+        # Check client ip address
+        if self.client_ip != self.client.getpeername()[0]:
+            self.send_close()
+            raise self.EClose('Not accepted: Invalid client ip address')
+        # Check timestamp
+        if self.timestamp < time()-300:
+            self.send_close()
+            raise self.EClose('Not accepted: Timestamp older than 5 minutes')
+       
+        # Connect to the target
+        self.msg("connecting to: %s:%s" % (self.target_host, self.target_port))
+        tsock = self.socket(self.target_host, self.target_port,
+                connect=True)
+
+        if self.verbose and not self.daemon:
+            print(self.traffic_legend)
+
+        # Start proxying
+        try:
+            self.do_proxy(tsock)
+        except:
+            if tsock:
+                tsock.shutdown(socket.SHUT_RDWR)
+                tsock.close()
+                self.vmsg("%s:%s: Target closed" % (self.target_host, self.target_port))
+            raise
+
+    def do_proxy(self, target):
+        """
+        Proxy client WebSocket to normal target socket.
+        """
+        
+        cqueue = []
+        c_pend = 0
+        tqueue = []
+        rlist = [self.client, target]
+
+        while True:
+            wlist = []
+
+            if tqueue: wlist.append(target)
+            if cqueue or c_pend: wlist.append(self.client)
+            ins, outs, excepts = select(rlist, wlist, [], 1)
+            if excepts: raise Exception("Socket exception")
+
+            if target in outs:
+                # Send queued client data to the target
+                dat = tqueue.pop(0)
+                sent = target.send(dat)
+                if sent == len(dat):
+                    self.traffic(">")
+                else:
+                    # requeue the remaining data
+                    tqueue.insert(0, dat[sent:])
+                    self.traffic(".>")
+
+
+            if target in ins:
+                # Receive target data, encode it and queue for client
+                buf = target.recv(self.buffer_size)
+                if len(buf) == 0: raise self.EClose("Target closed")
+
+                cqueue.append(buf)
+                self.traffic("{")
+
+
+            if self.client in outs:
+                # Send queued target data to the client
+                c_pend = self.send_frames(cqueue)
+
+                cqueue = []
+
+
+            if self.client in ins:
+                # Receive client data, decode it, and queue for target
+                bufs, closed = self.recv_frames()
+                tqueue.extend(bufs)
+
+                if closed:
+                    # TODO: What about blocking on client socket?
+                    self.send_close()
+                    raise self.EClose(closed)
+
+if __name__ == '__main__':
+    usage = "\n    %prog [options]"
+    usage += " [source_addr:]source_port"
+    usage += "\n    %prog [options]"
+    usage += " [source_addr:]source_port -- WRAP_COMMAND_LINE"
+    parser = optparse.OptionParser(usage=usage)
+    parser.add_option("--verbose", "-v", action="store_true",
+            help="verbose messages and per frame traffic")
+    parser.add_option("--record",
+            help="record sessions to FILE.[session_number]", metavar="FILE")
+    parser.add_option("--daemon", "-D",
+            dest="daemon", action="store_true",
+            help="become a daemon (background process)")
+    parser.add_option("--run-once", action="store_true",
+            help="handle a single WebSocket connection and exit")
+    parser.add_option("--timeout", type=int, default=0,
+            help="after TIMEOUT seconds exit when not connected")
+    parser.add_option("--cert", default="self.pem",
+            help="SSL certificate file")
+    parser.add_option("--key", default=None,
+            help="SSL key file (if separate from cert)")
+    parser.add_option("--ssl-only", action="store_true",
+            help="disallow non-encrypted connections")
+    parser.add_option("--web", default=None, metavar="DIR",
+            help="run webserver on same port. Serve files from DIR.")
+    (opts, args) = parser.parse_args()
+
+    # Sanity checks
+    if len(args) < 1:
+        parser.error("Too few arguments")
+    else:
+        if len(args) > 1:
+            parser.error("Too many arguments")
+
+    if opts.ssl_only and not os.path.exists(opts.cert):
+        parser.error("SSL only and %s not found" % opts.cert)
+
+    # Parse host:port and convert ports to numbers
+    if args[0].count(':') > 0:
+        opts.listen_host, opts.listen_port = args[0].rsplit(':', 1)
+    else:
+        opts.listen_host, opts.listen_port = '', args[0]
+
+    try:    opts.listen_port = int(opts.listen_port)
+    except: parser.error("Error parsing listen port")
+
+    # Create and start the WebSockets proxy
+    server = WebSocketProxy(**opts.__dict__)
+    server.start_server()

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a0571d1e/patches/systemvm/debian/config/root/lswcp/utils/websockify.py
----------------------------------------------------------------------
diff --git a/patches/systemvm/debian/config/root/lswcp/utils/websockify.py b/patches/systemvm/debian/config/root/lswcp/utils/websockify.py
new file mode 100644
index 0000000..05b5af4
--- /dev/null
+++ b/patches/systemvm/debian/config/root/lswcp/utils/websockify.py
@@ -0,0 +1 @@
+websockify
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a0571d1e/patches/systemvm/debian/config/root/lswcp/utils/wsproxy.py
----------------------------------------------------------------------
diff --git a/patches/systemvm/debian/config/root/lswcp/utils/wsproxy.py b/patches/systemvm/debian/config/root/lswcp/utils/wsproxy.py
new file mode 100644
index 0000000..05b5af4
--- /dev/null
+++ b/patches/systemvm/debian/config/root/lswcp/utils/wsproxy.py
@@ -0,0 +1 @@
+websockify
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a0571d1e/patches/systemvm/debian/config/root/lswcp/vnc.html
----------------------------------------------------------------------
diff --git a/patches/systemvm/debian/config/root/lswcp/vnc.html b/patches/systemvm/debian/config/root/lswcp/vnc.html
new file mode 100644
index 0000000..b6cf85b
--- /dev/null
+++ b/patches/systemvm/debian/config/root/lswcp/vnc.html
@@ -0,0 +1,198 @@
+<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.1//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile11.dtd">
+<html>
+<head>
+
+   <!--
+    noVNC example: simple example using default UI
+    Copyright (C) 2011 Joel Martin
+    Licensed under LGPL-3 (see LICENSE.txt)
+    -->
+    <title>noVNC</title>
+
+    <meta charset="utf-8">
+
+    <!-- Always force latest IE rendering engine (even in intranet) & Chrome Frame
+                Remove this if you use the .htaccess -->
+    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+
+    <!-- Apple iOS Safari settings -->
+    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+    <meta name="apple-mobile-web-app-capable" content="yes" />
+    <meta names="apple-mobile-web-app-status-bar-style" content="black-translucent" />
+    <!-- App Start Icon  -->
+    <link rel="apple-touch-startup-image" href="images/screen_320x460.png" />
+    <!-- For iOS devices set the icon to use if user bookmarks app on their homescreen -->
+    <link rel="apple-touch-icon" href="images/screen_57x57.png">
+    <!--
+    <link rel="apple-touch-icon-precomposed" href="images/screen_57x57.png" />
+    -->
+
+
+    <!-- Stylesheets -->
+    <link rel="stylesheet" href="include/base.css" />
+    <link rel="alternate stylesheet" href="include/black.css" TITLE="Black" />
+    <link rel="alternate stylesheet" href="include/blue.css" TITLE="Blue" />
+
+    <!--
+    <script type='text/javascript'
+        src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script>
+    -->
+
+    <script src="include/vnc.js"></script>
+    <script src="include/ui.js"></script>
+
+</head>
+
+<body>
+    <div id="noVNC-control-bar">
+        <!--noVNC Mobile Device only Buttons-->
+        <div class="noVNC-buttons-left">
+            <input type="image" src="images/drag.png"
+                id="noVNC_view_drag_button" class="noVNC_status_button"
+                title="Move/Drag Viewport"
+                onclick="UI.setViewDrag();">
+            <div id="noVNC_mobile_buttons">
+                <input type="image" src="images/mouse_none.png"
+                    id="noVNC_mouse_button0" class="noVNC_status_button"
+                    onclick="UI.setMouseButton(1);">
+                <input type="image" src="images/mouse_left.png"
+                    id="noVNC_mouse_button1" class="noVNC_status_button"
+                    onclick="UI.setMouseButton(2);">
+                <input type="image" src="images/mouse_middle.png"
+                    id="noVNC_mouse_button2" class="noVNC_status_button"
+                    onclick="UI.setMouseButton(4);">
+                <input type="image" src="images/mouse_right.png"
+                    id="noVNC_mouse_button4" class="noVNC_status_button"
+                    onclick="UI.setMouseButton(0);">
+                <input type="image" src="images/keyboard.png"
+                    id="showKeyboard" class="noVNC_status_button"
+                    value="Keyboard" title="Show Keyboard"
+                    onclick="UI.showKeyboard()"/>
+                <input type="email"
+                    autocapitalize="off" autocorrect="off"
+                    id="keyboardinput" class="noVNC_status_button"
+                    onKeyDown="onKeyDown(event);" onblur="UI.keyInputBlur();"/>
+            </div>
+        </div>
+
+        <!--noVNC Buttons-->
+        <div class="noVNC-buttons-right">
+            <input type="image" src="images/ctrlaltdel.png"
+                 id="sendCtrlAltDelButton" class="noVNC_status_button"
+                title="Send Ctrl-Alt-Del"
+                onclick="UI.sendCtrlAltDel();" />
+            <input type="image" src="images/clipboard.png"
+                id="clipboardButton" class="noVNC_status_button"
+                title="Clipboard"
+                onclick="UI.toggleClipboardPanel();" />
+            <input type="image" src="images/settings.png"
+                id="settingsButton" class="noVNC_status_button"
+                title="Settings"
+                onclick="UI.toggleSettingsPanel();" />
+            <input type="image" src="images/connect.png"
+                id="connectButton" class="noVNC_status_button"
+                title="Connect"
+                onclick="UI.toggleConnectPanel()" />
+            <input type="image" src="images/disconnect.png"
+                id="disconnectButton" class="noVNC_status_button"
+                title="Disconnect"
+                onclick="UI.disconnect()" />
+        </div>
+
+        <!-- Description Panel -->
+        <!-- Shown by default when hosted at for kanaka.github.com -->
+        <div id="noVNC_description" style="display:none;" class="">
+            noVNC is a browser based VNC client implemented using HTML5 Canvas
+            and WebSockets. You will either need a VNC server with WebSockets
+            support (such as <a href="http://libvncserver.sourceforge.net/">libvncserver</a>)
+            or you will need to use
+            <a href="https://github.com/kanaka/websockify">websockify</a>
+            to bridge between your browser and VNC server. See the noVNC
+            <a href="https://github.com/kanaka/noVNC">README</a>
+            and <a href="http://kanaka.github.com/noVNC">website</a>
+            for more information.
+            <br />
+            <input type="button" value="Close"
+                onclick="UI.toggleConnectPanel();">
+        </div>
+
+        <!-- Clipboard Panel -->
+        <div id="noVNC_clipboard" class="triangle-right top">
+            <textarea id="noVNC_clipboard_text" rows=5
+                onfocus="UI.displayBlur();" onblur="UI.displayFocus();"
+                onchange="UI.clipSend();">
+            </textarea>
+            <br />
+            <input id="noVNC_clipboard_clear_button" type="button"
+                value="Clear" onclick="UI.clipClear();">
+        </div>
+
+        <!-- Settings Panel -->
+        <div id="noVNC_settings" class="triangle-right top">
+            <span id="noVNC_settings_menu" onmouseover="UI.displayBlur();"
+                                           onmouseout="UI.displayFocus();">
+                <ul>
+                    <li><input id="noVNC_encrypt" type="checkbox"> Encrypt</li>
+                    <li><input id="noVNC_true_color" type="checkbox" checked> True Color</li>
+                    <li><input id="noVNC_cursor" type="checkbox"> Local Cursor</li>
+                    <li><input id="noVNC_clip" type="checkbox"> Clip to Window</li>
+                    <li><input id="noVNC_shared" type="checkbox"> Shared Mode</li>
+                    <li><input id="noVNC_view_only" type="checkbox"> View Only</li>
+                    <li><input id="noVNC_connectTimeout" type="input"> Connect Timeout (s)</li>
+                    <li><input id="noVNC_path" type="input" value="websockify"> Path</li>
+                    <hr>
+                    <!-- Stylesheet selection dropdown -->
+                    <li><label><strong>Style: </strong>
+                        <select id="noVNC_stylesheet" name="vncStyle">
+                            <option value="default">default</option>
+                        </select></label>
+                    </li>
+
+                    <!-- Logging selection dropdown -->
+                    <li><label><strong>Logging: </strong>
+                        <select id="noVNC_logging" name="vncLogging">
+                        </select></label>
+                    </li>
+                    <hr>
+                    <li><input type="button" id="noVNC_apply" value="Apply"
+                         onclick="UI.settingsApply()"></li>
+                </ul>
+            </span>
+        </div>
+
+        <!-- Connection Panel -->
+        <div id="noVNC_controls" class="triangle-right top">
+            <ul>
+                <li><label><strong>Host: </strong><input id="noVNC_host" /></label></li>
+                <li><label><strong>Port: </strong><input id="noVNC_port" /></label></li>
+                <li><label><strong>Password: </strong><input id="noVNC_password" type="password" /></label></li>
+                <li><input id="noVNC_connect_button" type="button" value="Connect" onclick="UI.connect();"></li>
+            </ul>
+        </div>
+
+    </div> <!-- End of noVNC-control-bar -->
+
+
+    <div id="noVNC_screen">
+        <div id="noVNC_screen_pad"></div>
+
+        <div id="noVNC_status_bar" class="noVNC_status_bar">
+                <div id="noVNC_status">Loading</div>
+        </div>
+
+        <h1 id="noVNC_logo"><span>no</span><br />VNC</h1>
+
+        <!-- HTML5 Canvas -->
+        <div id="noVNC_container">
+            <canvas id="noVNC_canvas" width="640px" height="20px">
+                        Canvas not supported.
+            </canvas>
+        </div>
+
+    </div>
+
+    <script>
+        window.onload = UI.load;
+    </script>
+ </body>
+</html>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a0571d1e/patches/systemvm/debian/config/root/lswcp/vnc_auto.html
----------------------------------------------------------------------
diff --git a/patches/systemvm/debian/config/root/lswcp/vnc_auto.html b/patches/systemvm/debian/config/root/lswcp/vnc_auto.html
new file mode 100644
index 0000000..2c0c962
--- /dev/null
+++ b/patches/systemvm/debian/config/root/lswcp/vnc_auto.html
@@ -0,0 +1,120 @@
+<!DOCTYPE html>
+<html>
+    <!-- 
+    noVNC Example: Automatically connect on page load.
+    Copyright (C) 2011 Joel Martin
+    Licensed under LGPL-3 (see LICENSE.txt)
+
+    Connect parameters are provided in query string:
+        http://example.com/?host=HOST&port=PORT&encrypt=1&true_color=1
+    -->
+    <head>
+        <title>noVNC</title>
+        <meta http-equiv="X-UA-Compatible" content="chrome=1">
+        <link rel="stylesheet" href="include/base.css" title="plain">
+        <link href="include/bootstrap.css" rel="stylesheet">
+        <script src="include/vnc.js"></script>
+        <script src="include/keymap.js"></script>
+        <script type="text/javascript">
+          window.addEventListener('load', function () { document.getElementById('noVNC_focus').focus(); } );
+        </script>
+    </head>
+
+    <body style="margin: 0px;">
+        <div id="noVNC_screen">
+            <input id="noVNC_focus" style="position:absolute; top:-1000px;"/>
+            <div id="noVNC_status_bar" class="noVNC_status_bar" style="margin-top: 0px;">
+                <div id="noVNC_buttons">
+                  <a href="#" onClick="return false;" class="btn" id="clipboardButton">Clipboard</a> 
+                  <a href="#" onClick="return false;" class="btn" id="sendCtrlAltDelButton">CtrlAltDel</a>
+                </div>
+                <div id="noVNC_status">Loading</div>
+            </div>
+            <canvas id="noVNC_canvas" width="640px" height="20px">
+                <p style="color:white">This browser does not fully support required functionality, please use latest Chrome, Firefox or Internet Explorer 10. </p> 
+            </canvas>
+        </div>
+
+        <script>
+        /*jslint white: false */
+        /*global window, $, Util, RFB, */
+        "use strict";
+
+        var rfb;
+
+        function passwordRequired(rfb) {
+            var msg;
+            msg = '<form onsubmit="return setPassword();"';
+            msg += '  style="margin-bottom: 0px">';
+            msg += 'Password Required: ';
+            msg += '<input type=password size=10 id="password_input" class="noVNC_status">';
+            msg += '<\/form>';
+            $D('noVNC_status_bar').setAttribute("class", "noVNC_status_warn");
+            $D('noVNC_status').innerHTML = msg;
+        }
+        function setPassword() {
+            rfb.sendPassword($D('password_input').value);
+            return false;
+        }
+        function updateState(rfb, state, oldstate, msg) { //rfb, state, oldstate, msg
+            var s, sb, cad, level, clss;
+            s = $D('noVNC_status');
+            sb = $D('noVNC_status_bar');
+            cad = $D('sendCtrlAltDelButton');
+            switch (state) {
+                case 'failed':       level = "error";  break;
+                case 'fatal':        level = "error";  break;
+                case 'normal':       level = "normal"; break;
+                case 'disconnected': level = "warn"; break;
+                case 'loaded':       level = "normal"; break;
+                default:             level = "warn";   break;
+            }
+            
+            if (state === "normal") { cad.disabled = false; }
+            else                    { cad.disabled = true; }
+
+            if (typeof(msg) !== 'undefined') {
+                s.setAttribute("class", "noVNC_status_" + level);
+                s.innerHTML ='<span></span>'+ msg;
+            }
+        }
+
+        window.onload = function () {
+            var host, port, password, path;
+
+            $D('sendCtrlAltDelButton').style.display = "inline";
+            $D('sendCtrlAltDelButton').onclick = function() {
+              if (confirm("Are you sure?")) rfb.sendCtrlAltDel();
+            };
+
+            $D('clipboardButton').style.display = "inline";
+            $D('clipboardButton').onclick = function() {
+              rfb.sendString(prompt("Enter text to paste:"));
+            };
+
+            document.title = unescape(WebUtil.getQueryVar('title', 'noVNC'));
+            host = WebUtil.getQueryVar('host', null);
+            port = WebUtil.getQueryVar('port', null);
+            password = WebUtil.getQueryVar('password', '');
+            path = WebUtil.getQueryVar('path', 'websockify');
+            if ((!host) || (!port)) {
+                updateState('failed',
+                    "Must specify host and port in URL");
+                return;
+            }
+
+            rfb = new RFB({'target':       $D('noVNC_canvas'),
+                           'encrypt':      WebUtil.getQueryVar('encrypt',
+                                    (window.location.protocol === "https:")),
+                           'true_color':   WebUtil.getQueryVar('true_color', true),
+                           'local_cursor': WebUtil.getQueryVar('cursor', true),
+                           'shared':       WebUtil.getQueryVar('shared', true),
+                           'view_only':    WebUtil.getQueryVar('view_only', false),
+                           'updateState':  updateState,
+                           'onPasswordRequired':  passwordRequired});
+            rfb.connect(host, port, password, path);
+        };
+        </script>
+
+    </body>
+</html>

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/a0571d1e/scripts/vm/systemvm/injectkeys.sh
----------------------------------------------------------------------
diff --git a/scripts/vm/systemvm/injectkeys.sh b/scripts/vm/systemvm/injectkeys.sh
index 9f94678..ff58ef7 100755
--- a/scripts/vm/systemvm/injectkeys.sh
+++ b/scripts/vm/systemvm/injectkeys.sh
@@ -24,7 +24,7 @@
 #set -x
 
 TMP=/tmp
-MOUNTPATH=${HOME}/systemvm_mnt
+MOUNTPATH=${TMP}/systemvm_mnt
 TMPDIR=${TMP}/cloud/systemvm
 
 


Mime
View raw message