├── .github └── workflows │ └── docker-image.yml ├── Dockerfile ├── Dockerfile.arm64 ├── Dockerfile.armhf ├── LICENSE ├── README.md ├── deployment.properties ├── novnc ├── .gitignore ├── .gitmodules ├── .travis.yml ├── CONTRIBUTING.md ├── LICENSE.txt ├── README.md ├── debian │ ├── changelog │ ├── compat │ ├── control │ ├── copyright │ ├── novnc.install │ └── rules ├── docs │ ├── LICENSE.Apache-2.0 │ ├── LICENSE.BSD-2-Clause │ ├── LICENSE.BSD-3-Clause │ ├── LICENSE.GPL-3 │ ├── LICENSE.LGPL-3 │ ├── LICENSE.MPL-2.0 │ ├── LICENSE.OFL-1.1 │ ├── LICENSE.zlib │ ├── VERSION │ ├── flash_policy.txt │ ├── links │ ├── notes │ ├── packaging.txt │ ├── release.txt │ ├── rfb_notes │ ├── rfbproto-3.3.pdf │ ├── rfbproto-3.7.pdf │ └── rfbproto-3.8.pdf ├── favicon.ico ├── images │ ├── alt.png │ ├── clipboard.png │ ├── connect.png │ ├── ctrl.png │ ├── ctrlaltdel.png │ ├── disconnect.png │ ├── drag.png │ ├── esc.png │ ├── favicon.ico │ ├── favicon.png │ ├── keyboard.png │ ├── mouse_left.png │ ├── mouse_middle.png │ ├── mouse_none.png │ ├── mouse_right.png │ ├── power.png │ ├── screen_320x460.png │ ├── screen_57x57.png │ ├── screen_700x700.png │ ├── settings.png │ ├── showextrakeys.png │ └── tab.png ├── include │ ├── Orbitron700.ttf │ ├── Orbitron700.woff │ ├── base.css │ ├── base64.js │ ├── black.css │ ├── blue.css │ ├── chrome-app │ │ └── tcp-client.js │ ├── des.js │ ├── display.js │ ├── input.js │ ├── jsunzip.js │ ├── keyboard.js │ ├── keysym.js │ ├── keysymdef.js │ ├── logo.js │ ├── playback.js │ ├── rfb.js │ ├── ui.js │ ├── util.js │ ├── web-socket-js │ │ ├── README.txt │ │ ├── WebSocketMain.swf │ │ ├── swfobject.js │ │ └── web_socket.js │ ├── websock.js │ └── webutil.js ├── index.html ├── karma.conf.js ├── package.json ├── tests │ ├── arrays.html │ ├── arrays.js │ ├── assertions.js │ ├── base64.html │ ├── base64.js │ ├── browser.js │ ├── canvas.html │ ├── cursor.html │ ├── face.png │ ├── face.png.js │ ├── fake.websocket.js │ ├── input.html │ ├── keyboard-tests.html │ ├── run_from_console.casper.js │ ├── run_from_console.js │ ├── run_from_console.zombie.js │ ├── stats.js │ ├── test.base64.js │ ├── test.display.js │ ├── test.helper.js │ ├── test.keyboard.js │ ├── test.rfb.js │ ├── test.util.js │ ├── test.websock.js │ ├── viewport.css │ ├── viewport.html │ ├── vnc_perf.html │ └── vnc_playback.html ├── utils │ ├── Makefile │ ├── README.md │ ├── img2js.py │ ├── json2graph.py │ ├── launch.sh │ ├── nova-novncproxy │ ├── parse.js │ ├── rebind │ ├── rebind.c │ ├── u2x11 │ ├── web.py │ ├── websocket.py │ ├── websockify │ ├── websockify.py │ └── wsproxy.py ├── vnc.html └── vnc_auto.html ├── supervisord.conf └── supervisord.conf.arm /.github/workflows/docker-image.yml: -------------------------------------------------------------------------------- 1 | name: Docker Image CI 2 | 3 | on: 4 | push: 5 | branches: [ "master" ] 6 | pull_request: 7 | branches: [ "master" ] 8 | 9 | jobs: 10 | 11 | build: 12 | 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - uses: actions/checkout@v3 17 | - name: Build the Docker image 18 | run: docker build . --file Dockerfile --tag my-image-name:$(date +%s) 19 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:14.04 2 | MAINTAINER Kyle Anderson 3 | 4 | ENV DEBIAN_FRONTEND noninteractive 5 | RUN apt-get update && apt-get -y install xvfb x11vnc wget \ 6 | supervisor fluxbox icedtea-7-plugin net-tools python-numpy \ 7 | chromium-browser 8 | RUN sed -e '/^jdk.jar.disabledAlgorithms/s/^/#/' -i /usr/lib/jvm/java-7-openjdk-amd64/jre/lib/security/java.security 9 | ADD supervisord.conf /etc/supervisor/conf.d/supervisord.conf 10 | 11 | WORKDIR /root/ 12 | RUN mkdir -p /root/images 13 | ADD novnc /root/novnc/ 14 | 15 | ENV DISPLAY :0 16 | ENV RES 1024x768x24 17 | EXPOSE 8080 18 | CMD ["/usr/bin/supervisord"] 19 | -------------------------------------------------------------------------------- /Dockerfile.arm64: -------------------------------------------------------------------------------- 1 | FROM ubuntu:14.04 2 | MAINTAINER Kyle Anderson 3 | 4 | ENV DEBIAN_FRONTEND noninteractive 5 | 6 | RUN dpkg --add-architecture armhf 7 | 8 | RUN apt-get update && apt-get -y install xvfb x11vnc wget \ 9 | supervisor fluxbox icedtea-7-plugin net-tools python-numpy \ 10 | libfile-basedir-perl libfile-desktopentry-perl libfile-mimeinfo-perl \ 11 | libgmp10:armhf libisl10:armhf libmpc3:armhf libmpfr4:armhf \ 12 | x11-xserver-utils:armhf xdg-utils:armhf libdbus-glib-1-2:armhf \ 13 | libdbus-glib-1-2:armhf libgnome-keyring0:armhf cpp:armhf \ 14 | cpp-4.8:armhf libcloog-isl4:armhf libpulse0:armhf libnspr4:armhf \ 15 | libasound2:armhf libstdc++6:armhf libxss1:armhf libxtst6:armhf \ 16 | libxml2:armhf libldap-2.4-2:armhf libatk1.0-0:armhf libcairo2:armhf \ 17 | libcups2:armhf libexpat1:armhf libfontconfig1:armhf libudev-dev:armhf \ 18 | libfreetype6:armhf libgdk-pixbuf2.0-0:armhf libgssapi-krb5-2:armhf \ 19 | libgtk2.0-0:armhf libk5crypto3:armhf libkrb5-3:armhf libnss3:armhf \ 20 | libpango-1.0-0:armhf libpangocairo-1.0-0:armhf libpangoft2-1.0-0:armhf 21 | 22 | 23 | ADD supervisord.conf.arm /etc/supervisor/conf.d/supervisord.conf 24 | 25 | RUN wget http://launchpadlibrarian.net/170877332/gconf-service-backend_3.2.6-0ubuntu2_armhf.deb 26 | RUN wget http://launchpadlibrarian.net/170877334/libgconf-2-4_3.2.6-0ubuntu2_armhf.deb 27 | RUN wget http://launchpadlibrarian.net/170876897/gconf2-common_3.2.6-0ubuntu2_all.deb 28 | RUN wget http://launchpadlibrarian.net/218525711/chromium-codecs-ffmpeg-extra_45.0.2454.85-0ubuntu0.14.04.1.1097_armhf.deb 29 | RUN wget http://launchpadlibrarian.net/170877331/gconf-service_3.2.6-0ubuntu2_armhf.deb 30 | RUN wget http://launchpadlibrarian.net/218525709/chromium-browser_45.0.2454.85-0ubuntu0.14.04.1.1097_armhf.deb 31 | 32 | RUN dpkg -i gconf-service-backend_3.2.6-0ubuntu2_armhf.deb libgconf-2-4_3.2.6-0ubuntu2_armhf.deb gconf2-common_3.2.6-0ubuntu2_all.deb chromium-codecs-ffmpeg-extra_45.0.2454.85-0ubuntu0.14.04.1.1097_armhf.deb gconf-service_3.2.6-0ubuntu2_armhf.deb chromium-browser_45.0.2454.85-0ubuntu0.14.04.1.1097_armhf.deb 33 | 34 | ADD deployment.properties /root/.config/icedtea-web/deployment.properties 35 | 36 | WORKDIR /root/ 37 | RUN mkdir -p /root/images 38 | ADD novnc /root/novnc/ 39 | 40 | ENV DISPLAY :0 41 | ENV RES 1024x768x24 42 | EXPOSE 8080 43 | CMD ["/usr/bin/supervisord"] 44 | -------------------------------------------------------------------------------- /Dockerfile.armhf: -------------------------------------------------------------------------------- 1 | FROM ubuntu:14.04 2 | MAINTAINER Kyle Anderson 3 | 4 | ENV DEBIAN_FRONTEND noninteractive 5 | RUN apt-get update && apt-get -y install xvfb x11vnc wget \ 6 | supervisor fluxbox icedtea-7-plugin net-tools python-numpy \ 7 | libfile-basedir-perl libfile-desktopentry-perl libfile-mimeinfo-perl \ 8 | libgmp10 libisl10 libmpc3 libmpfr4 x11-xserver-utils xdg-utils \ 9 | libdbus-glib-1-2 libgnome-keyring0 cpp cpp-4.8 libcloog-isl4 10 | 11 | ADD supervisord.conf.arm /etc/supervisor/conf.d/supervisord.conf 12 | 13 | RUN wget http://launchpadlibrarian.net/170877332/gconf-service-backend_3.2.6-0ubuntu2_armhf.deb 14 | RUN wget http://launchpadlibrarian.net/170877334/libgconf-2-4_3.2.6-0ubuntu2_armhf.deb 15 | RUN wget http://launchpadlibrarian.net/170876897/gconf2-common_3.2.6-0ubuntu2_all.deb 16 | RUN wget http://launchpadlibrarian.net/218525711/chromium-codecs-ffmpeg-extra_45.0.2454.85-0ubuntu0.14.04.1.1097_armhf.deb 17 | RUN wget http://launchpadlibrarian.net/170877331/gconf-service_3.2.6-0ubuntu2_armhf.deb 18 | RUN wget http://launchpadlibrarian.net/218525709/chromium-browser_45.0.2454.85-0ubuntu0.14.04.1.1097_armhf.deb 19 | 20 | RUN dpkg -i gconf-service-backend_3.2.6-0ubuntu2_armhf.deb libgconf-2-4_3.2.6-0ubuntu2_armhf.deb gconf2-common_3.2.6-0ubuntu2_all.deb chromium-codecs-ffmpeg-extra_45.0.2454.85-0ubuntu0.14.04.1.1097_armhf.deb gconf-service_3.2.6-0ubuntu2_armhf.deb chromium-browser_45.0.2454.85-0ubuntu0.14.04.1.1097_armhf.deb 21 | 22 | WORKDIR /root/ 23 | RUN mkdir -p /root/images 24 | ADD novnc /root/novnc/ 25 | 26 | ENV DISPLAY :0 27 | ENV RES 1024x768x24 28 | EXPOSE 8080 29 | CMD ["/usr/bin/supervisord"] 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## ipmi-kvm-docker 2 | 3 | ![Docker Image Size (tag)](https://img.shields.io/docker/image-size/solarkennedy/ipmi-kvm-docker/latest) 4 | ![Docker Pulls](https://img.shields.io/docker/pulls/solarkennedy/ipmi-kvm-docker) 5 | 6 | Ever wanted to access and IPMI KVM console, only to find that you don't 7 | have network access or the right version of java or a compatible 8 | browser or credentials? 9 | 10 | This container runs: 11 | 12 | * Xvfb - X11 in a virtual framebuffer 13 | * x11vnc - A VNC server that scrapes the above X11 server 14 | * [noNVC](https://kanaka.github.io/noVNC/) - A HTML5 canvas vnc viewer 15 | * Fluxbox - a small window manager 16 | * Firefox - For browsing IPMI consoles 17 | * Java-plugin - Because... you need java to access most IPMI KVM Consoles. 18 | 19 | This is a [trusted build](https://registry.hub.docker.com/u/solarkennedy/ipmi-kvm-docker/) 20 | on the Docker Hub. 21 | 22 | ## Run It 23 | 24 | # on a remote host that can reach ipmi 25 | ssh admin 26 | $ docker run -p 8080:8080 solarkennedy/ipmi-kvm-docker 27 | 28 | # Now on your laptop 29 | xdg-open http://admin:8080 30 | # On a mac 31 | open http://admin:8080 32 | # Or just open in a browser 33 | 34 | In your web browser you should see the firefox, ready to connect to 35 | and IPMI KVM: 36 | 37 | ![IPMI Screenshot](https://raw.githubusercontent.com/solarkennedy/ipmi-kvm-docker/master/screenshot.png) 38 | 39 | ### Custom resolution 40 | 41 | By default, the VNC session will run with a resolution of 1024x768 (with 24-bit color depth). 42 | Custom resolutions can be specified with the docker environment variable RES, and must include color depth. 43 | 44 | $ docker run -p 8080:8080 -e RES=1600x900x24 solarkennedy/ipmi-kvm-docker 45 | 46 | ### Mount volume 47 | 48 | In case you need to mount floppy/iso images to the machine you can mount a volume to the container. 49 | 50 | $ docker run -p 8080:8080 -v /your/local/folder:/root/images solarkennedy/ipmi-kvm-docker -------------------------------------------------------------------------------- /deployment.properties: -------------------------------------------------------------------------------- 1 | deployment.security.level=ALLOW_UNSIGNED 2 | 3 | -------------------------------------------------------------------------------- /novnc/.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *.o 3 | tests/data_*.js 4 | utils/rebind.so 5 | node_modules 6 | -------------------------------------------------------------------------------- /novnc/.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "include/web-socket-js-project"] 2 | path = include/web-socket-js-project 3 | url = https://github.com/gimite/web-socket-js.git 4 | -------------------------------------------------------------------------------- /novnc/.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '0.11.13' 4 | env: 5 | matrix: 6 | - TEST_BROWSER_NAME=PhantomJS 7 | - TEST_BROWSER_NAME=chrome TEST_BROWSER_OS='Windows 7,Linux' 8 | - TEST_BROWSER_NAME=firefox TEST_BROWSER_OS='Windows 7,Linux' TEST_BROWSER_VERSION='30,26' 9 | - TEST_BROWSER_NAME='internet explorer' TEST_BROWSER_OS='Windows 7' TEST_BROWSER_VERSION=10 10 | - TEST_BROWSER_NAME='internet explorer' TEST_BROWSER_OS='Windows 8.1' TEST_BROWSER_VERSION=11 11 | - TEST_BROWSER_NAME=safari TEST_BROWSER_OS='OS X 10.8' TEST_BROWSER_VERSION=6 12 | - TEST_BROWSER_NAME=safari TEST_BROWSER_OS='OS X 10.9' TEST_BROWSER_VERSION=7 13 | global: 14 | - secure: QE5GqGd2hrpQsIgd8dlv3oRUUHqZayomzzQjNXOB81VQi241uz/ru+3GtBZLB5WLZCq/Gj89vbLnR0LN4ixlmPaWv3/WJQGyDGuRD/vMnccVl+rBUP/Hh2zdYwiISIGcrywNAE+KLus/lyt/ahVgzbaRaDSzrM1HaZFT/rndGck= 15 | - secure: g75sdctEwj0hoLW0Y08Tdv8s5scNzplB6a9EtaJ2vJD9S/bK+AsPqbWesGv1UlrFPCWdbV7Vg61vkmoUjcmb5xhqFIjcM9TlYJoKWeOTsOmnQoSIkIq6gMF1k02+LmKInbPgIzrp3m3jluS1qaOs/EzFpDnJp9hWBiAfXa12Jxk= 16 | before_script: npm install -g karma-cli 17 | -------------------------------------------------------------------------------- /novnc/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | How to contribute to noVNC 2 | ========================== 3 | 4 | We accept code via pull requests on GitHub. There are several guidelines that 5 | we expect contributors submitting code requests to follow. If you have issues 6 | following any of these guidelines, feel free to drop us a line by leaving a 7 | comment in the code request or sending us an email. 8 | 9 | Contributing Guidelines 10 | ----------------------- 11 | 12 | * While we don't have an official coding style guide, please try to follow 13 | the general coding style of the existing code. 14 | ** Use four spaces instead of tabs 15 | ** prefix private variables and functions with an `_` 16 | 17 | * Please try to include unit tests for your code. For instance, if you 18 | introduce a new encoding, add a test to `tests/test.rfb.js` under the 19 | "Encoding Handlers" section (basically, input a small pattern in your 20 | encoding and make sure the pattern gets displayed correctly). If you 21 | fix a bug, try to add a unit test that would have caught that bug 22 | (if possible -- some bugs, especially visual ones, are hard to test for). 23 | 24 | * Squash your commits down in to a clean commit history. For instance, there 25 | should not be "cleanup" commits where you fix issues in previous commits in 26 | the same pull request. Before you go to commit, use `git rebase -i` to 27 | squash these changes into the relevant commits. For instance, a good commit 28 | history might look like "Added support for FOO encoding, Added support for 29 | BAR message, Placed Button in UI to Trigger BAR" (where each comma denotes 30 | a separate commit). 31 | 32 | * Add both a title and description to your commit, if possible. Place more 33 | detail on what you did in the description. 34 | 35 | Running the unit tests 36 | ---------------------- 37 | 38 | There are two ways to run the unit tests. For both ways, you should first run 39 | `npm install` (not as root). 40 | 41 | The first way to run the tests is to run `npm test`. This will run all the 42 | tests in the headless PhantomJS browser (which uses WebKit). 43 | 44 | The second way to run the tests is using the `tests/run_from_console.js` file. 45 | This way is a bit more flexible, and can provide more information about what 46 | went wrong. To run all the tests, simply run `tests/run_from_console.js`. 47 | To run a specific test file, you can use the `-t path/to/test/file.js` option. 48 | If you wish to simply generate the HTML for the test, use the `-g` option, and 49 | the path to the temporary HTML file will be written to standard out. To open 50 | this file in your default browser automatically, pass the `-o` option as well. 51 | More information can be found by passing the `--help` or `-h` option. 52 | 53 | 54 | Thanks, and happy coding! 55 | -------------------------------------------------------------------------------- /novnc/LICENSE.txt: -------------------------------------------------------------------------------- 1 | noVNC is Copyright (C) 2011 Joel Martin 2 | 3 | The noVNC core library files are licensed under the MPL 2.0 (Mozilla 4 | Public License 2.0). The noVNC core library is composed of the 5 | Javascript code necessary for full noVNC operation. This includes (but 6 | is not limited to): 7 | 8 | include/base64.js 9 | include/des.js 10 | include/display.js 11 | include/input.js 12 | include/jsunzip.js 13 | include/keysym.js 14 | include/logo.js 15 | include/rfb.js 16 | include/ui.js 17 | include/util.js 18 | include/vnc.js 19 | include/websock.js 20 | include/webutil.js 21 | 22 | The HTML, CSS, font and images files that included with the noVNC 23 | source distibution (or repository) are not considered part of the 24 | noVNC core library and are licensed under more permissive licenses. 25 | The intent is to allow easy integration of noVNC into existing web 26 | sites and web applications. 27 | 28 | The HTML, CSS, font and image files are licensed as follows: 29 | 30 | *.html : 2-Clause BSD license 31 | 32 | include/*.css : 2-Clause BSD license 33 | 34 | include/Orbitron* : SIL Open Font License 1.1 35 | (Copyright 2009 Matt McInerney) 36 | 37 | images/ : Creative Commons Attribution-ShareAlike 38 | http://creativecommons.org/licenses/by-sa/3.0/ 39 | 40 | Some portions of noVNC are copyright to their individual authors. 41 | Please refer to the individual source files and/or to the noVNC commit 42 | history: https://github.com/kanaka/noVNC/commits/master 43 | 44 | The are several files and projects that have been incorporated into 45 | the noVNC core library. Here is a list of those files and the original 46 | licenses (all MPL 2.0 compatible): 47 | 48 | include/base64.js : MPL 2.0 49 | 50 | include/des.js : Various BSD style licenses 51 | 52 | include/jsunzip.js : zlib/libpng license 53 | 54 | include/web-socket-js/ : New BSD license (3-clause). Source code at 55 | http://github.com/gimite/web-socket-js 56 | 57 | include/chrome-app/tcp-stream.js 58 | : Apache 2.0 license 59 | 60 | utils/websockify 61 | utils/websocket.py : LGPL 3 62 | 63 | The following license texts are included: 64 | 65 | docs/LICENSE.MPL-2.0 66 | docs/LICENSE.LGPL-3 and 67 | docs/LICENSE.GPL-3 68 | docs/LICENSE.OFL-1.1 69 | docs/LICENSE.BSD-3-Clause (New BSD) 70 | docs/LICENSE.BSD-2-Clause (Simplified BSD / FreeBSD) 71 | docs/LICENSE.zlib 72 | docs/LICENSE.Apache-2.0 73 | 74 | Or alternatively the license texts may be found here: 75 | 76 | http://www.mozilla.org/MPL/2.0/ 77 | http://www.gnu.org/licenses/lgpl.html and 78 | http://www.gnu.org/licenses/gpl.html 79 | http://scripts.sil.org/OFL 80 | http://en.wikipedia.org/wiki/BSD_licenses 81 | http://www.gzip.org/zlib/zlib_license.html 82 | http://www.apache.org/licenses/LICENSE-2.0.html 83 | -------------------------------------------------------------------------------- /novnc/README.md: -------------------------------------------------------------------------------- 1 | ## noVNC: HTML5 VNC Client 2 | 3 | [![Build Status](https://travis-ci.org/kanaka/noVNC.svg?branch=master)](https://travis-ci.org/kanaka/noVNC) 4 | 5 | ### Description 6 | 7 | noVNC is a HTML5 VNC client that runs well in any modern browser 8 | including mobile browsers (iPhone/iPad and Android). 9 | 10 | Many companies/projects have integrated noVNC including [Ganeti Web 11 | Manager](http://code.osuosl.org/projects/ganeti-webmgr), 12 | [OpenStack](http://www.openstack.org), 13 | [OpenNebula](http://opennebula.org/), and 14 | [LibVNCServer](http://libvncserver.sourceforge.net). See [the Projects 15 | and Companies wiki 16 | page](https://github.com/kanaka/noVNC/wiki/ProjectsCompanies-using-noVNC) 17 | for a more complete list with additional info and links. 18 | 19 | ### News/help/contact 20 | 21 | Notable commits, announcements and news are posted to 22 | @noVNC 23 | 24 | If you are a noVNC developer/integrator/user (or want to be) please 25 | join the noVNC 27 | discussion group 28 | 29 | Bugs and feature requests can be submitted via [github 30 | issues](https://github.com/kanaka/noVNC/issues). If you are looking 31 | for a place to start contributing to noVNC, a good place to start 32 | would be the issues that are marked as 33 | ["patchwelcome"](https://github.com/kanaka/noVNC/issues?labels=patchwelcome). 34 | 35 | If you want to show appreciation for noVNC you could donate to a great 36 | non-profits such as: [Compassion 37 | International](http://www.compassion.com/), [SIL](http://www.sil.org), 38 | [Habitat for Humanity](http://www.habitat.org), [Electronic Frontier 39 | Foundation](https://www.eff.org/), [Against Malaria 40 | Foundation](http://www.againstmalaria.com/), [Nothing But 41 | Nets](http://www.nothingbutnets.net/), etc. Please tweet @noVNC if you do. 43 | 44 | 45 | ### Features 46 | 47 | * Supports all modern browsers including mobile (iOS, Android) 48 | * Supported VNC encodings: raw, copyrect, rre, hextile, tight, tightPNG 49 | * WebSocket SSL/TLS encryption (i.e. "wss://") support 50 | * 24-bit true color and 8 bit colour mapped 51 | * Supports desktop resize notification/pseudo-encoding 52 | * Local or remote cursor 53 | * Clipboard copy/paste 54 | * Clipping or scolling modes for large remote screens 55 | * Easy site integration and theming (3 example themes included) 56 | * Licensed under the [MPL 2.0](http://www.mozilla.org/MPL/2.0/) 57 | 58 | ### Screenshots 59 | 60 | Running in Chrome before and after connecting: 61 | 62 |   63 | 64 | See more screenshots here. 65 | 66 | 67 | ### Browser Requirements 68 | 69 | * HTML5 Canvas (with createImageData): Chrome, Firefox 3.6+, iOS 70 | Safari, Opera 11+, Internet Explorer 9+, etc. 71 | 72 | * HTML5 WebSockets: For browsers that do not have builtin 73 | WebSockets support, the project includes 74 | web-socket-js, 75 | a WebSockets emulator using Adobe Flash. iOS 4.2+ has built-in 76 | WebSocket support. 77 | 78 | * Fast Javascript Engine: this is not strictly a requirement, but 79 | without a fast Javascript engine, noVNC might be painfully slow. 80 | 81 | * See the more detailed [browser compatibility wiki page](https://github.com/kanaka/noVNC/wiki/Browser-support). 82 | 83 | 84 | ### Server Requirements 85 | 86 | Unless you are using a VNC server with support for WebSockets 87 | connections (such as 88 | [x11vnc/libvncserver](http://libvncserver.sourceforge.net/), 89 | [QEMU](http://www.qemu.org/), or 90 | [PocketVNC](http://www.pocketvnc.com/blog/?page_id=866)), you need to 91 | use a WebSockets to TCP socket proxy. There is a python proxy included 92 | ('websockify'). 93 | 94 | 95 | ### Quick Start 96 | 97 | * Use the launch script to start a mini-webserver and the WebSockets 98 | proxy (websockify). The `--vnc` option is used to specify the location of 99 | a running VNC server: 100 | 101 | `./utils/launch.sh --vnc localhost:5901` 102 | 103 | * Point your browser to the cut-and-paste URL that is output by the 104 | launch script. Enter a password if the VNC server has one 105 | configured. Hit the Connect button and enjoy! 106 | 107 | 108 | ### Other Pages 109 | 110 | * [Encrypted Connections](https://github.com/kanaka/websockify/wiki/Encrypted-Connections). How to setup websockify so that you can use encrypted connections from noVNC. 111 | 112 | * [Advanced Usage](https://github.com/kanaka/noVNC/wiki/Advanced-usage). Starting a VNC server, advanced websockify usage, etc. 113 | 114 | * [Integrating noVNC](https://github.com/kanaka/noVNC/wiki/Integration) into existing projects. 115 | 116 | * [Troubleshooting noVNC](https://github.com/kanaka/noVNC/wiki/Troubleshooting) problems. 117 | 118 | 119 | ### Authors/Contributors 120 | 121 | * Core team: 122 | * [Joel Martin](https://github.com/kanaka) 123 | * [Samuel Mannehed](https://github.com/samhed) (Cendio) 124 | * [Peter Åstrand](https://github.com/astrand) (Cendio) 125 | * [Solly Ross](https://github.com/DirectXMan12) (Red Hat / OpenStack) 126 | 127 | * Notable contributions: 128 | * UI and Icons : Chris Gordon 129 | * Original Logo : Michael Sersen 130 | * tight encoding : Michael Tinglof (Mercuri.ca) 131 | 132 | * Included libraries: 133 | * web-socket-js : Hiroshi Ichikawa (github.com/gimite/web-socket-js) 134 | * as3crypto : Henri Torgemane (code.google.com/p/as3crypto) 135 | * base64 : Martijn Pieters (Digital Creations 2), Samuel Sieb (sieb.net) 136 | * jsunzip : Erik Moller (github.com/operasoftware/jsunzip), 137 | * tinflate : Joergen Ibsen (ibsensoftware.com) 138 | * DES : Dave Zimmerman (Widget Workshop), Jef Poskanzer (ACME Labs) 139 | -------------------------------------------------------------------------------- /novnc/debian/changelog: -------------------------------------------------------------------------------- 1 | novnc (0.4) maverick; urgency=low 2 | 3 | * Clarify permissive licenses of HTML, CSS, images. 4 | * Use render queue and requestAnimationFrame 5 | * UltraVNC repeater support 6 | 7 | -- Joel Martin Fri, 14 Sep 2012 05:00:00 -0600 8 | 9 | novnc (0.3) maverick; urgency=low 10 | 11 | * add tight encoding support 12 | * release pressed key when focus lost (fixes locked Alt key) 13 | * Support Apple Remote Desktop 14 | * Add nova/openstack proxy wrapper 15 | * Better connection close handling/reporting 16 | 17 | -- Joel Martin Fri, 11 May 2012 03:00:00 -0600 18 | 19 | novnc (0.2) maverick; urgency=low 20 | 21 | * Mobile device support with viewport clipping 22 | * Much better styling that also works on mobile devices well 23 | * Update websockify to support latest WebSocket protocol HyBi 13 24 | (i.e. support IETF 6455) 25 | * Better support in websockify for python 2.4 through 3.2 26 | * Support VMWare ESX and Intel AMT KVM 27 | * View only mode 28 | 29 | -- Joel Martin Tue, 05 Jul 2011 01:00:00 -0600 30 | 31 | novnc (0.1) maverick; urgency=low 32 | 33 | * First upstream release 34 | 35 | -- Joel Martin Tue, 05 Jul 2011 01:00:00 -0600 36 | -------------------------------------------------------------------------------- /novnc/debian/compat: -------------------------------------------------------------------------------- 1 | 7 2 | -------------------------------------------------------------------------------- /novnc/debian/control: -------------------------------------------------------------------------------- 1 | Source: novnc 2 | Section: web 3 | Priority: optional 4 | Maintainer: Joel Martin 5 | Build-Depends: debhelper (>= 7.0.0~) 6 | Standards-Version: 3.8.3 7 | Homepage: https://github.com/kanaka/noVNC/ 8 | 9 | Package: novnc 10 | Architecture: any 11 | Depends: ${shlibs:Depends}, ${misc:Depends}, python (>= 2.4) 12 | Description: HTML5 VNC client 13 | VNC client using HTML5 (WebSockets, Canvas) with encryption (wss://) support. 14 | -------------------------------------------------------------------------------- /novnc/debian/copyright: -------------------------------------------------------------------------------- 1 | Upstream Project: https://github.com/kanaka/noVNC/ 2 | 3 | --------------------- Original LICENSE.txt --------------------------- 4 | 5 | noVNC is Copyright (C) 2012 Joel Martin 6 | 7 | Some portions of noVNC are copyright to their individual authors. 8 | Please refer to the individual source files and/or to the noVNC commit 9 | history: https://github.com/kanaka/noVNC/commits/master 10 | 11 | noVNC is licensed under the MPL 2.0 (Mozilla Public License) with the 12 | following exceptions: 13 | 14 | *.html, *.css : 2-Clause BSD license 15 | 16 | include/Orbitron* : SIL Open Font License 1.1 17 | (Copyright 2009 Matt McInerney) 18 | 19 | images/ : Creative Commons Attribution-ShareAlike 20 | http://creativecommons.org/licenses/by-sa/3.0/ 21 | 22 | include/base64.js : MPL 2.0 23 | 24 | include/des.js : Various BSD style licenses 25 | 26 | include/jsunzip.js : zlib/libpng license 27 | 28 | include/web-socket-js/ : New BSD license (3-clause). Source code at 29 | http://github.com/gimite/web-socket-js 30 | 31 | include/chrome-app/tcp-stream.js 32 | : Apache 2.0 license 33 | 34 | ---------------------------------------------------------------------- 35 | 36 | The MPL-2.0 license text may be found here: 37 | http://www.mozilla.org/MPL/2.0/ 38 | -------------------------------------------------------------------------------- /novnc/debian/novnc.install: -------------------------------------------------------------------------------- 1 | vnc.html /usr/share/novnc 2 | vnc_auto.html /usr/share/novnc 3 | README.md /usr/share/doc/novnc 4 | LICENSE.txt /usr/share/doc/novnc 5 | utils/Makefile /usr/share/novnc/utils 6 | utils/launch.sh /usr/share/novnc/utils 7 | utils/websocket.py /usr/share/novnc/utils 8 | utils/websockify /usr/share/novnc/utils 9 | utils/rebind.c /usr/share/novnc/utils 10 | utils/rebind.so /usr/share/novnc/utils 11 | images /usr/share/novnc 12 | images/favicon.ico /usr/share/novnc 13 | include/base64.js /usr/share/novnc/include 14 | include/des.js /usr/share/novnc/include 15 | include/display.js /usr/share/novnc/include 16 | include/keysymdef.js /usr/share/novnc/include 17 | include/keyboard.js /usr/share/novnc/include 18 | include/input.js /usr/share/novnc/include 19 | include/logo.js /usr/share/novnc/include 20 | include/base.css /usr/share/novnc/include 21 | include/blue.css /usr/share/novnc/include 22 | include/black.css /usr/share/novnc/include 23 | include/playback.js /usr/share/novnc/include 24 | include/rfb.js /usr/share/novnc/include 25 | include/ui.js /usr/share/novnc/include 26 | include/util.js /usr/share/novnc/include 27 | include/websock.js /usr/share/novnc/include 28 | include/webutil.js /usr/share/novnc/include 29 | include/jsunzip.js /usr/share/novnc/include 30 | include/web-socket-js/* /usr/share/novnc/include/web-socket-js 31 | -------------------------------------------------------------------------------- /novnc/debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | 3 | # Uncomment this to turn on verbose mode. 4 | #export DH_VERBOSE=1 5 | 6 | clean: 7 | make -C utils clean 8 | dh clean 9 | 10 | build: 11 | make -C utils rebind.so 12 | 13 | %: 14 | dh ${@} 15 | -------------------------------------------------------------------------------- /novnc/docs/LICENSE.BSD-2-Clause: -------------------------------------------------------------------------------- 1 | Copyright (c) , 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above copyright 10 | notice, this list of conditions and the following disclaimer in the 11 | documentation and/or other materials provided with the distribution. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 14 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 17 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 20 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 22 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | -------------------------------------------------------------------------------- /novnc/docs/LICENSE.BSD-3-Clause: -------------------------------------------------------------------------------- 1 | Copyright (c) , 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | * Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright 9 | notice, this list of conditions and the following disclaimer in the 10 | documentation and/or other materials provided with the distribution. 11 | * Neither the name of the nor the 12 | names of its contributors may be used to endorse or promote products 13 | derived from this software without specific prior written permission. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 19 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /novnc/docs/LICENSE.LGPL-3: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | -------------------------------------------------------------------------------- /novnc/docs/LICENSE.OFL-1.1: -------------------------------------------------------------------------------- 1 | This Font Software is licensed under the SIL Open Font License, Version 1.1. 2 | This license is copied below, and is also available with a FAQ at: 3 | http://scripts.sil.org/OFL 4 | 5 | 6 | ----------------------------------------------------------- 7 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 8 | ----------------------------------------------------------- 9 | 10 | PREAMBLE 11 | The goals of the Open Font License (OFL) are to stimulate worldwide 12 | development of collaborative font projects, to support the font creation 13 | efforts of academic and linguistic communities, and to provide a free and 14 | open framework in which fonts may be shared and improved in partnership 15 | with others. 16 | 17 | The OFL allows the licensed fonts to be used, studied, modified and 18 | redistributed freely as long as they are not sold by themselves. The 19 | fonts, including any derivative works, can be bundled, embedded, 20 | redistributed and/or sold with any software provided that any reserved 21 | names are not used by derivative works. The fonts and derivatives, 22 | however, cannot be released under any other type of license. The 23 | requirement for fonts to remain under this license does not apply 24 | to any document created using the fonts or their derivatives. 25 | 26 | DEFINITIONS 27 | "Font Software" refers to the set of files released by the Copyright 28 | Holder(s) under this license and clearly marked as such. This may 29 | include source files, build scripts and documentation. 30 | 31 | "Reserved Font Name" refers to any names specified as such after the 32 | copyright statement(s). 33 | 34 | "Original Version" refers to the collection of Font Software components as 35 | distributed by the Copyright Holder(s). 36 | 37 | "Modified Version" refers to any derivative made by adding to, deleting, 38 | or substituting -- in part or in whole -- any of the components of the 39 | Original Version, by changing formats or by porting the Font Software to a 40 | new environment. 41 | 42 | "Author" refers to any designer, engineer, programmer, technical 43 | writer or other person who contributed to the Font Software. 44 | 45 | PERMISSION & CONDITIONS 46 | Permission is hereby granted, free of charge, to any person obtaining 47 | a copy of the Font Software, to use, study, copy, merge, embed, modify, 48 | redistribute, and sell modified and unmodified copies of the Font 49 | Software, subject to the following conditions: 50 | 51 | 1) Neither the Font Software nor any of its individual components, 52 | in Original or Modified Versions, may be sold by itself. 53 | 54 | 2) Original or Modified Versions of the Font Software may be bundled, 55 | redistributed and/or sold with any software, provided that each copy 56 | contains the above copyright notice and this license. These can be 57 | included either as stand-alone text files, human-readable headers or 58 | in the appropriate machine-readable metadata fields within text or 59 | binary files as long as those fields can be easily viewed by the user. 60 | 61 | 3) No Modified Version of the Font Software may use the Reserved Font 62 | Name(s) unless explicit written permission is granted by the corresponding 63 | Copyright Holder. This restriction only applies to the primary font name as 64 | presented to the users. 65 | 66 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 67 | Software shall not be used to promote, endorse or advertise any 68 | Modified Version, except to acknowledge the contribution(s) of the 69 | Copyright Holder(s) and the Author(s) or with their explicit written 70 | permission. 71 | 72 | 5) The Font Software, modified or unmodified, in part or in whole, 73 | must be distributed entirely under this license, and must not be 74 | distributed under any other license. The requirement for fonts to 75 | remain under this license does not apply to any document created 76 | using the Font Software. 77 | 78 | TERMINATION 79 | This license becomes null and void if any of the above conditions are 80 | not met. 81 | 82 | DISCLAIMER 83 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 84 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 85 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 86 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 87 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 88 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 89 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 90 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 91 | OTHER DEALINGS IN THE FONT SOFTWARE. 92 | -------------------------------------------------------------------------------- /novnc/docs/LICENSE.zlib: -------------------------------------------------------------------------------- 1 | Copyright (c) , 2 | All rights reserved. 3 | 4 | This software is provided 'as-is', without any express 5 | or implied warranty. In no event will the authors be 6 | held liable for any damages arising from the use of 7 | this software. 8 | 9 | Permission is granted to anyone to use this software 10 | for any purpose, including commercial applications, 11 | and to alter it and redistribute it freely, subject to 12 | the following restrictions: 13 | 14 | 1. The origin of this software must not be 15 | misrepresented; you must not claim that you 16 | wrote the original software. If you use this 17 | software in a product, an acknowledgment in 18 | the product documentation would be appreciated 19 | but is not required. 20 | 21 | 2. Altered source versions must be plainly marked 22 | as such, and must not be misrepresented as 23 | being the original software. 24 | 25 | 3. This notice may not be removed or altered from 26 | any source distribution. 27 | 28 | -------------------------------------------------------------------------------- /novnc/docs/VERSION: -------------------------------------------------------------------------------- 1 | 0.4 2 | -------------------------------------------------------------------------------- /novnc/docs/flash_policy.txt: -------------------------------------------------------------------------------- 1 | Manual setup: 2 | 3 | DATA="echo \'\'" 4 | /usr/bin/socat -T 1 TCP-L:843,reuseaddr,fork,crlf SYSTEM:"$DATA" 5 | -------------------------------------------------------------------------------- /novnc/docs/links: -------------------------------------------------------------------------------- 1 | New tight PNG protocol: 2 | http://wiki.qemu.org/VNC_Tight_PNG 3 | http://xf.iksaif.net/blog/index.php?post/2010/06/14/QEMU:-Tight-PNG-and-some-profiling 4 | 5 | RFB protocol and extensions: 6 | http://tigervnc.org/cgi-bin/rfbproto 7 | 8 | Canvas Browser Compatibility: 9 | http://philip.html5.org/tests/canvas/suite/tests/results.html 10 | 11 | WebSockets API standard: 12 | http://www.whatwg.org/specs/web-apps/current-work/complete.html#websocket 13 | http://dev.w3.org/html5/websockets/ 14 | http://www.ietf.org/id/draft-ietf-hybi-thewebsocketprotocol-00.txt 15 | 16 | Browser Keyboard Events detailed: 17 | http://unixpapa.com/js/key.html 18 | 19 | ActionScript (Flash) WebSocket implementation: 20 | http://github.com/gimite/web-socket-js 21 | 22 | ActionScript (Flash) crypto/TLS library: 23 | http://code.google.com/p/as3crypto 24 | http://github.com/lyokato/as3crypto_patched 25 | 26 | TLS Protocol: 27 | http://en.wikipedia.org/wiki/Transport_Layer_Security 28 | 29 | Generate self-signed certificate: 30 | http://docs.python.org/dev/library/ssl.html#certificates 31 | 32 | Cursor appearance/style (for Cursor pseudo-encoding): 33 | http://en.wikipedia.org/wiki/ICO_(file_format) 34 | http://www.daubnet.com/en/file-format-cur 35 | https://developer.mozilla.org/en/Using_URL_values_for_the_cursor_property 36 | http://www.fileformat.info/format/bmp/egff.htm 37 | 38 | Icon/Cursor file format: 39 | http://msdn.microsoft.com/en-us/library/ms997538 40 | http://msdn.microsoft.com/en-us/library/aa921550.aspx 41 | http://msdn.microsoft.com/en-us/library/aa930622.aspx 42 | 43 | 44 | RDP Protocol specification: 45 | http://msdn.microsoft.com/en-us/library/cc240445(v=PROT.10).aspx 46 | 47 | 48 | Related projects: 49 | 50 | guacamole: http://guacamole.sourceforge.net/ 51 | 52 | - Web client, but Java servlet does pre-processing 53 | 54 | jsvnc: http://code.google.com/p/jsvnc/ 55 | 56 | - No releases 57 | 58 | webvnc: http://code.google.com/p/webvnc/ 59 | 60 | - Jetty web server gateway, no updates since April 2008. 61 | 62 | RealVNC Java applet: http://www.realvnc.com/support/javavncviewer.html 63 | 64 | - Java applet 65 | 66 | Flashlight-VNC: http://www.wizhelp.com/flashlight-vnc/ 67 | 68 | - Adobe Flash implementation 69 | 70 | FVNC: http://osflash.org/fvnc 71 | 72 | - Adbove Flash implementation 73 | 74 | CanVNC: http://canvnc.sourceforge.net/ 75 | 76 | - HTML client with REST to VNC python proxy. Mostly vapor. 77 | -------------------------------------------------------------------------------- /novnc/docs/notes: -------------------------------------------------------------------------------- 1 | Some implementation notes: 2 | 3 | There is an included flash object (web-socket-js) that is used to 4 | emulate websocket support on browsers without websocket support 5 | (currently only Chrome has WebSocket support). 6 | 7 | Javascript doesn't have a bytearray type, so what you get out of 8 | a WebSocket object is just Javascript strings. Javascript has UTF-16 9 | unicode strings and anything sent through the WebSocket gets converted 10 | to UTF-8 and vice-versa. So, one additional (and necessary) function 11 | of websockify is base64 encoding/decoding what is sent to/from the 12 | browser. 13 | 14 | Building web-socket-js emulator: 15 | 16 | cd include/web-socket-js/flash-src 17 | mxmlc -static-link-runtime-shared-libraries WebSocketMain.as 18 | -------------------------------------------------------------------------------- /novnc/docs/packaging.txt: -------------------------------------------------------------------------------- 1 | noVNC packaging steps for Debian/Ubuntu: 2 | 3 | - Update the noVNC version in docs/VERSION and add a new entry for the 4 | version in debian/changelog 5 | 6 | - Rename the novnc source directory to match the form "novnc-VERSION". 7 | 8 | - In the novnc source directory, run the packaging command: 9 | 10 | debuild -I -uc -us 11 | 12 | - The -I option ignores the .git directory when generating the 13 | source tarball. 14 | - the -uc and -us may be omitted in order to create a signed 15 | package. 16 | 17 | - Alternatively, use pbuilder instead of debuild in order to build 18 | for other distributions and to guarantee a sanitized package. 19 | 20 | - Verify the package and then commit the changes to docs/VERSION and 21 | debian/changelog. 22 | 23 | - Upload the new package file(s). 24 | -------------------------------------------------------------------------------- /novnc/docs/release.txt: -------------------------------------------------------------------------------- 1 | - Update and commit docs/VERSION and debian/changelog 2 | - Create version tag and tarball from tag 3 | WVER=0.3 4 | git tag v${WVER} 5 | git push origin master 6 | git push origin v${WVER} 7 | git archive --format=tar --prefix=novnc-${WVER}/ v${WVER} > novnc-${WVER}.tar 8 | gzip novnc-${WVER}.tar 9 | - Upload tarball to repo 10 | -------------------------------------------------------------------------------- /novnc/docs/rfb_notes: -------------------------------------------------------------------------------- 1 | 5.1.1 ProtocolVersion: 12, 12 bytes 2 | 3 | - Sent by server, max supported 4 | 12 ascii - "RFB 003.008\n" 5 | - Response by client, version to use 6 | 12 ascii - "RFB 003.003\n" 7 | 8 | 5.1.2 Authentication: >=4, [16, 4] bytes 9 | 10 | - Sent by server 11 | CARD32 - authentication-scheme 12 | 0 - connection failed 13 | CARD32 - length 14 | length - reason 15 | 1 - no authentication 16 | 17 | 2 - VNC authentication 18 | 16 CARD8 - challenge (random bytes) 19 | 20 | - Response by client (if VNC authentication) 21 | 16 CARD8 - client encrypts the challenge with DES, using user 22 | password as key, sends resulting 16 byte response 23 | 24 | - Response by server (if VNC authentication) 25 | CARD32 - 0 - OK 26 | 1 - failed 27 | 2 - too-many 28 | 29 | 5.1.3 ClientInitialisation: 1 byte 30 | - Sent by client 31 | CARD8 - shared-flag, 0 exclusive, non-zero shared 32 | 33 | 5.1.4 ServerInitialisation: >=24 bytes 34 | - Sent by server 35 | CARD16 - framebuffer-width 36 | CARD16 - framebuffer-height 37 | 16 byte PIXEL_FORMAT - server-pixel-format 38 | CARD8 - bits-per-pixel 39 | CARD8 - depth 40 | CARD8 - big-endian-flag, non-zero is big endian 41 | CARD8 - true-color-flag, non-zero then next 6 apply 42 | CARD16 - red-max 43 | CARD16 - green-max 44 | CARD16 - blue-max 45 | CARD8 - red-shift 46 | CARD8 - green-shift 47 | CARD8 - blue-shift 48 | 3 bytes - padding 49 | CARD32 - name-length 50 | 51 | CARD8[length] - name-string 52 | 53 | 54 | 55 | Client to Server Messages: 56 | 57 | 5.2.1 SetPixelFormat: 20 bytes 58 | CARD8: 0 - message-type 59 | ... 60 | 61 | 5.2.2 FixColourMapEntries: >=6 bytes 62 | CARD8: 1 - message-type 63 | ... 64 | 65 | 5.2.3 SetEncodings: >=8 bytes 66 | CARD8: 2 - message-type 67 | CARD8 - padding 68 | CARD16 - numer-of-encodings 69 | 70 | CARD32 - encoding-type in preference order 71 | 0 - raw 72 | 1 - copy-rectangle 73 | 2 - RRE 74 | 4 - CoRRE 75 | 5 - hextile 76 | 77 | 5.2.4 FramebufferUpdateRequest (10 bytes) 78 | CARD8: 3 - message-type 79 | CARD8 - incremental (0 for full-update, non-zero for incremental) 80 | CARD16 - x-position 81 | CARD16 - y-position 82 | CARD16 - width 83 | CARD16 - height 84 | 85 | 86 | 5.2.5 KeyEvent: 8 bytes 87 | CARD8: 4 - message-type 88 | CARD8 - down-flag 89 | 2 bytes - padding 90 | CARD32 - key (X-Windows keysym values) 91 | 92 | 5.2.6 PointerEvent: 6 bytes 93 | CARD8: 5 - message-type 94 | CARD8 - button-mask 95 | CARD16 - x-position 96 | CARD16 - y-position 97 | 98 | 5.2.7 ClientCutText: >=9 bytes 99 | CARD8: 6 - message-type 100 | ... 101 | 102 | 103 | Server to Client Messages: 104 | 105 | 5.3.1 FramebufferUpdate 106 | CARD8: 0 - message-type 107 | 1 byte - padding 108 | CARD16 - number-of-rectangles 109 | 110 | CARD16 - x-position 111 | CARD16 - y-position 112 | CARD16 - width 113 | CARD16 - height 114 | CARD16 - encoding-type: 115 | 0 - raw 116 | 1 - copy rectangle 117 | 2 - RRE 118 | 4 - CoRRE 119 | 5 - hextile 120 | 121 | raw: 122 | - width x height pixel values 123 | 124 | copy rectangle: 125 | CARD16 - src-x-position 126 | CARD16 - src-y-position 127 | 128 | RRE: 129 | CARD32 - N number-of-subrectangles 130 | Nxd bytes - background-pixel-value (d bits-per-pixel) 131 | 132 | ... 133 | 134 | 5.3.2 SetColourMapEntries (no support) 135 | CARD8: 1 - message-type 136 | ... 137 | 138 | 5.3.3 Bell 139 | CARD8: 2 - message-type 140 | 141 | 5.3.4 ServerCutText 142 | CARD8: 3 - message-type 143 | 144 | 145 | 146 | 147 | 148 | -------------------------------------------------------------------------------- /novnc/docs/rfbproto-3.3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solarkennedy/ipmi-kvm-docker/26002abba9b39f574a5a775165d4ea659fd004e7/novnc/docs/rfbproto-3.3.pdf -------------------------------------------------------------------------------- /novnc/docs/rfbproto-3.7.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solarkennedy/ipmi-kvm-docker/26002abba9b39f574a5a775165d4ea659fd004e7/novnc/docs/rfbproto-3.7.pdf -------------------------------------------------------------------------------- /novnc/docs/rfbproto-3.8.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solarkennedy/ipmi-kvm-docker/26002abba9b39f574a5a775165d4ea659fd004e7/novnc/docs/rfbproto-3.8.pdf -------------------------------------------------------------------------------- /novnc/favicon.ico: -------------------------------------------------------------------------------- 1 | images/favicon.ico -------------------------------------------------------------------------------- /novnc/images/alt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solarkennedy/ipmi-kvm-docker/26002abba9b39f574a5a775165d4ea659fd004e7/novnc/images/alt.png -------------------------------------------------------------------------------- /novnc/images/clipboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solarkennedy/ipmi-kvm-docker/26002abba9b39f574a5a775165d4ea659fd004e7/novnc/images/clipboard.png -------------------------------------------------------------------------------- /novnc/images/connect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solarkennedy/ipmi-kvm-docker/26002abba9b39f574a5a775165d4ea659fd004e7/novnc/images/connect.png -------------------------------------------------------------------------------- /novnc/images/ctrl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solarkennedy/ipmi-kvm-docker/26002abba9b39f574a5a775165d4ea659fd004e7/novnc/images/ctrl.png -------------------------------------------------------------------------------- /novnc/images/ctrlaltdel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solarkennedy/ipmi-kvm-docker/26002abba9b39f574a5a775165d4ea659fd004e7/novnc/images/ctrlaltdel.png -------------------------------------------------------------------------------- /novnc/images/disconnect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solarkennedy/ipmi-kvm-docker/26002abba9b39f574a5a775165d4ea659fd004e7/novnc/images/disconnect.png -------------------------------------------------------------------------------- /novnc/images/drag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solarkennedy/ipmi-kvm-docker/26002abba9b39f574a5a775165d4ea659fd004e7/novnc/images/drag.png -------------------------------------------------------------------------------- /novnc/images/esc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solarkennedy/ipmi-kvm-docker/26002abba9b39f574a5a775165d4ea659fd004e7/novnc/images/esc.png -------------------------------------------------------------------------------- /novnc/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solarkennedy/ipmi-kvm-docker/26002abba9b39f574a5a775165d4ea659fd004e7/novnc/images/favicon.ico -------------------------------------------------------------------------------- /novnc/images/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solarkennedy/ipmi-kvm-docker/26002abba9b39f574a5a775165d4ea659fd004e7/novnc/images/favicon.png -------------------------------------------------------------------------------- /novnc/images/keyboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solarkennedy/ipmi-kvm-docker/26002abba9b39f574a5a775165d4ea659fd004e7/novnc/images/keyboard.png -------------------------------------------------------------------------------- /novnc/images/mouse_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solarkennedy/ipmi-kvm-docker/26002abba9b39f574a5a775165d4ea659fd004e7/novnc/images/mouse_left.png -------------------------------------------------------------------------------- /novnc/images/mouse_middle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solarkennedy/ipmi-kvm-docker/26002abba9b39f574a5a775165d4ea659fd004e7/novnc/images/mouse_middle.png -------------------------------------------------------------------------------- /novnc/images/mouse_none.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solarkennedy/ipmi-kvm-docker/26002abba9b39f574a5a775165d4ea659fd004e7/novnc/images/mouse_none.png -------------------------------------------------------------------------------- /novnc/images/mouse_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solarkennedy/ipmi-kvm-docker/26002abba9b39f574a5a775165d4ea659fd004e7/novnc/images/mouse_right.png -------------------------------------------------------------------------------- /novnc/images/power.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solarkennedy/ipmi-kvm-docker/26002abba9b39f574a5a775165d4ea659fd004e7/novnc/images/power.png -------------------------------------------------------------------------------- /novnc/images/screen_320x460.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solarkennedy/ipmi-kvm-docker/26002abba9b39f574a5a775165d4ea659fd004e7/novnc/images/screen_320x460.png -------------------------------------------------------------------------------- /novnc/images/screen_57x57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solarkennedy/ipmi-kvm-docker/26002abba9b39f574a5a775165d4ea659fd004e7/novnc/images/screen_57x57.png -------------------------------------------------------------------------------- /novnc/images/screen_700x700.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solarkennedy/ipmi-kvm-docker/26002abba9b39f574a5a775165d4ea659fd004e7/novnc/images/screen_700x700.png -------------------------------------------------------------------------------- /novnc/images/settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solarkennedy/ipmi-kvm-docker/26002abba9b39f574a5a775165d4ea659fd004e7/novnc/images/settings.png -------------------------------------------------------------------------------- /novnc/images/showextrakeys.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solarkennedy/ipmi-kvm-docker/26002abba9b39f574a5a775165d4ea659fd004e7/novnc/images/showextrakeys.png -------------------------------------------------------------------------------- /novnc/images/tab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solarkennedy/ipmi-kvm-docker/26002abba9b39f574a5a775165d4ea659fd004e7/novnc/images/tab.png -------------------------------------------------------------------------------- /novnc/include/Orbitron700.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solarkennedy/ipmi-kvm-docker/26002abba9b39f574a5a775165d4ea659fd004e7/novnc/include/Orbitron700.ttf -------------------------------------------------------------------------------- /novnc/include/Orbitron700.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solarkennedy/ipmi-kvm-docker/26002abba9b39f574a5a775165d4ea659fd004e7/novnc/include/Orbitron700.woff -------------------------------------------------------------------------------- /novnc/include/base64.js: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 | 5 | // From: http://hg.mozilla.org/mozilla-central/raw-file/ec10630b1a54/js/src/devtools/jint/sunspider/string-base64.js 6 | 7 | /*jslint white: false */ 8 | /*global console */ 9 | 10 | var Base64 = { 11 | /* Convert data (an array of integers) to a Base64 string. */ 12 | toBase64Table : 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='.split(''), 13 | base64Pad : '=', 14 | 15 | encode: function (data) { 16 | "use strict"; 17 | var result = ''; 18 | var toBase64Table = Base64.toBase64Table; 19 | var length = data.length; 20 | var lengthpad = (length % 3); 21 | // Convert every three bytes to 4 ascii characters. 22 | 23 | for (var i = 0; i < (length - 2); i += 3) { 24 | result += toBase64Table[data[i] >> 2]; 25 | result += toBase64Table[((data[i] & 0x03) << 4) + (data[i + 1] >> 4)]; 26 | result += toBase64Table[((data[i + 1] & 0x0f) << 2) + (data[i + 2] >> 6)]; 27 | result += toBase64Table[data[i + 2] & 0x3f]; 28 | } 29 | 30 | // Convert the remaining 1 or 2 bytes, pad out to 4 characters. 31 | var j = 0; 32 | if (lengthpad === 2) { 33 | j = length - lengthpad; 34 | result += toBase64Table[data[j] >> 2]; 35 | result += toBase64Table[((data[j] & 0x03) << 4) + (data[j + 1] >> 4)]; 36 | result += toBase64Table[(data[j + 1] & 0x0f) << 2]; 37 | result += toBase64Table[64]; 38 | } else if (lengthpad === 1) { 39 | j = length - lengthpad; 40 | result += toBase64Table[data[j] >> 2]; 41 | result += toBase64Table[(data[j] & 0x03) << 4]; 42 | result += toBase64Table[64]; 43 | result += toBase64Table[64]; 44 | } 45 | 46 | return result; 47 | }, 48 | 49 | /* Convert Base64 data to a string */ 50 | /* jshint -W013 */ 51 | toBinaryTable : [ 52 | -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, 53 | -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, 54 | -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63, 55 | 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1, 0,-1,-1, 56 | -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14, 57 | 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1, 58 | -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, 59 | 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1 60 | ], 61 | /* jshint +W013 */ 62 | 63 | decode: function (data, offset) { 64 | "use strict"; 65 | offset = typeof(offset) !== 'undefined' ? offset : 0; 66 | var toBinaryTable = Base64.toBinaryTable; 67 | var base64Pad = Base64.base64Pad; 68 | var result, result_length; 69 | var leftbits = 0; // number of bits decoded, but yet to be appended 70 | var leftdata = 0; // bits decoded, but yet to be appended 71 | var data_length = data.indexOf('=') - offset; 72 | 73 | if (data_length < 0) { data_length = data.length - offset; } 74 | 75 | /* Every four characters is 3 resulting numbers */ 76 | result_length = (data_length >> 2) * 3 + Math.floor((data_length % 4) / 1.5); 77 | result = new Array(result_length); 78 | 79 | // Convert one by one. 80 | for (var idx = 0, i = offset; i < data.length; i++) { 81 | var c = toBinaryTable[data.charCodeAt(i) & 0x7f]; 82 | var padding = (data.charAt(i) === base64Pad); 83 | // Skip illegal characters and whitespace 84 | if (c === -1) { 85 | console.error("Illegal character code " + data.charCodeAt(i) + " at position " + i); 86 | continue; 87 | } 88 | 89 | // Collect data into leftdata, update bitcount 90 | leftdata = (leftdata << 6) | c; 91 | leftbits += 6; 92 | 93 | // If we have 8 or more bits, append 8 bits to the result 94 | if (leftbits >= 8) { 95 | leftbits -= 8; 96 | // Append if not padding. 97 | if (!padding) { 98 | result[idx++] = (leftdata >> leftbits) & 0xff; 99 | } 100 | leftdata &= (1 << leftbits) - 1; 101 | } 102 | } 103 | 104 | // If there are any bits left, the base64 string was corrupted 105 | if (leftbits) { 106 | err = new Error('Corrupted base64 string'); 107 | err.name = 'Base64-Error'; 108 | throw err; 109 | } 110 | 111 | return result; 112 | } 113 | }; /* End of Base64 namespace */ 114 | -------------------------------------------------------------------------------- /novnc/include/black.css: -------------------------------------------------------------------------------- 1 | /* 2 | * noVNC black CSS 3 | * Copyright (C) 2012 Joel Martin 4 | * Copyright (C) 2013 Samuel Mannehed for Cendio AB 5 | * noVNC is licensed under the MPL 2.0 (see LICENSE.txt) 6 | * This file is licensed under the 2-Clause BSD license (see LICENSE.txt). 7 | */ 8 | 9 | #keyboardinput { 10 | background-color:#000; 11 | } 12 | 13 | .noVNC_status_normal { 14 | background: #4c4c4c; /* Old browsers */ 15 | background: -moz-linear-gradient(top, #4c4c4c 0%, #2c2c2c 50%, #000000 51%, #131313 100%); /* FF3.6+ */ 16 | background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#4c4c4c), color-stop(50%,#2c2c2c), color-stop(51%,#000000), color-stop(100%,#131313)); /* Chrome,Safari4+ */ 17 | background: -webkit-linear-gradient(top, #4c4c4c 0%,#2c2c2c 50%,#000000 51%,#131313 100%); /* Chrome10+,Safari5.1+ */ 18 | background: -o-linear-gradient(top, #4c4c4c 0%,#2c2c2c 50%,#000000 51%,#131313 100%); /* Opera11.10+ */ 19 | background: -ms-linear-gradient(top, #4c4c4c 0%,#2c2c2c 50%,#000000 51%,#131313 100%); /* IE10+ */ 20 | background: linear-gradient(top, #4c4c4c 0%,#2c2c2c 50%,#000000 51%,#131313 100%); /* W3C */ 21 | } 22 | .noVNC_status_error { 23 | background: #f04040; /* Old browsers */ 24 | background: -moz-linear-gradient(top, #f04040 0%, #2c2c2c 50%, #000000 51%, #131313 100%); /* FF3.6+ */ 25 | background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f04040), color-stop(50%,#2c2c2c), color-stop(51%,#000000), color-stop(100%,#131313)); /* Chrome,Safari4+ */ 26 | background: -webkit-linear-gradient(top, #f04040 0%,#2c2c2c 50%,#000000 51%,#131313 100%); /* Chrome10+,Safari5.1+ */ 27 | background: -o-linear-gradient(top, #f04040 0%,#2c2c2c 50%,#000000 51%,#131313 100%); /* Opera11.10+ */ 28 | background: -ms-linear-gradient(top, #f04040 0%,#2c2c2c 50%,#000000 51%,#131313 100%); /* IE10+ */ 29 | background: linear-gradient(top, #f04040 0%,#2c2c2c 50%,#000000 51%,#131313 100%); /* W3C */ 30 | } 31 | .noVNC_status_warn { 32 | background: #f0f040; /* Old browsers */ 33 | background: -moz-linear-gradient(top, #f0f040 0%, #2c2c2c 50%, #000000 51%, #131313 100%); /* FF3.6+ */ 34 | background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f0f040), color-stop(50%,#2c2c2c), color-stop(51%,#000000), color-stop(100%,#131313)); /* Chrome,Safari4+ */ 35 | background: -webkit-linear-gradient(top, #f0f040 0%,#2c2c2c 50%,#000000 51%,#131313 100%); /* Chrome10+,Safari5.1+ */ 36 | background: -o-linear-gradient(top, #f0f040 0%,#2c2c2c 50%,#000000 51%,#131313 100%); /* Opera11.10+ */ 37 | background: -ms-linear-gradient(top, #f0f040 0%,#2c2c2c 50%,#000000 51%,#131313 100%); /* IE10+ */ 38 | background: linear-gradient(top, #f0f040 0%,#2c2c2c 50%,#000000 51%,#131313 100%); /* W3C */ 39 | } 40 | 41 | .triangle-right { 42 | border:2px solid #fff; 43 | background:#000; 44 | color:#fff; 45 | } 46 | 47 | .noVNC_status_button { 48 | font-size: 12px; 49 | vertical-align: middle; 50 | border:1px solid #4c4c4c; 51 | 52 | background: #4c4c4c; /* Old browsers */ 53 | background: -moz-linear-gradient(top, #4c4c4c 0%, #2c2c2c 50%, #000000 51%, #131313 100%); /* FF3.6+ */ 54 | background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#4c4c4c), color-stop(50%,#2c2c2c), color-stop(51%,#000000), color-stop(100%,#131313)); /* Chrome,Safari4+ */ 55 | background: -webkit-linear-gradient(top, #4c4c4c 0%,#2c2c2c 50%,#000000 51%,#131313 100%); /* Chrome10+,Safari5.1+ */ 56 | background: -o-linear-gradient(top, #4c4c4c 0%,#2c2c2c 50%,#000000 51%,#131313 100%); /* Opera11.10+ */ 57 | background: -ms-linear-gradient(top, #4c4c4c 0%,#2c2c2c 50%,#000000 51%,#131313 100%); /* IE10+ */ 58 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#4c4c4c', endColorstr='#131313',GradientType=0 ); /* IE6-9 */ 59 | background: linear-gradient(top, #4c4c4c 0%,#2c2c2c 50%,#000000 51%,#131313 100%); /* W3C */ 60 | } 61 | 62 | .noVNC_status_button_selected { 63 | background: #9dd53a; /* Old browsers */ 64 | background: -moz-linear-gradient(top, #9dd53a 0%, #a1d54f 50%, #80c217 51%, #7cbc0a 100%); /* FF3.6+ */ 65 | background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#9dd53a), color-stop(50%,#a1d54f), color-stop(51%,#80c217), color-stop(100%,#7cbc0a)); /* Chrome,Safari4+ */ 66 | background: -webkit-linear-gradient(top, #9dd53a 0%,#a1d54f 50%,#80c217 51%,#7cbc0a 100%); /* Chrome10+,Safari5.1+ */ 67 | background: -o-linear-gradient(top, #9dd53a 0%,#a1d54f 50%,#80c217 51%,#7cbc0a 100%); /* Opera11.10+ */ 68 | background: -ms-linear-gradient(top, #9dd53a 0%,#a1d54f 50%,#80c217 51%,#7cbc0a 100%); /* IE10+ */ 69 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#9dd53a', endColorstr='#7cbc0a',GradientType=0 ); /* IE6-9 */ 70 | background: linear-gradient(top, #9dd53a 0%,#a1d54f 50%,#80c217 51%,#7cbc0a 100%); /* W3C */ 71 | } 72 | -------------------------------------------------------------------------------- /novnc/include/blue.css: -------------------------------------------------------------------------------- 1 | /* 2 | * noVNC blue CSS 3 | * Copyright (C) 2012 Joel Martin 4 | * Copyright (C) 2013 Samuel Mannehed for Cendio AB 5 | * noVNC is licensed under the MPL 2.0 (see LICENSE.txt) 6 | * This file is licensed under the 2-Clause BSD license (see LICENSE.txt). 7 | */ 8 | 9 | .noVNC_status_normal { 10 | background-color:#04073d; 11 | background-image: -webkit-gradient( 12 | linear, 13 | left bottom, 14 | left top, 15 | color-stop(0.54, rgb(10,15,79)), 16 | color-stop(0.5, rgb(4,7,61)) 17 | ); 18 | background-image: -moz-linear-gradient( 19 | center bottom, 20 | rgb(10,15,79) 54%, 21 | rgb(4,7,61) 50% 22 | ); 23 | } 24 | .noVNC_status_error { 25 | background-color:#f04040; 26 | background-image: -webkit-gradient( 27 | linear, 28 | left bottom, 29 | left top, 30 | color-stop(0.54, rgb(240,64,64)), 31 | color-stop(0.5, rgb(4,7,61)) 32 | ); 33 | background-image: -moz-linear-gradient( 34 | center bottom, 35 | rgb(4,7,61) 54%, 36 | rgb(249,64,64) 50% 37 | ); 38 | } 39 | .noVNC_status_warn { 40 | background-color:#f0f040; 41 | background-image: -webkit-gradient( 42 | linear, 43 | left bottom, 44 | left top, 45 | color-stop(0.54, rgb(240,240,64)), 46 | color-stop(0.5, rgb(4,7,61)) 47 | ); 48 | background-image: -moz-linear-gradient( 49 | center bottom, 50 | rgb(4,7,61) 54%, 51 | rgb(240,240,64) 50% 52 | ); 53 | } 54 | 55 | .triangle-right { 56 | border:2px solid #fff; 57 | background:#04073d; 58 | color:#fff; 59 | } 60 | 61 | #keyboardinput { 62 | background-color:#04073d; 63 | } 64 | 65 | -------------------------------------------------------------------------------- /novnc/include/playback.js: -------------------------------------------------------------------------------- 1 | /* 2 | * noVNC: HTML5 VNC client 3 | * Copyright (C) 2012 Joel Martin 4 | * Licensed under MPL 2.0 (see LICENSE.txt) 5 | */ 6 | 7 | "use strict"; 8 | /*jslint browser: true, white: false */ 9 | /*global Util, VNC_frame_data, finish */ 10 | 11 | var rfb, mode, test_state, frame_idx, frame_length, 12 | iteration, iterations, istart_time, 13 | 14 | // Pre-declarations for jslint 15 | send_array, next_iteration, queue_next_packet, do_packet; 16 | 17 | // Override send_array 18 | send_array = function (arr) { 19 | // Stub out send_array 20 | }; 21 | 22 | next_iteration = function () { 23 | if (iteration === 0) { 24 | frame_length = VNC_frame_data.length; 25 | test_state = 'running'; 26 | } else { 27 | rfb.disconnect(); 28 | } 29 | 30 | if (test_state !== 'running') { return; } 31 | 32 | iteration += 1; 33 | if (iteration > iterations) { 34 | finish(); 35 | return; 36 | } 37 | 38 | frame_idx = 0; 39 | istart_time = (new Date()).getTime(); 40 | rfb.connect('test', 0, "bogus"); 41 | 42 | queue_next_packet(); 43 | 44 | }; 45 | 46 | queue_next_packet = function () { 47 | var frame, foffset, toffset, delay; 48 | if (test_state !== 'running') { return; } 49 | 50 | frame = VNC_frame_data[frame_idx]; 51 | while ((frame_idx < frame_length) && (frame.charAt(0) === "}")) { 52 | //Util.Debug("Send frame " + frame_idx); 53 | frame_idx += 1; 54 | frame = VNC_frame_data[frame_idx]; 55 | } 56 | 57 | if (frame === 'EOF') { 58 | Util.Debug("Finished, found EOF"); 59 | next_iteration(); 60 | return; 61 | } 62 | if (frame_idx >= frame_length) { 63 | Util.Debug("Finished, no more frames"); 64 | next_iteration(); 65 | return; 66 | } 67 | 68 | if (mode === 'realtime') { 69 | foffset = frame.slice(1, frame.indexOf('{', 1)); 70 | toffset = (new Date()).getTime() - istart_time; 71 | delay = foffset - toffset; 72 | if (delay < 1) { 73 | delay = 1; 74 | } 75 | 76 | setTimeout(do_packet, delay); 77 | } else { 78 | setTimeout(do_packet, 1); 79 | } 80 | }; 81 | 82 | var bytes_processed = 0; 83 | 84 | do_packet = function () { 85 | //Util.Debug("Processing frame: " + frame_idx); 86 | var frame = VNC_frame_data[frame_idx], 87 | start = frame.indexOf('{', 1) + 1; 88 | bytes_processed += frame.length - start; 89 | if (VNC_frame_encoding === 'binary') { 90 | var u8 = new Uint8Array(frame.length - start); 91 | for (var i = 0; i < frame.length - start; i++) { 92 | u8[i] = frame.charCodeAt(start + i); 93 | } 94 | rfb.recv_message({'data' : u8}); 95 | } else { 96 | rfb.recv_message({'data' : frame.slice(start)}); 97 | } 98 | frame_idx += 1; 99 | 100 | queue_next_packet(); 101 | }; 102 | 103 | -------------------------------------------------------------------------------- /novnc/include/web-socket-js/README.txt: -------------------------------------------------------------------------------- 1 | * How to try 2 | 3 | Assuming you have Web server (e.g. Apache) running at http://example.com/ . 4 | 5 | - Download web_socket.rb from: 6 | http://github.com/gimite/web-socket-ruby/tree/master 7 | - Run sample Web Socket server (echo server) in example.com with: (#1) 8 | $ ruby web-socket-ruby/samples/echo_server.rb example.com 10081 9 | - If your server already provides socket policy file at port 843, modify the file to allow access to port 10081. Otherwise you can skip this step. See below for details. 10 | - Publish the web-socket-js directory with your Web server (e.g. put it in ~/public_html). 11 | - Change ws://localhost:10081 to ws://example.com:10081 in sample.html. 12 | - Open sample.html in your browser. 13 | - After "onopen" is shown, input something, click [Send] and confirm echo back. 14 | 15 | #1: First argument of echo_server.rb means that it accepts Web Socket connection from HTML pages in example.com. 16 | 17 | 18 | * Troubleshooting 19 | 20 | If it doesn't work, try these: 21 | 22 | 1. Try Chrome and Firefox 3.x. 23 | - It doesn't work on Chrome: 24 | -- It's likely an issue of your code or the server. Debug your code as usual e.g. using console.log. 25 | - It works on Chrome but it doesn't work on Firefox: 26 | -- It's likely an issue of web-socket-js specific configuration (e.g. 3 and 4 below). 27 | - It works on both Chrome and Firefox, but it doesn't work on your browser: 28 | -- Check "Supported environment" section below. Your browser may not be supported by web-socket-js. 29 | 30 | 2. Add this line before your code: 31 | WEB_SOCKET_DEBUG = true; 32 | and use Developer Tools (Chrome/Safari) or Firebug (Firefox) to see if console.log outputs any errors. 33 | 34 | 3. Make sure you do NOT open your HTML page as local file e.g. file:///.../sample.html. web-socket-js doesn't work on local file. Open it via Web server e.g. http:///.../sample.html. 35 | 36 | 4. If you are NOT using web-socket-ruby as your WebSocket server, you need to place Flash socket policy file on your server. See "Flash socket policy file" section below for details. 37 | 38 | 5. Check if sample.html bundled with web-socket-js works. 39 | 40 | 6. Make sure the port used for WebSocket (10081 in example above) is not blocked by your server/client's firewall. 41 | 42 | 7. Install debugger version of Flash Player available here to see Flash errors: 43 | http://www.adobe.com/support/flashplayer/downloads.html 44 | 45 | 46 | * Supported environments 47 | 48 | It should work on: 49 | - Google Chrome 4 or later (just uses native implementation) 50 | - Firefox 3.x, Internet Explorer 8 + Flash Player 9 or later 51 | 52 | It may or may not work on other browsers such as Safari, Opera or IE 6. Patch for these browsers are appreciated, but I will not work on fixing issues specific to these browsers by myself. 53 | 54 | 55 | * Flash socket policy file 56 | 57 | This implementation uses Flash's socket, which means that your server must provide Flash socket policy file to declare the server accepts connections from Flash. 58 | 59 | If you use web-socket-ruby available at 60 | http://github.com/gimite/web-socket-ruby/tree/master 61 | , you don't need anything special, because web-socket-ruby handles Flash socket policy file request. But if you already provide socket policy file at port 843, you need to modify the file to allow access to Web Socket port, because it precedes what web-socket-ruby provides. 62 | 63 | If you use other Web Socket server implementation, you need to provide socket policy file yourself. See 64 | http://www.lightsphere.com/dev/articles/flash_socket_policy.html 65 | for details and sample script to run socket policy file server. node.js implementation is available here: 66 | http://github.com/LearnBoost/Socket.IO-node/blob/master/lib/socket.io/transports/flashsocket.js 67 | 68 | Actually, it's still better to provide socket policy file at port 843 even if you use web-socket-ruby. Flash always try to connect to port 843 first, so providing the file at port 843 makes startup faster. 69 | 70 | 71 | * Cookie considerations 72 | 73 | Cookie is sent if Web Socket host is the same as the origin of JavaScript. Otherwise it is not sent, because I don't know way to send right Cookie (which is Cookie of the host of Web Socket, I heard). 74 | 75 | Note that it's technically possible that client sends arbitrary string as Cookie and any other headers (by modifying this library for example) once you place Flash socket policy file in your server. So don't trust Cookie and other headers if you allow connection from untrusted origin. 76 | 77 | 78 | * Proxy considerations 79 | 80 | The WebSocket spec (http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol) specifies instructions for User Agents to support proxied connections by implementing the HTTP CONNECT method. 81 | 82 | The AS3 Socket class doesn't implement this mechanism, which renders it useless for the scenarios where the user trying to open a socket is behind a proxy. 83 | 84 | The class RFC2817Socket (by Christian Cantrell) effectively lets us implement this, as long as the proxy settings are known and provided by the interface that instantiates the WebSocket. As such, if you want to support proxied conncetions, you'll have to supply this information to the WebSocket constructor when Flash is being used. One way to go about it would be to ask the user for proxy settings information if the initial connection fails. 85 | 86 | 87 | * How to host HTML file and SWF file in different domains 88 | 89 | By default, HTML file and SWF file must be in the same domain. You can follow steps below to allow hosting them in different domain. 90 | 91 | WARNING: If you use the method below, HTML files in ANY domains can send arbitrary TCP data to your WebSocket server, regardless of configuration in Flash socket policy file. Arbitrary TCP data means that they can even fake request headers including Origin and Cookie. 92 | 93 | - Unzip WebSocketMainInsecure.zip to extract WebSocketMainInsecure.swf. 94 | - Put WebSocketMainInsecure.swf on your server, instead of WebSocketMain.swf. 95 | - In JavaScript, set WEB_SOCKET_SWF_LOCATION to URL of your WebSocketMainInsecure.swf. 96 | 97 | 98 | * How to build WebSocketMain.swf 99 | 100 | Install Flex 4 SDK: 101 | http://opensource.adobe.com/wiki/display/flexsdk/Download+Flex+4 102 | 103 | $ cd flash-src 104 | $ ./build.sh 105 | 106 | 107 | * License 108 | 109 | New BSD License. 110 | -------------------------------------------------------------------------------- /novnc/include/web-socket-js/WebSocketMain.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solarkennedy/ipmi-kvm-docker/26002abba9b39f574a5a775165d4ea659fd004e7/novnc/include/web-socket-js/WebSocketMain.swf -------------------------------------------------------------------------------- /novnc/include/web-socket-js/swfobject.js: -------------------------------------------------------------------------------- 1 | /* SWFObject v2.2 2 | is released under the MIT License 3 | */ 4 | var swfobject=function(){var D="undefined",r="object",S="Shockwave Flash",W="ShockwaveFlash.ShockwaveFlash",q="application/x-shockwave-flash",R="SWFObjectExprInst",x="onreadystatechange",O=window,j=document,t=navigator,T=false,U=[h],o=[],N=[],I=[],l,Q,E,B,J=false,a=false,n,G,m=true,M=function(){var aa=typeof j.getElementById!=D&&typeof j.getElementsByTagName!=D&&typeof j.createElement!=D,ah=t.userAgent.toLowerCase(),Y=t.platform.toLowerCase(),ae=Y?/win/.test(Y):/win/.test(ah),ac=Y?/mac/.test(Y):/mac/.test(ah),af=/webkit/.test(ah)?parseFloat(ah.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,X=!+"\v1",ag=[0,0,0],ab=null;if(typeof t.plugins!=D&&typeof t.plugins[S]==r){ab=t.plugins[S].description;if(ab&&!(typeof t.mimeTypes!=D&&t.mimeTypes[q]&&!t.mimeTypes[q].enabledPlugin)){T=true;X=false;ab=ab.replace(/^.*\s+(\S+\s+\S+$)/,"$1");ag[0]=parseInt(ab.replace(/^(.*)\..*$/,"$1"),10);ag[1]=parseInt(ab.replace(/^.*\.(.*)\s.*$/,"$1"),10);ag[2]=/[a-zA-Z]/.test(ab)?parseInt(ab.replace(/^.*[a-zA-Z]+(.*)$/,"$1"),10):0}}else{if(typeof O.ActiveXObject!=D){try{var ad=new ActiveXObject(W);if(ad){ab=ad.GetVariable("$version");if(ab){X=true;ab=ab.split(" ")[1].split(",");ag=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}}catch(Z){}}}return{w3:aa,pv:ag,wk:af,ie:X,win:ae,mac:ac}}(),k=function(){if(!M.w3){return}if((typeof j.readyState!=D&&j.readyState=="complete")||(typeof j.readyState==D&&(j.getElementsByTagName("body")[0]||j.body))){f()}if(!J){if(typeof j.addEventListener!=D){j.addEventListener("DOMContentLoaded",f,false)}if(M.ie&&M.win){j.attachEvent(x,function(){if(j.readyState=="complete"){j.detachEvent(x,arguments.callee);f()}});if(O==top){(function(){if(J){return}try{j.documentElement.doScroll("left")}catch(X){setTimeout(arguments.callee,0);return}f()})()}}if(M.wk){(function(){if(J){return}if(!/loaded|complete/.test(j.readyState)){setTimeout(arguments.callee,0);return}f()})()}s(f)}}();function f(){if(J){return}try{var Z=j.getElementsByTagName("body")[0].appendChild(C("span"));Z.parentNode.removeChild(Z)}catch(aa){return}J=true;var X=U.length;for(var Y=0;Y0){for(var af=0;af0){var ae=c(Y);if(ae){if(F(o[af].swfVersion)&&!(M.wk&&M.wk<312)){w(Y,true);if(ab){aa.success=true;aa.ref=z(Y);ab(aa)}}else{if(o[af].expressInstall&&A()){var ai={};ai.data=o[af].expressInstall;ai.width=ae.getAttribute("width")||"0";ai.height=ae.getAttribute("height")||"0";if(ae.getAttribute("class")){ai.styleclass=ae.getAttribute("class")}if(ae.getAttribute("align")){ai.align=ae.getAttribute("align")}var ah={};var X=ae.getElementsByTagName("param");var ac=X.length;for(var ad=0;ad'}}aa.outerHTML='"+af+"";N[N.length]=ai.id;X=c(ai.id)}else{var Z=C(r);Z.setAttribute("type",q);for(var ac in ai){if(ai[ac]!=Object.prototype[ac]){if(ac.toLowerCase()=="styleclass"){Z.setAttribute("class",ai[ac])}else{if(ac.toLowerCase()!="classid"){Z.setAttribute(ac,ai[ac])}}}}for(var ab in ag){if(ag[ab]!=Object.prototype[ab]&&ab.toLowerCase()!="movie"){e(Z,ab,ag[ab])}}aa.parentNode.replaceChild(Z,aa);X=Z}}return X}function e(Z,X,Y){var aa=C("param");aa.setAttribute("name",X);aa.setAttribute("value",Y);Z.appendChild(aa)}function y(Y){var X=c(Y);if(X&&X.nodeName=="OBJECT"){if(M.ie&&M.win){X.style.display="none";(function(){if(X.readyState==4){b(Y)}else{setTimeout(arguments.callee,10)}})()}else{X.parentNode.removeChild(X)}}}function b(Z){var Y=c(Z);if(Y){for(var X in Y){if(typeof Y[X]=="function"){Y[X]=null}}Y.parentNode.removeChild(Y)}}function c(Z){var X=null;try{X=j.getElementById(Z)}catch(Y){}return X}function C(X){return j.createElement(X)}function i(Z,X,Y){Z.attachEvent(X,Y);I[I.length]=[Z,X,Y]}function F(Z){var Y=M.pv,X=Z.split(".");X[0]=parseInt(X[0],10);X[1]=parseInt(X[1],10)||0;X[2]=parseInt(X[2],10)||0;return(Y[0]>X[0]||(Y[0]==X[0]&&Y[1]>X[1])||(Y[0]==X[0]&&Y[1]==X[1]&&Y[2]>=X[2]))?true:false}function v(ac,Y,ad,ab){if(M.ie&&M.mac){return}var aa=j.getElementsByTagName("head")[0];if(!aa){return}var X=(ad&&typeof ad=="string")?ad:"screen";if(ab){n=null;G=null}if(!n||G!=X){var Z=C("style");Z.setAttribute("type","text/css");Z.setAttribute("media",X);n=aa.appendChild(Z);if(M.ie&&M.win&&typeof j.styleSheets!=D&&j.styleSheets.length>0){n=j.styleSheets[j.styleSheets.length-1]}G=X}if(M.ie&&M.win){if(n&&typeof n.addRule==r){n.addRule(ac,Y)}}else{if(n&&typeof j.createTextNode!=D){n.appendChild(j.createTextNode(ac+" {"+Y+"}"))}}}function w(Z,X){if(!m){return}var Y=X?"visible":"hidden";if(J&&c(Z)){c(Z).style.visibility=Y}else{v("#"+Z,"visibility:"+Y)}}function L(Y){var Z=/[\\\"<>\.;]/;var X=Z.exec(Y)!=null;return X&&typeof encodeURIComponent!=D?encodeURIComponent(Y):Y}var d=function(){if(M.ie&&M.win){window.attachEvent("onunload",function(){var ac=I.length;for(var ab=0;ab 1) && (typeof obj[i] === "object")) { 61 | // Recurse attributes that are objects 62 | msg += WebUtil.dirObj(obj[i], depth - 1, parent + "." + i); 63 | } else { 64 | //val = new String(obj[i]).replace("\n", " "); 65 | var val = ""; 66 | if (typeof(obj[i]) === "undefined") { 67 | val = "undefined"; 68 | } else { 69 | val = obj[i].toString().replace("\n", " "); 70 | } 71 | if (val.length > 30) { 72 | val = val.substr(0, 30) + "..."; 73 | } 74 | msg += parent + "." + i + ": " + val + "\n"; 75 | } 76 | } 77 | return msg; 78 | }; 79 | 80 | // Read a query string variable 81 | WebUtil.getQueryVar = function (name, defVal) { 82 | "use strict"; 83 | var re = new RegExp('.*[?&]' + name + '=([^&#]*)'), 84 | match = document.location.href.match(re); 85 | if (typeof defVal === 'undefined') { defVal = null; } 86 | if (match) { 87 | return decodeURIComponent(match[1]); 88 | } else { 89 | return defVal; 90 | } 91 | }; 92 | 93 | 94 | /* 95 | * Cookie handling. Dervied from: http://www.quirksmode.org/js/cookies.html 96 | */ 97 | 98 | // No days means only for this browser session 99 | WebUtil.createCookie = function (name, value, days) { 100 | "use strict"; 101 | var date, expires; 102 | if (days) { 103 | date = new Date(); 104 | date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); 105 | expires = "; expires=" + date.toGMTString(); 106 | } else { 107 | expires = ""; 108 | } 109 | 110 | var secure; 111 | if (document.location.protocol === "https:") { 112 | secure = "; secure"; 113 | } else { 114 | secure = ""; 115 | } 116 | document.cookie = name + "=" + value + expires + "; path=/" + secure; 117 | }; 118 | 119 | WebUtil.readCookie = function (name, defaultValue) { 120 | "use strict"; 121 | var nameEQ = name + "=", 122 | ca = document.cookie.split(';'); 123 | 124 | for (var i = 0; i < ca.length; i += 1) { 125 | var c = ca[i]; 126 | while (c.charAt(0) === ' ') { c = c.substring(1, c.length); } 127 | if (c.indexOf(nameEQ) === 0) { return c.substring(nameEQ.length, c.length); } 128 | } 129 | return (typeof defaultValue !== 'undefined') ? defaultValue : null; 130 | }; 131 | 132 | WebUtil.eraseCookie = function (name) { 133 | "use strict"; 134 | WebUtil.createCookie(name, "", -1); 135 | }; 136 | 137 | /* 138 | * Setting handling. 139 | */ 140 | 141 | WebUtil.initSettings = function (callback /*, ...callbackArgs */) { 142 | "use strict"; 143 | var callbackArgs = Array.prototype.slice.call(arguments, 1); 144 | if (window.chrome && window.chrome.storage) { 145 | window.chrome.storage.sync.get(function (cfg) { 146 | WebUtil.settings = cfg; 147 | console.log(WebUtil.settings); 148 | if (callback) { 149 | callback.apply(this, callbackArgs); 150 | } 151 | }); 152 | } else { 153 | // No-op 154 | if (callback) { 155 | callback.apply(this, callbackArgs); 156 | } 157 | } 158 | }; 159 | 160 | // No days means only for this browser session 161 | WebUtil.writeSetting = function (name, value) { 162 | "use strict"; 163 | if (window.chrome && window.chrome.storage) { 164 | //console.log("writeSetting:", name, value); 165 | if (WebUtil.settings[name] !== value) { 166 | WebUtil.settings[name] = value; 167 | window.chrome.storage.sync.set(WebUtil.settings); 168 | } 169 | } else { 170 | localStorage.setItem(name, value); 171 | } 172 | }; 173 | 174 | WebUtil.readSetting = function (name, defaultValue) { 175 | "use strict"; 176 | var value; 177 | if (window.chrome && window.chrome.storage) { 178 | value = WebUtil.settings[name]; 179 | } else { 180 | value = localStorage.getItem(name); 181 | } 182 | if (typeof value === "undefined") { 183 | value = null; 184 | } 185 | if (value === null && typeof defaultValue !== undefined) { 186 | return defaultValue; 187 | } else { 188 | return value; 189 | } 190 | }; 191 | 192 | WebUtil.eraseSetting = function (name) { 193 | "use strict"; 194 | if (window.chrome && window.chrome.storage) { 195 | window.chrome.storage.sync.remove(name); 196 | delete WebUtil.settings[name]; 197 | } else { 198 | localStorage.removeItem(name); 199 | } 200 | }; 201 | 202 | /* 203 | * Alternate stylesheet selection 204 | */ 205 | WebUtil.getStylesheets = function () { 206 | "use strict"; 207 | var links = document.getElementsByTagName("link"); 208 | var sheets = []; 209 | 210 | for (var i = 0; i < links.length; i += 1) { 211 | if (links[i].title && 212 | links[i].rel.toUpperCase().indexOf("STYLESHEET") > -1) { 213 | sheets.push(links[i]); 214 | } 215 | } 216 | return sheets; 217 | }; 218 | 219 | // No sheet means try and use value from cookie, null sheet used to 220 | // clear all alternates. 221 | WebUtil.selectStylesheet = function (sheet) { 222 | "use strict"; 223 | if (typeof sheet === 'undefined') { 224 | sheet = 'default'; 225 | } 226 | 227 | var sheets = WebUtil.getStylesheets(); 228 | for (var i = 0; i < sheets.length; i += 1) { 229 | var link = sheets[i]; 230 | if (link.title === sheet) { 231 | Util.Debug("Using stylesheet " + sheet); 232 | link.disabled = false; 233 | } else { 234 | //Util.Debug("Skipping stylesheet " + link.title); 235 | link.disabled = true; 236 | } 237 | } 238 | return sheet; 239 | }; 240 | -------------------------------------------------------------------------------- /novnc/index.html: -------------------------------------------------------------------------------- 1 | vnc_auto.html -------------------------------------------------------------------------------- /novnc/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration 2 | 3 | module.exports = function(config) { 4 | /*var customLaunchers = { 5 | sl_chrome_win7: { 6 | base: 'SauceLabs', 7 | browserName: 'chrome', 8 | platform: 'Windows 7' 9 | }, 10 | 11 | sl_firefox30_linux: { 12 | base: 'SauceLabs', 13 | browserName: 'firefox', 14 | version: '30', 15 | platform: 'Linux' 16 | }, 17 | 18 | sl_firefox26_linux: { 19 | base: 'SauceLabs', 20 | browserName: 'firefox', 21 | version: 26, 22 | platform: 'Linux' 23 | }, 24 | 25 | sl_windows7_ie10: { 26 | base: 'SauceLabs', 27 | browserName: 'internet explorer', 28 | platform: 'Windows 7', 29 | version: '10' 30 | }, 31 | 32 | sl_windows81_ie11: { 33 | base: 'SauceLabs', 34 | browserName: 'internet explorer', 35 | platform: 'Windows 8.1', 36 | version: '11' 37 | }, 38 | 39 | sl_osxmavericks_safari7: { 40 | base: 'SauceLabs', 41 | browserName: 'safari', 42 | platform: 'OS X 10.9', 43 | version: '7' 44 | }, 45 | 46 | sl_osxmtnlion_safari6: { 47 | base: 'SauceLabs', 48 | browserName: 'safari', 49 | platform: 'OS X 10.8', 50 | version: '6' 51 | } 52 | };*/ 53 | 54 | var customLaunchers = {}; 55 | var browsers = []; 56 | var useSauce = false; 57 | 58 | if (process.env.SAUCE_USERNAME && process.env.SAUCE_ACCESS_KEY) { 59 | useSauce = true; 60 | } 61 | 62 | if (useSauce && process.env.TEST_BROWSER_NAME && process.env.TEST_BROWSER_NAME != 'PhantomJS') { 63 | var names = process.env.TEST_BROWSER_NAME.split(','); 64 | var platforms = process.env.TEST_BROWSER_OS.split(','); 65 | var versions = []; 66 | if (process.env.TEST_BROWSER_VERSION) { 67 | versions = process.env.TEST_BROWSER_VERSION.split(','); 68 | } else { 69 | versions = [null]; 70 | } 71 | 72 | for (var i = 0; i < names.length; i++) { 73 | for (var j = 0; j < platforms.length; j++) { 74 | for (var k = 0; k < versions.length; k++) { 75 | var launcher_name = 'sl_' + platforms[j].replace(/[^a-zA-Z0-9]/g, '') + '_' + names[i]; 76 | if (versions[k]) { 77 | launcher_name += '_' + versions[k]; 78 | } 79 | 80 | customLaunchers[launcher_name] = { 81 | base: 'SauceLabs', 82 | browserName: names[i], 83 | platform: platforms[j], 84 | }; 85 | 86 | if (versions[i]) { 87 | customLaunchers[launcher_name].version = versions[k]; 88 | } 89 | } 90 | } 91 | } 92 | 93 | browsers = Object.keys(customLaunchers); 94 | } else { 95 | useSauce = false; 96 | browsers = ['PhantomJS']; 97 | } 98 | 99 | var my_conf = { 100 | 101 | // base path that will be used to resolve all patterns (eg. files, exclude) 102 | basePath: '', 103 | 104 | // frameworks to use 105 | // available frameworks: https://npmjs.org/browse/keyword/karma-adapter 106 | frameworks: ['mocha', 'sinon', 'chai', 'sinon-chai'], 107 | 108 | 109 | // list of files / patterns to load in the browser (loaded in order) 110 | files: [ 111 | 'tests/fake.*.js', 112 | 'tests/assertions.js', 113 | 'include/util.js', // load first to avoid issues, since methods are called immediately 114 | //'../include/*.js', 115 | 'include/base64.js', 116 | 'include/keysym.js', 117 | 'include/keysymdef.js', 118 | 'include/keyboard.js', 119 | 'include/input.js', 120 | 'include/websock.js', 121 | 'include/rfb.js', 122 | 'include/jsunzip.js', 123 | 'include/des.js', 124 | 'include/display.js', 125 | 'tests/test.*.js' 126 | ], 127 | 128 | client: { 129 | mocha: { 130 | 'ui': 'bdd' 131 | } 132 | }, 133 | 134 | // list of files to exclude 135 | exclude: [ 136 | '../include/playback.js', 137 | '../include/ui.js' 138 | ], 139 | 140 | customLaunchers: customLaunchers, 141 | 142 | // start these browsers 143 | // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher 144 | browsers: browsers, 145 | 146 | // preprocess matching files before serving them to the browser 147 | // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor 148 | preprocessors: { 149 | 150 | }, 151 | 152 | 153 | // test results reporter to use 154 | // possible values: 'dots', 'progress' 155 | // available reporters: https://npmjs.org/browse/keyword/karma-reporter 156 | reporters: ['mocha', 'saucelabs'], 157 | 158 | 159 | // web server port 160 | port: 9876, 161 | 162 | 163 | // enable / disable colors in the output (reporters and logs) 164 | colors: true, 165 | 166 | 167 | // level of logging 168 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG 169 | logLevel: config.LOG_INFO, 170 | 171 | 172 | // enable / disable watching file and executing tests whenever any file changes 173 | autoWatch: false, 174 | 175 | // Continuous Integration mode 176 | // if true, Karma captures browsers, runs the tests and exits 177 | singleRun: true, 178 | 179 | // Increase timeout in case connection is slow/we run more browsers than possible 180 | // (we currently get 3 for free, and we try to run 7, so it can take a while) 181 | captureTimeout: 240000 182 | }; 183 | 184 | if (useSauce) { 185 | my_conf.captureTimeout = 0; // use SL timeout 186 | my_conf.sauceLabs = { 187 | testName: 'noVNC Tests (all)', 188 | startConnect: true, 189 | tunnelIdentifier: process.env.TRAVIS_JOB_NUMBER 190 | }; 191 | } 192 | 193 | config.set(my_conf); 194 | }; 195 | -------------------------------------------------------------------------------- /novnc/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "noVNC", 3 | "version": "0.5.0", 4 | "description": "An HTML5 VNC client", 5 | "main": "karma.conf.js", 6 | "directories": { 7 | "doc": "docs", 8 | "test": "tests" 9 | }, 10 | "scripts": { 11 | "test": "karma start karma.conf.js" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "https://github.com/kanaka/noVNC.git" 16 | }, 17 | "author": "Joel Martin (https://github.com/kanaka)", 18 | "contributors": [ 19 | "Solly Ross (https://github.com/directxman12)", 20 | "Peter Åstrand (https://github.com/astrand)", 21 | "Samuel Mannehed (https://github.com/samhed)" 22 | ], 23 | "license": "MPL 2.0", 24 | "bugs": { 25 | "url": "https://github.com/kanaka/noVNC/issues" 26 | }, 27 | "homepage": "https://github.com/kanaka/noVNC", 28 | "devDependencies": { 29 | "ansi": "^0.3.0", 30 | "casperjs": "^1.1.0-beta3", 31 | "chai": "^1.10.0", 32 | "commander": "^2.5.0", 33 | "karma": "^0.12.25", 34 | "karma-chai": "^0.1.0", 35 | "karma-mocha": "^0.1.9", 36 | "karma-mocha-reporter": "^0.3.1", 37 | "karma-phantomjs-launcher": "^0.1.4", 38 | "karma-sauce-launcher": "^0.2.10", 39 | "karma-sinon": "^1.0.3", 40 | "karma-sinon-chai-latest": "^0.1.0", 41 | "mocha": "^2.0.1", 42 | "open": "^0.0.5", 43 | "phantom": "^0.7.0", 44 | "phantomjs": "^1.9.12", 45 | "sinon": "^1.12.1", 46 | "sinon-chai": "^2.6.0", 47 | "spooky": "^0.2.5", 48 | "temp": "^0.8.1" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /novnc/tests/arrays.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Javascript Arrays Performance Test 5 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |

Javascript Arrays Performance Test

17 | Iterations:   18 | Array Size: *1024  19 | 20 |   22 | 23 |

24 | Results:
25 | 26 |
27 | 28 | 29 | 30 | 31 | 39 | 40 | -------------------------------------------------------------------------------- /novnc/tests/assertions.js: -------------------------------------------------------------------------------- 1 | // some useful assertions for noVNC 2 | chai.use(function (_chai, utils) { 3 | _chai.Assertion.addMethod('displayed', function (target_data) { 4 | var obj = this._obj; 5 | var data_cl = obj._drawCtx.getImageData(0, 0, obj._viewportLoc.w, obj._viewportLoc.h).data; 6 | // NB(directxman12): PhantomJS 1.x doesn't implement Uint8ClampedArray, so work around that 7 | var data = new Uint8Array(data_cl); 8 | this.assert(utils.eql(data, target_data), 9 | "expected #{this} to have displayed the image #{exp}, but instead it displayed #{act}", 10 | "expected #{this} not to have displayed the image #{act}", 11 | target_data, 12 | data); 13 | }); 14 | 15 | _chai.Assertion.addMethod('sent', function (target_data) { 16 | var obj = this._obj; 17 | var data = obj._websocket._get_sent_data(); 18 | this.assert(utils.eql(data, target_data), 19 | "expected #{this} to have sent the data #{exp}, but it actually sent #{act}", 20 | "expected #{this} not to have sent the data #{act}", 21 | target_data, 22 | data); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /novnc/tests/base64.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Native Base64 Tests 5 | 6 | 7 | 8 | 9 | 10 |

Native Base64 Tests

11 | 12 |
13 | Messages:
14 | 15 | 16 |
17 | 18 | 19 | 92 | -------------------------------------------------------------------------------- /novnc/tests/base64.js: -------------------------------------------------------------------------------- 1 | // The following results in 'hello [MANGLED]' 2 | // 3 | // Filed as https://github.com/ry/node/issues/issue/402 4 | 5 | var sys = require("sys"), 6 | buf = new Buffer(1024), len, 7 | str1 = "aGVsbG8g", // 'hello ' 8 | str2 = "d29ybGQ=", // 'world' 9 | 10 | len = buf.write(str1, 0, 'base64'); 11 | len += buf.write(str2, len, 'base64'); 12 | sys.log("decoded result: " + buf.toString('binary', 0, len)); 13 | -------------------------------------------------------------------------------- /novnc/tests/browser.js: -------------------------------------------------------------------------------- 1 | /* 2 | * From: 3 | * http://www.quirksmode.org/js/detect.html 4 | */ 5 | 6 | var Browser = { 7 | init: function () { 8 | this.browser = this.searchString(this.dataBrowser) || "An unknown browser"; 9 | this.version = this.searchVersion(navigator.userAgent) 10 | || this.searchVersion(navigator.appVersion) 11 | || "an unknown version"; 12 | this.majorVersion = this.searchMajorVersion(navigator.userAgent) 13 | || this.searchMajorVersion(navigator.appVersion) 14 | || "an unknown version"; 15 | this.fullVersion = this.searchFullVersion(navigator.userAgent) 16 | || this.searchFullVersion(navigator.appVersion) 17 | || "an unknown version"; 18 | this.OS = this.searchString(this.dataOS) || "an unknown OS"; 19 | }, 20 | searchString: function (data) { 21 | for (var i=0;i 2 | 3 | 4 | Canvas Performance Test 5 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | Iterations:   17 | 18 | Width:   19 | Height:   20 | 21 |   23 | 24 |

25 | 26 | Canvas (should see three squares and two happy faces):
27 | 29 | Canvas not supported. 30 | 31 | 32 |
33 | Results:
34 | 35 | 36 | 37 | 148 | 149 | -------------------------------------------------------------------------------- /novnc/tests/cursor.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Cursor Change test 5 | 6 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |

Roll over the buttons to test cursors

17 |
18 | 19 | 20 | 21 |
22 |
23 |
24 | Debug:
25 | 26 |
27 |
28 | 29 | Canvas not supported. 30 | 31 | 32 | 33 | 34 | 136 | -------------------------------------------------------------------------------- /novnc/tests/face.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solarkennedy/ipmi-kvm-docker/26002abba9b39f574a5a775165d4ea659fd004e7/novnc/tests/face.png -------------------------------------------------------------------------------- /novnc/tests/face.png.js: -------------------------------------------------------------------------------- 1 | var face64 = 'iVBORw0KGgoAAAANSUhEUgAAACMAAAAjCAIAAACRuyQOAAAAA3NCSVQICAjb4U/gAAAAGXRFWHRTb2Z0d2FyZQBnbm9tZS1zY3JlZW5zaG907wO/PgAACJJJREFUSIm1lltsXMUdxr8558zZq9d3OxebJDYhJLhNIAmUWyFKIBUtVaGqSgtUlIJKeahoEahgIZU+VC0oQiVVC60obckDgVIp3KRCQkmhhIhA4oY4wjg2ufmS9drec/bc5vbvw9prJwq85dP/YWfP7Pfb/8w3s8v6339l2fkrbMvGuZQ2mkUTA0bpc4qpyjrX3dTkAATQ5z0WUrqcAwjL/eXirmBqj0yKSTTBwNxMM0+15JuurG/dlClcOH/yWcVEaVBKUR3Eidizr2946Nhr/9q5b//BsudZzDLG5DK4sDt3443XrFm34bkX9x4ZPimkWNBa/+MfrB84+O7rbxz4+JPQD8liljY6n8t9uWfld2/++vp1F3ct6cikU2eSnvr7P7e99OqC9vaTJ0ccMtl8loyJ4igKwzAIK0GglersWv7sM08VCrk4joY/O/rLXz3mTYzmcnnXdZXWcRzHURwEQRCEHUuXdS/vnp4qP/CT2zdvuAKAQwCB4kRse+m1LY//Wojkscd/57opKUQUJ8wyzFaOq7OGGGPcdZ/f/sKbu3YT0YZrr3JT7pq1l3qeH4SBqgRETBljDKXSqXyh/i9PP/W/Q31btz59zVXrUpxb1dYsixUK+c7Fi59/YUdz2yInnbXcLHfTtpu23ZRlu4ZZiRBTp8Z37HjlhW1/evnFZ9/a+VZdLsecFOMpx83ydJanc24q67iuFOr48NC1G6+fKBY7zutIElFNBAC4nN99602XXLzutjvvETqAlcqktVQin0QiLsRxEAUBaRVUfBh1QfcigmzIuw0NTe2LOjNlL07iOArDwA88z0unGWNTk5P1dfkf3XH3BT2r9b23zZKIAHxr81f/uGpF/8G+Fau+VPbKp8ZHpqdKSRiEYWiMMVopJSuVyl+f3UpIQKL34btvvf2BxuZWN5Umo7TWFiNDDHCampob6utLpRKz7Hvv+E5jfR5ELCkNShFXOytOTH7vjrsOfXJ0wcLFF63sXr1mfXtbS6FQB4BZyGYzX7l0TWtrvWVpUGxUMFEa2bv3Q9+bNCaECX2/NFEc3bd/4r19/tR0uLC98c+/3/LVy9fWzhNq56m1pfEPvabnut2OI8EvBMAYAxhgAWz3u3tuvuWeRx/56aYNa0Hy3fc/euiRZx596IZvbF5Dpgw9CdMI0waqaMrEScPgvtdWXH5JzdzC7NElIPQH3GyTk+4ABCgCEpAkMgRGcLb/49WGxqYtTzwNaJDa/tJ7DU1tW558GaYCEwESYGAWwEidTOcWM8tElcGauTP/ivDGd7V3fxv6JGCBIpBDjIMxgIM5B/YfjMJwfGwEMIA40DcQhcn46DGAzX7p6gIwBhj5WUvH8vLYG+nu8+d6qimY2lPXup70GFEEE9baAhRIj5w8cfz4MSESkJw3FLOfnrvSCETqs3xTd2Vyd+1Na/4MmRRt3gBTgfGJKkQhTAQTwgQgv2tpR8X3Vq5YCiiC7lrSXPG9lRe0AmZ2hQxo5jXpspNqEElxPmlOIi5ZThYUgBKYKRgPxgMFMAGM/+D9P2xuLPQ+dBcoAYkHf/bN5sZM74M3gHS1acBUi0gZ4zk8J5NyzdzBGSIJkoANCqsrwgBAg+zN1605Mfw6IIkiUHL9xouODzwBE4ACkKrGBNBkBEgSKSIz39gxRkuRVAduulHLCZtZoARkzybTAFU2m7GjBBSDkmoRJYCc3U5lSBgjAFeJae4Wauan9WSnWlU0aqdtUAXElAicVDNIgfHZaJkZU0pAESgmCJAACUCApJIBKCITg+VVMuWm2+btEwFE1coVLvOKe2HVE8UwUd/OXi0nQZXZ8kH+7HIFoIgoqvKqzWkV9L2zy5jQ6Ig5nX5pOFd/Vc3cmv9zW9eyYfzITmY1giKiMJNtCiYPw1RgPBh/psiHqcAEZAJQBFMlxaDEnyqmc3mjY2NCiy+bHB3Kt2w8I+UzxTPLlAzjygCz6kFBx6qNg/ue84p9M7AZRoWoQhSAqumfacsrnRg6uH9Rd4/RFWafl1RGjLJ5ZknNnIXjh+PQB0BEQkqv9L4sb1t59cMU74GVKxcnhg5sdzN1jQtX5grtqVyj46ZtywIJrUOZeCKYCLxTU+PHkzhZ2vO1XH5MRIfcwvcHP9qRafp5XfN6l3PGGIA5ktJaJEJINXnkvmWrNza0rSBxEFYbnE6veGRq9IPQO54Ep5QItRYAs22Hu1k315QtdDYsuCzf1KHDt0XlbTu3ySuVRo6MNnc/6XLHTbmObc+QotAHIJUSQiSJTKLR4Nh9Pdc+kM44JA+D5RhfBud8ZjeD5WHVMVYHqwAYmGkyUyRPqPDfMnhTxcNW+jKpGj/94NX8eVtTmYWpFHddlzsOABaOzZGkkImQUsrI/1iVfrPq6vszuSyJD0EasGEVmN0KlgXLgYGMT6qkkwEthrQuG53Y2U0icT79YIfb2pup6+Gcp1zOXV4j9VdJxhghpJBSSCmEjL0+XXqsa+0tTYvWQ/aTHJrZW9JEkowwJjYmMjo0OmR8uZ1eNz12+Nih/zgtv0gXVrsur1Jcl1uWNUsK/GoQldZSSCGllEpIGYcndOm36Vyqa/VNmboFRh4ldZR02ZhpMhJwCGnmLGZ8SewXj/bvTkLDW3pT2UUu55w7Lufc5dVNAsCCsf4o8Gqpr8KkUlIqpZRUKim/Y/y/pVLZ1s5V+Zbl3C3Ybp5Iq2RKxhP+xFBxZFAmwi7cmaq/kjuO4zicO9xx5mPOQqrGvYZRWmulldYqGlLBf3X8EfQkSR8A43WMN1nuWid3hZPpcmzbdmzHtmuwarjnkw5FldNIczyljDZKa62NNpoM1QSA1WQx27Jt23Js27It7pzJmLthz/7/nzHOOThcImPoNBIIAMNpJMtiNcBZDZ3PfVIjgtkWsy3riyZ9AaFGMlozhuqCnDsxxv4PC7uS+QV5eeoAAAAASUVORK5CYII='; 2 | -------------------------------------------------------------------------------- /novnc/tests/fake.websocket.js: -------------------------------------------------------------------------------- 1 | var FakeWebSocket; 2 | 3 | (function () { 4 | // PhantomJS can't create Event objects directly, so we need to use this 5 | function make_event(name, props) { 6 | var evt = document.createEvent('Event'); 7 | evt.initEvent(name, true, true); 8 | if (props) { 9 | for (var prop in props) { 10 | evt[prop] = props[prop]; 11 | } 12 | } 13 | return evt; 14 | } 15 | 16 | FakeWebSocket = function (uri, protocols) { 17 | this.url = uri; 18 | this.binaryType = "arraybuffer"; 19 | this.extensions = ""; 20 | 21 | if (!protocols || typeof protocols === 'string') { 22 | this.protocol = protocols; 23 | } else { 24 | this.protocol = protocols[0]; 25 | } 26 | 27 | this._send_queue = new Uint8Array(20000); 28 | 29 | this.readyState = FakeWebSocket.CONNECTING; 30 | this.bufferedAmount = 0; 31 | 32 | this.__is_fake = true; 33 | }; 34 | 35 | FakeWebSocket.prototype = { 36 | close: function (code, reason) { 37 | this.readyState = FakeWebSocket.CLOSED; 38 | if (this.onclose) { 39 | this.onclose(make_event("close", { 'code': code, 'reason': reason, 'wasClean': true })); 40 | } 41 | }, 42 | 43 | send: function (data) { 44 | if (this.protocol == 'base64') { 45 | data = Base64.decode(data); 46 | } else { 47 | data = new Uint8Array(data); 48 | } 49 | this._send_queue.set(data, this.bufferedAmount); 50 | this.bufferedAmount += data.length; 51 | }, 52 | 53 | _get_sent_data: function () { 54 | var arr = []; 55 | for (var i = 0; i < this.bufferedAmount; i++) { 56 | arr[i] = this._send_queue[i]; 57 | } 58 | 59 | this.bufferedAmount = 0; 60 | 61 | return arr; 62 | }, 63 | 64 | _open: function (data) { 65 | this.readyState = FakeWebSocket.OPEN; 66 | if (this.onopen) { 67 | this.onopen(make_event('open')); 68 | } 69 | }, 70 | 71 | _receive_data: function (data) { 72 | this.onmessage(make_event("message", { 'data': data })); 73 | } 74 | }; 75 | 76 | FakeWebSocket.OPEN = WebSocket.OPEN; 77 | FakeWebSocket.CONNECTING = WebSocket.CONNECTING; 78 | FakeWebSocket.CLOSING = WebSocket.CLOSING; 79 | FakeWebSocket.CLOSED = WebSocket.CLOSED; 80 | 81 | FakeWebSocket.__is_fake = true; 82 | 83 | FakeWebSocket.replace = function () { 84 | if (!WebSocket.__is_fake) { 85 | var real_version = WebSocket; 86 | WebSocket = FakeWebSocket; 87 | FakeWebSocket.__real_version = real_version; 88 | } 89 | }; 90 | 91 | FakeWebSocket.restore = function () { 92 | if (WebSocket.__is_fake) { 93 | WebSocket = WebSocket.__real_version; 94 | } 95 | }; 96 | })(); 97 | -------------------------------------------------------------------------------- /novnc/tests/input.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Input Test 4 | 5 |

6 | 7 | Canvas: 8 | 11 |
12 | 14 | Canvas not supported. 15 | 16 | 17 |
18 | Results:
19 | 20 | 21 | 22 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 131 | 132 | -------------------------------------------------------------------------------- /novnc/tests/keyboard-tests.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Mocha Tests 6 | 7 | 8 | 9 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /novnc/tests/run_from_console.casper.js: -------------------------------------------------------------------------------- 1 | var Spooky = require('spooky'); 2 | var path = require('path'); 3 | 4 | var phantom_path = require('phantomjs').path; 5 | var casper_path = path.resolve(__dirname, '../node_modules/casperjs/bin/casperjs'); 6 | process.env.PHANTOMJS_EXECUTABLE = phantom_path; 7 | var casper_opts = { 8 | child: { 9 | transport: 'http', 10 | command: casper_path 11 | }, 12 | casper: { 13 | logLevel: 'debug', 14 | verbose: true 15 | } 16 | }; 17 | 18 | var provide_emitter = function(file_paths) { 19 | var spooky = new Spooky(casper_opts, function(err) { 20 | if (err) { 21 | if (err.stack) console.warn(err.stack); 22 | else console.warn(err); 23 | return; 24 | } 25 | spooky.start('about:blank'); 26 | 27 | file_paths.forEach(function(file_path, path_ind) { 28 | spooky.thenOpen('file://'+file_path); 29 | spooky.waitFor(function() { 30 | return this.getGlobal('__mocha_done') === true; 31 | }, 32 | [{ path_ind: path_ind }, function() { 33 | var res_json = { 34 | file_ind: path_ind 35 | }; 36 | 37 | res_json.num_tests = this.evaluate(function() { return document.querySelectorAll('li.test').length; }); 38 | res_json.num_passes = this.evaluate(function() { return document.querySelectorAll('li.test.pass').length; }); 39 | res_json.num_fails = this.evaluate(function() { return document.querySelectorAll('li.test.fail').length; }); 40 | res_json.num_slow = this.evaluate(function() { return document.querySelectorAll('li.test.pass:not(.fast):not(.pending)').length; }); 41 | res_json.num_skipped = this.evaluate(function () { return document.querySelectorAll('li.test.pending').length; }); 42 | res_json.duration = this.evaluate(function() { return document.querySelector('li.duration em').textContent; }); 43 | 44 | res_json.suites = this.evaluate(function() { 45 | var traverse_node = function(elem) { 46 | var res; 47 | if (elem.classList.contains('suite')) { 48 | res = { 49 | type: 'suite', 50 | name: elem.querySelector('h1').textContent, 51 | has_subfailures: elem.querySelectorAll('li.test.fail').length > 0, 52 | }; 53 | 54 | var child_elems = elem.querySelector('ul').children; 55 | res.children = Array.prototype.map.call(child_elems, traverse_node); 56 | return res; 57 | } 58 | else { 59 | var h2_content = elem.querySelector('h2').childNodes; 60 | res = { 61 | type: 'test', 62 | text: h2_content[0].textContent, 63 | }; 64 | 65 | if (elem.classList.contains('pass')) { 66 | res.pass = true; 67 | if (elem.classList.contains('pending')) { 68 | res.slow = false; 69 | res.skipped = true; 70 | } 71 | else { 72 | res.slow = !elem.classList.contains('fast'); 73 | res.skipped = false; 74 | res.duration = h2_content[1].textContent; 75 | } 76 | } 77 | else { 78 | res.error = elem.querySelector('pre.error').textContent; 79 | } 80 | 81 | return res; 82 | } 83 | }; 84 | var top_suites = document.querySelectorAll('#mocha-report > li.suite'); 85 | return Array.prototype.map.call(top_suites, traverse_node); 86 | }); 87 | 88 | res_json.replay = this.evaluate(function() { return document.querySelector('a.replay').textContent; }); 89 | 90 | this.emit('test_ready', res_json); 91 | }]); 92 | }); 93 | spooky.run(); 94 | }); 95 | 96 | return spooky; 97 | }; 98 | 99 | module.exports = { 100 | provide_emitter: provide_emitter, 101 | name: 'SpookyJS (CapserJS on PhantomJS)' 102 | }; 103 | -------------------------------------------------------------------------------- /novnc/tests/run_from_console.zombie.js: -------------------------------------------------------------------------------- 1 | var Browser = require('zombie'); 2 | var path = require('path'); 3 | var EventEmitter = require('events').EventEmitter; 4 | var Q = require('q'); 5 | 6 | var provide_emitter = function(file_paths) { 7 | var emitter = new EventEmitter(); 8 | 9 | file_paths.reduce(function(prom, file_path, path_ind) { 10 | return prom.then(function(browser) { 11 | browser.visit('file://'+file_path, function() { 12 | if (browser.error) throw new Error(browser.errors); 13 | 14 | var res_json = {}; 15 | res_json.file_ind = path_ind; 16 | 17 | res_json.num_tests = browser.querySelectorAll('li.test').length; 18 | res_json.num_fails = browser.querySelectorAll('li.test.fail').length; 19 | res_json.num_passes = browser.querySelectorAll('li.test.pass').length; 20 | res_json.num_slow = browser.querySelectorAll('li.test.pass:not(.fast)').length; 21 | res_json.num_skipped = browser.querySelectorAll('li.test.pending').length; 22 | res_json.duration = browser.text('li.duration em'); 23 | 24 | var traverse_node = function(elem) { 25 | var classList = elem.className.split(' '); 26 | var res; 27 | if (classList.indexOf('suite') > -1) { 28 | res = { 29 | type: 'suite', 30 | name: elem.querySelector('h1').textContent, 31 | has_subfailures: elem.querySelectorAll('li.test.fail').length > 0 32 | }; 33 | 34 | var child_elems = elem.querySelector('ul').children; 35 | res.children = Array.prototype.map.call(child_elems, traverse_node); 36 | return res; 37 | } 38 | else { 39 | var h2_content = elem.querySelector('h2').childNodes; 40 | res = { 41 | type: 'test', 42 | text: h2_content[0].textContent 43 | }; 44 | 45 | if (classList.indexOf('pass') > -1) { 46 | res.pass = true; 47 | if (classList.indexOf('pending') > -1) { 48 | res.slow = false; 49 | res.skipped = true; 50 | } 51 | else { 52 | res.slow = classList.indexOf('fast') < 0; 53 | res.skipped = false; 54 | res.duration = h2_content[1].textContent; 55 | } 56 | } 57 | else { 58 | res.error = elem.querySelector('pre.error').textContent; 59 | } 60 | 61 | return res; 62 | } 63 | }; 64 | 65 | var top_suites = browser.querySelectorAll('#mocha-report > li.suite'); 66 | res_json.suites = Array.prototype.map.call(top_suites, traverse_node); 67 | res_json.replay = browser.querySelector('a.replay').textContent; 68 | 69 | emitter.emit('test_ready', res_json); 70 | }); 71 | 72 | return new Browser(); 73 | }); 74 | }, Q(new Browser())); 75 | 76 | return emitter; 77 | }; 78 | 79 | module.exports = { 80 | provide_emitter: provide_emitter, 81 | name: 'ZombieJS' 82 | }; 83 | -------------------------------------------------------------------------------- /novnc/tests/stats.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Define some useful statistical functions on arrays of numbers 3 | */ 4 | 5 | Array.prototype.sum = function() { 6 | var i, sum = 0; 7 | for (i = 0; i < this.length; i++) { 8 | sum += this[i]; 9 | } 10 | return sum; 11 | } 12 | 13 | Array.prototype.max = function() { 14 | return Math.max.apply(null, this); 15 | } 16 | 17 | Array.prototype.min = function() { 18 | return Math.min.apply(null, this); 19 | } 20 | 21 | Array.prototype.mean = function() { 22 | return this.sum() / this.length; 23 | } 24 | Array.prototype.average = Array.prototype.mean; 25 | 26 | Array.prototype.median = function() { 27 | var sorted = this.sort( function(a,b) { return a-b; }), 28 | len = sorted.length; 29 | if (len % 2) { 30 | return sorted[Math.floor(len / 2)]; // Odd 31 | } else { 32 | return (sorted[len/2 - 1] + sorted[len/2]) / 2; // Even 33 | } 34 | } 35 | 36 | Array.prototype.stdDev = function(sample) { 37 | var i, sumSqr = 0, mean = this.mean(), N; 38 | 39 | if (sample) { 40 | // Population correction if this is a sample 41 | N = this.length - 1; 42 | } else { 43 | // Standard deviation of just the array 44 | N = this.length; 45 | } 46 | 47 | for (i = 0; i < this.length; i++) { 48 | sumSqr += Math.pow(this[i] - mean, 2); 49 | } 50 | 51 | return Math.sqrt(sumSqr / N); 52 | } 53 | 54 | -------------------------------------------------------------------------------- /novnc/tests/test.base64.js: -------------------------------------------------------------------------------- 1 | // requires local modules: base64 2 | var assert = chai.assert; 3 | var expect = chai.expect; 4 | 5 | describe('Base64 Tools', function() { 6 | "use strict"; 7 | 8 | var BIN_ARR = new Array(256); 9 | for (var i = 0; i < 256; i++) { 10 | BIN_ARR[i] = i; 11 | } 12 | 13 | var B64_STR = "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w=="; 14 | 15 | 16 | describe('encode', function() { 17 | it('should encode a binary string into Base64', function() { 18 | var encoded = Base64.encode(BIN_ARR); 19 | expect(encoded).to.equal(B64_STR); 20 | }); 21 | }); 22 | 23 | describe('decode', function() { 24 | it('should decode a Base64 string into a normal string', function() { 25 | var decoded = Base64.decode(B64_STR); 26 | expect(decoded).to.deep.equal(BIN_ARR); 27 | }); 28 | 29 | it('should throw an error if we have extra characters at the end of the string', function() { 30 | expect(function () { Base64.decode(B64_STR+'abcdef'); }).to.throw(Error); 31 | }); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /novnc/tests/test.util.js: -------------------------------------------------------------------------------- 1 | // requires local modules: util 2 | /* jshint expr: true */ 3 | 4 | var assert = chai.assert; 5 | var expect = chai.expect; 6 | 7 | describe('Utils', function() { 8 | "use strict"; 9 | 10 | describe('Array instance methods', function () { 11 | describe('push8', function () { 12 | it('should push a byte on to the array', function () { 13 | var arr = [1]; 14 | arr.push8(128); 15 | expect(arr).to.deep.equal([1, 128]); 16 | }); 17 | 18 | it('should only use the least significant byte of any number passed in', function () { 19 | var arr = [1]; 20 | arr.push8(0xABCD); 21 | expect(arr).to.deep.equal([1, 0xCD]); 22 | }); 23 | }); 24 | 25 | describe('push16', function () { 26 | it('should push two bytes on to the array', function () { 27 | var arr = [1]; 28 | arr.push16(0xABCD); 29 | expect(arr).to.deep.equal([1, 0xAB, 0xCD]); 30 | }); 31 | 32 | it('should only use the two least significant bytes of any number passed in', function () { 33 | var arr = [1]; 34 | arr.push16(0xABCDEF); 35 | expect(arr).to.deep.equal([1, 0xCD, 0xEF]); 36 | }); 37 | }); 38 | 39 | describe('push32', function () { 40 | it('should push four bytes on to the array', function () { 41 | var arr = [1]; 42 | arr.push32(0xABCDEF12); 43 | expect(arr).to.deep.equal([1, 0xAB, 0xCD, 0xEF, 0x12]); 44 | }); 45 | 46 | it('should only use the four least significant bytes of any number passed in', function () { 47 | var arr = [1]; 48 | arr.push32(0xABCDEF1234); 49 | expect(arr).to.deep.equal([1, 0xCD, 0xEF, 0x12, 0x34]); 50 | }); 51 | }); 52 | }); 53 | 54 | describe('logging functions', function () { 55 | beforeEach(function () { 56 | sinon.spy(console, 'log'); 57 | sinon.spy(console, 'warn'); 58 | sinon.spy(console, 'error'); 59 | }); 60 | 61 | afterEach(function () { 62 | console.log.restore(); 63 | console.warn.restore(); 64 | console.error.restore(); 65 | }); 66 | 67 | it('should use noop for levels lower than the min level', function () { 68 | Util.init_logging('warn'); 69 | Util.Debug('hi'); 70 | Util.Info('hello'); 71 | expect(console.log).to.not.have.been.called; 72 | }); 73 | 74 | it('should use console.log for Debug and Info', function () { 75 | Util.init_logging('debug'); 76 | Util.Debug('dbg'); 77 | Util.Info('inf'); 78 | expect(console.log).to.have.been.calledWith('dbg'); 79 | expect(console.log).to.have.been.calledWith('inf'); 80 | }); 81 | 82 | it('should use console.warn for Warn', function () { 83 | Util.init_logging('warn'); 84 | Util.Warn('wrn'); 85 | expect(console.warn).to.have.been.called; 86 | expect(console.warn).to.have.been.calledWith('wrn'); 87 | }); 88 | 89 | it('should use console.error for Error', function () { 90 | Util.init_logging('error'); 91 | Util.Error('err'); 92 | expect(console.error).to.have.been.called; 93 | expect(console.error).to.have.been.calledWith('err'); 94 | }); 95 | }); 96 | 97 | // TODO(directxman12): test the conf_default and conf_defaults methods 98 | // TODO(directxman12): test decodeUTF8 99 | // TODO(directxman12): test the event methods (addEvent, removeEvent, stopEvent) 100 | // TODO(directxman12): figure out a good way to test getPosition and getEventPosition 101 | // TODO(directxman12): figure out how to test the browser detection functions properly 102 | // (we can't really test them against the browsers, except for Gecko 103 | // via PhantomJS, the default test driver) 104 | // TODO(directxman12): figure out how to test Util.Flash 105 | }); 106 | -------------------------------------------------------------------------------- /novnc/tests/viewport.css: -------------------------------------------------------------------------------- 1 | html,body { 2 | margin: 0px; 3 | padding: 0px; 4 | width: 100%; 5 | height: 100%; 6 | } 7 | 8 | .flex-layout { 9 | width: 100%; 10 | height: 100%; 11 | 12 | display: box; 13 | display: -webkit-box; 14 | display: -moz-box; 15 | display: -ms-box; 16 | 17 | box-orient: vertical; 18 | -webkit-box-orient: vertical; 19 | -moz-box-orient: vertical; 20 | -ms-box-orient: vertical; 21 | 22 | box-align: stretch; 23 | -webkit-box-align: stretch; 24 | -moz-box-align: stretch; 25 | -ms-box-align: stretch; 26 | } 27 | .flex-box { 28 | box-flex: 1; 29 | -webkit-box-flex: 1; 30 | -moz-box-flex: 1; 31 | -ms-box-flex: 1; 32 | } 33 | 34 | .container { 35 | margin: 0px; 36 | padding: 0px; 37 | } 38 | 39 | .canvas { 40 | position: absolute; 41 | border-style: dotted; 42 | border-width: 1px; 43 | } 44 | -------------------------------------------------------------------------------- /novnc/tests/viewport.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Viewport Test 4 | 5 | 9 | 10 | 11 | 12 |
13 |
14 | Canvas: 15 | 17 |
18 |
19 |
20 | 21 | Canvas not supported. 22 | 23 |
24 |
25 |
26 |
27 | Results:
28 | 29 |
30 |
31 | 32 | 33 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 204 | 205 | -------------------------------------------------------------------------------- /novnc/tests/vnc_perf.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | VNC Performance Benchmark 5 | 6 | 7 | 8 | Passes:   9 | 10 |   12 | 13 |

14 | 15 | Results:
16 | 17 | 18 |

19 | 20 |
21 |
22 | 23 | 24 |
Loading
25 |
26 | 27 | Canvas not supported. 28 | 29 |
30 | 31 | 32 | 33 | 37 | 38 | 43 | 44 | 45 | 46 | 47 | 209 | 210 | -------------------------------------------------------------------------------- /novnc/tests/vnc_playback.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | VNC Playback 5 | 6 | 7 | 8 | Iterations:   9 | Perftest:  10 | Realtime:   11 | 12 |   14 | 15 |

16 | 17 | Results:
18 | 19 | 20 |

21 | 22 |
23 |
24 | 25 | 26 |
Loading
27 |
28 | 29 | Canvas not supported. 30 | 31 |
32 | 33 | 34 | 35 | 39 | 40 | 45 | 46 | 47 | 48 | 138 | 139 | -------------------------------------------------------------------------------- /novnc/utils/Makefile: -------------------------------------------------------------------------------- 1 | TARGETS=rebind.so 2 | CFLAGS += -fPIC 3 | 4 | all: $(TARGETS) 5 | 6 | rebind.so: rebind.o 7 | $(CC) $(LDFLAGS) $^ -shared -fPIC -ldl -o $@ 8 | 9 | clean: 10 | rm -f rebind.o rebind.so 11 | 12 | -------------------------------------------------------------------------------- /novnc/utils/README.md: -------------------------------------------------------------------------------- 1 | ## WebSockets Proxy/Bridge 2 | 3 | For more detailed description and usage information please refer to 4 | the [websockify README](https://github.com/kanaka/websockify/blob/master/README.md). 5 | 6 | The other versions of websockify (C, Node.js) and the associated test 7 | programs have been moved to 8 | [websockify](https://github.com/kanaka/websockify). Websockify was 9 | formerly named wsproxy. 10 | 11 | -------------------------------------------------------------------------------- /novnc/utils/img2js.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # 4 | # Convert image to Javascript compatible base64 Data URI 5 | # Copyright 2011 Joel Martin 6 | # Licensed under MPL 2.0 (see docs/LICENSE.MPL-2.0) 7 | # 8 | 9 | import sys, base64 10 | 11 | try: 12 | from PIL import Image 13 | except: 14 | print "python PIL module required (python-imaging package)" 15 | sys.exit(1) 16 | 17 | 18 | if len(sys.argv) < 3: 19 | print "Usage: %s IMAGE JS_VARIABLE" % sys.argv[0] 20 | sys.exit(1) 21 | 22 | fname = sys.argv[1] 23 | var = sys.argv[2] 24 | 25 | ext = fname.lower().split('.')[-1] 26 | if ext == "png": mime = "image/png" 27 | elif ext in ["jpg", "jpeg"]: mime = "image/jpeg" 28 | elif ext == "gif": mime = "image/gif" 29 | else: 30 | print "Only PNG, JPEG and GIF images are supported" 31 | sys.exit(1) 32 | uri = "data:%s;base64," % mime 33 | 34 | im = Image.open(fname) 35 | w, h = im.size 36 | 37 | raw = open(fname).read() 38 | 39 | print '%s = {"width": %s, "height": %s, "data": "%s%s"};' % ( 40 | var, w, h, uri, base64.b64encode(raw)) 41 | -------------------------------------------------------------------------------- /novnc/utils/json2graph.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | ''' 4 | Use matplotlib to generate performance charts 5 | Copyright 2011 Joel Martin 6 | Licensed under MPL-2.0 (see docs/LICENSE.MPL-2.0) 7 | ''' 8 | 9 | # a bar plot with errorbars 10 | import sys, json, pprint 11 | import numpy as np 12 | import matplotlib.pyplot as plt 13 | from matplotlib.font_manager import FontProperties 14 | 15 | def usage(): 16 | print "%s json_file level1 level2 level3 [legend_height]\n\n" % sys.argv[0] 17 | print "Description:\n" 18 | print "level1, level2, and level3 are one each of the following:\n"; 19 | print " select=ITEM - select only ITEM at this level"; 20 | print " bar - each item on this level becomes a graph bar"; 21 | print " group - items on this level become groups of bars"; 22 | print "\n"; 23 | print "json_file is a file containing json data in the following format:\n" 24 | print ' {'; 25 | print ' "conf": {'; 26 | print ' "order_l1": ['; 27 | print ' "level1_label1",'; 28 | print ' "level1_label2",'; 29 | print ' ...'; 30 | print ' ],'; 31 | print ' "order_l2": ['; 32 | print ' "level2_label1",'; 33 | print ' "level2_label2",'; 34 | print ' ...'; 35 | print ' ],'; 36 | print ' "order_l3": ['; 37 | print ' "level3_label1",'; 38 | print ' "level3_label2",'; 39 | print ' ...'; 40 | print ' ]'; 41 | print ' },'; 42 | print ' "stats": {'; 43 | print ' "level1_label1": {'; 44 | print ' "level2_label1": {'; 45 | print ' "level3_label1": [val1, val2, val3],'; 46 | print ' "level3_label2": [val1, val2, val3],'; 47 | print ' ...'; 48 | print ' },'; 49 | print ' "level2_label2": {'; 50 | print ' ...'; 51 | print ' },'; 52 | print ' },'; 53 | print ' "level1_label2": {'; 54 | print ' ...'; 55 | print ' },'; 56 | print ' ...'; 57 | print ' },'; 58 | print ' }'; 59 | sys.exit(2) 60 | 61 | def error(msg): 62 | print msg 63 | sys.exit(1) 64 | 65 | 66 | #colors = ['#ff0000', '#0863e9', '#00f200', '#ffa100', 67 | # '#800000', '#805100', '#013075', '#007900'] 68 | colors = ['#ff0000', '#00ff00', '#0000ff', 69 | '#dddd00', '#dd00dd', '#00dddd', 70 | '#dd6622', '#dd2266', '#66dd22', 71 | '#8844dd', '#44dd88', '#4488dd'] 72 | 73 | if len(sys.argv) < 5: 74 | usage() 75 | 76 | filename = sys.argv[1] 77 | L1 = sys.argv[2] 78 | L2 = sys.argv[3] 79 | L3 = sys.argv[4] 80 | if len(sys.argv) > 5: 81 | legendHeight = float(sys.argv[5]) 82 | else: 83 | legendHeight = 0.75 84 | 85 | # Load the JSON data from the file 86 | data = json.loads(file(filename).read()) 87 | conf = data['conf'] 88 | stats = data['stats'] 89 | 90 | # Sanity check data hierarchy 91 | if len(conf['order_l1']) != len(stats.keys()): 92 | error("conf.order_l1 does not match stats level 1") 93 | for l1 in stats.keys(): 94 | if len(conf['order_l2']) != len(stats[l1].keys()): 95 | error("conf.order_l2 does not match stats level 2 for %s" % l1) 96 | if conf['order_l1'].count(l1) < 1: 97 | error("%s not found in conf.order_l1" % l1) 98 | for l2 in stats[l1].keys(): 99 | if len(conf['order_l3']) != len(stats[l1][l2].keys()): 100 | error("conf.order_l3 does not match stats level 3") 101 | if conf['order_l2'].count(l2) < 1: 102 | error("%s not found in conf.order_l2" % l2) 103 | for l3 in stats[l1][l2].keys(): 104 | if conf['order_l3'].count(l3) < 1: 105 | error("%s not found in conf.order_l3" % l3) 106 | 107 | # 108 | # Generate the data based on the level specifications 109 | # 110 | bar_labels = None 111 | group_labels = None 112 | bar_vals = [] 113 | bar_sdvs = [] 114 | if L3.startswith("select="): 115 | select_label = l3 = L3.split("=")[1] 116 | bar_labels = conf['order_l1'] 117 | group_labels = conf['order_l2'] 118 | bar_vals = [[0]*len(group_labels) for i in bar_labels] 119 | bar_sdvs = [[0]*len(group_labels) for i in bar_labels] 120 | for b in range(len(bar_labels)): 121 | l1 = bar_labels[b] 122 | for g in range(len(group_labels)): 123 | l2 = group_labels[g] 124 | bar_vals[b][g] = np.mean(stats[l1][l2][l3]) 125 | bar_sdvs[b][g] = np.std(stats[l1][l2][l3]) 126 | elif L2.startswith("select="): 127 | select_label = l2 = L2.split("=")[1] 128 | bar_labels = conf['order_l1'] 129 | group_labels = conf['order_l3'] 130 | bar_vals = [[0]*len(group_labels) for i in bar_labels] 131 | bar_sdvs = [[0]*len(group_labels) for i in bar_labels] 132 | for b in range(len(bar_labels)): 133 | l1 = bar_labels[b] 134 | for g in range(len(group_labels)): 135 | l3 = group_labels[g] 136 | bar_vals[b][g] = np.mean(stats[l1][l2][l3]) 137 | bar_sdvs[b][g] = np.std(stats[l1][l2][l3]) 138 | elif L1.startswith("select="): 139 | select_label = l1 = L1.split("=")[1] 140 | bar_labels = conf['order_l2'] 141 | group_labels = conf['order_l3'] 142 | bar_vals = [[0]*len(group_labels) for i in bar_labels] 143 | bar_sdvs = [[0]*len(group_labels) for i in bar_labels] 144 | for b in range(len(bar_labels)): 145 | l2 = bar_labels[b] 146 | for g in range(len(group_labels)): 147 | l3 = group_labels[g] 148 | bar_vals[b][g] = np.mean(stats[l1][l2][l3]) 149 | bar_sdvs[b][g] = np.std(stats[l1][l2][l3]) 150 | else: 151 | usage() 152 | 153 | # If group is before bar then flip (zip) the data 154 | if [L1, L2, L3].index("group") < [L1, L2, L3].index("bar"): 155 | bar_labels, group_labels = group_labels, bar_labels 156 | bar_vals = zip(*bar_vals) 157 | bar_sdvs = zip(*bar_sdvs) 158 | 159 | print "bar_vals:", bar_vals 160 | 161 | # 162 | # Now render the bar graph 163 | # 164 | ind = np.arange(len(group_labels)) # the x locations for the groups 165 | width = 0.8 * (1.0/len(bar_labels)) # the width of the bars 166 | 167 | fig = plt.figure(figsize=(10,6), dpi=80) 168 | plot = fig.add_subplot(1, 1, 1) 169 | 170 | rects = [] 171 | for i in range(len(bar_vals)): 172 | rects.append(plot.bar(ind+width*i, bar_vals[i], width, color=colors[i], 173 | yerr=bar_sdvs[i], align='center')) 174 | 175 | # add some 176 | plot.set_ylabel('Milliseconds (less is better)') 177 | plot.set_title("Javascript array test: %s" % select_label) 178 | plot.set_xticks(ind+width) 179 | plot.set_xticklabels( group_labels ) 180 | 181 | fontP = FontProperties() 182 | fontP.set_size('small') 183 | plot.legend( [r[0] for r in rects], bar_labels, prop=fontP, 184 | loc = 'center right', bbox_to_anchor = (1.0, legendHeight)) 185 | 186 | def autolabel(rects): 187 | # attach some text labels 188 | for rect in rects: 189 | height = rect.get_height() 190 | if np.isnan(height): 191 | height = 0.0 192 | plot.text(rect.get_x()+rect.get_width()/2., height+20, '%d'%int(height), 193 | ha='center', va='bottom', size='7') 194 | 195 | for rect in rects: 196 | autolabel(rect) 197 | 198 | # Adjust axis sizes 199 | axis = list(plot.axis()) 200 | axis[0] = -width # Make sure left side has enough for bar 201 | #axis[1] = axis[1] * 1.20 # Add 20% to the right to make sure it fits 202 | axis[2] = 0 # Make y-axis start at 0 203 | axis[3] = axis[3] * 1.10 # Add 10% to the top 204 | plot.axis(axis) 205 | 206 | plt.show() 207 | -------------------------------------------------------------------------------- /novnc/utils/launch.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | usage() { 4 | if [ "$*" ]; then 5 | echo "$*" 6 | echo 7 | fi 8 | echo "Usage: ${NAME} [--listen PORT] [--vnc VNC_HOST:PORT] [--cert CERT]" 9 | echo 10 | echo "Starts the WebSockets proxy and a mini-webserver and " 11 | echo "provides a cut-and-paste URL to go to." 12 | echo 13 | echo " --listen PORT Port for proxy/webserver to listen on" 14 | echo " Default: 6080" 15 | echo " --vnc VNC_HOST:PORT VNC server host:port proxy target" 16 | echo " Default: localhost:5900" 17 | echo " --cert CERT Path to combined cert/key file" 18 | echo " Default: self.pem" 19 | echo " --web WEB Path to web files (e.g. vnc.html)" 20 | echo " Default: ./" 21 | exit 2 22 | } 23 | 24 | NAME="$(basename $0)" 25 | HERE="$(cd "$(dirname "$0")" && pwd)" 26 | PORT="6080" 27 | VNC_DEST="localhost:5900" 28 | CERT="" 29 | WEB="" 30 | proxy_pid="" 31 | 32 | die() { 33 | echo "$*" 34 | exit 1 35 | } 36 | 37 | cleanup() { 38 | trap - TERM QUIT INT EXIT 39 | trap "true" CHLD # Ignore cleanup messages 40 | echo 41 | if [ -n "${proxy_pid}" ]; then 42 | echo "Terminating WebSockets proxy (${proxy_pid})" 43 | kill ${proxy_pid} 44 | fi 45 | } 46 | 47 | # Process Arguments 48 | 49 | # Arguments that only apply to chrooter itself 50 | while [ "$*" ]; do 51 | param=$1; shift; OPTARG=$1 52 | case $param in 53 | --listen) PORT="${OPTARG}"; shift ;; 54 | --vnc) VNC_DEST="${OPTARG}"; shift ;; 55 | --cert) CERT="${OPTARG}"; shift ;; 56 | --web) WEB="${OPTARG}"; shift ;; 57 | -h|--help) usage ;; 58 | -*) usage "Unknown chrooter option: ${param}" ;; 59 | *) break ;; 60 | esac 61 | done 62 | 63 | # Sanity checks 64 | which netstat >/dev/null 2>&1 \ 65 | || die "Must have netstat installed" 66 | 67 | netstat -ltn | grep -qs "${PORT} .*LISTEN" \ 68 | && die "Port ${PORT} in use. Try --listen PORT" 69 | 70 | trap "cleanup" TERM QUIT INT EXIT 71 | 72 | # Find vnc.html 73 | if [ -n "${WEB}" ]; then 74 | if [ ! -e "${WEB}/vnc.html" ]; then 75 | die "Could not find ${WEB}/vnc.html" 76 | fi 77 | elif [ -e "$(pwd)/vnc.html" ]; then 78 | WEB=$(pwd) 79 | elif [ -e "${HERE}/../vnc.html" ]; then 80 | WEB=${HERE}/../ 81 | elif [ -e "${HERE}/vnc.html" ]; then 82 | WEB=${HERE} 83 | elif [ -e "${HERE}/../share/novnc/vnc.html" ]; then 84 | WEB=${HERE}/../share/novnc/ 85 | else 86 | die "Could not find vnc.html" 87 | fi 88 | 89 | # Find self.pem 90 | if [ -n "${CERT}" ]; then 91 | if [ ! -e "${CERT}" ]; then 92 | die "Could not find ${CERT}" 93 | fi 94 | elif [ -e "$(pwd)/self.pem" ]; then 95 | CERT="$(pwd)/self.pem" 96 | elif [ -e "${HERE}/../self.pem" ]; then 97 | CERT="${HERE}/../self.pem" 98 | elif [ -e "${HERE}/self.pem" ]; then 99 | CERT="${HERE}/self.pem" 100 | else 101 | echo "Warning: could not find self.pem" 102 | fi 103 | 104 | echo "Starting webserver and WebSockets proxy on port ${PORT}" 105 | ${HERE}/websockify --web ${WEB} ${CERT:+--cert ${CERT}} ${PORT} ${VNC_DEST} & 106 | proxy_pid="$!" 107 | sleep 1 108 | if ! ps -p ${proxy_pid} >/dev/null; then 109 | proxy_pid= 110 | echo "Failed to start WebSockets proxy" 111 | exit 1 112 | fi 113 | 114 | echo -e "\n\nNavigate to this URL:\n" 115 | echo -e " http://$(hostname):${PORT}/vnc.html?host=$(hostname)&port=${PORT}\n" 116 | echo -e "Press Ctrl-C to exit\n\n" 117 | 118 | wait ${proxy_pid} 119 | -------------------------------------------------------------------------------- /novnc/utils/nova-novncproxy: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # vim: tabstop=4 shiftwidth=4 softtabstop=4 3 | 4 | # Copyright (c) 2012 Openstack, LLC. 5 | # All Rights Reserved. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 8 | # not use this file except in compliance with the License. You may obtain 9 | # a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 16 | # License for the specific language governing permissions and limitations 17 | # under the License. 18 | #!/usr/bin/env python 19 | 20 | ''' 21 | Websocket proxy that is compatible with Openstack Nova. 22 | Leverages websockify by Joel Martin 23 | ''' 24 | 25 | import Cookie 26 | from oslo.config import cfg 27 | import socket 28 | import sys 29 | 30 | import websockify 31 | 32 | from nova import config 33 | from nova import context 34 | from nova import utils 35 | from nova.openstack.common import rpc 36 | 37 | 38 | opts = [ 39 | cfg.BoolOpt('record', 40 | default=False, 41 | help='Record sessions to FILE.[session_number]'), 42 | cfg.BoolOpt('daemon', 43 | default=False, 44 | help='Become a daemon (background process)'), 45 | cfg.BoolOpt('ssl_only', 46 | default=False, 47 | help='Disallow non-encrypted connections'), 48 | cfg.BoolOpt('source_is_ipv6', 49 | default=False, 50 | help='Source is ipv6'), 51 | cfg.StrOpt('cert', 52 | default='self.pem', 53 | help='SSL certificate file'), 54 | cfg.StrOpt('key', 55 | default=None, 56 | help='SSL key file (if separate from cert)'), 57 | cfg.StrOpt('web', 58 | default='.', 59 | help='Run webserver on same port. Serve files from DIR.'), 60 | cfg.StrOpt('novncproxy_host', 61 | default='0.0.0.0', 62 | help='Host on which to listen for incoming requests'), 63 | cfg.IntOpt('novncproxy_port', 64 | default=6080, 65 | help='Port on which to listen for incoming requests'), 66 | ] 67 | CONF = cfg.CONF 68 | CONF.register_cli_opts(opts) 69 | 70 | # As of nova commit 0b11668e64450039dc071a4a123abd02206f865f we must 71 | # manually register the rpc library 72 | if hasattr(rpc, 'register_opts'): 73 | rpc.register_opts(CONF) 74 | 75 | 76 | class NovaWebSocketProxy(websockify.WebSocketProxy): 77 | def __init__(self, *args, **kwargs): 78 | websockify.WebSocketProxy.__init__(self, *args, **kwargs) 79 | 80 | def new_client(self): 81 | """ 82 | Called after a new WebSocket connection has been established. 83 | """ 84 | cookie = Cookie.SimpleCookie() 85 | cookie.load(self.headers.getheader('cookie')) 86 | token = cookie['token'].value 87 | ctxt = context.get_admin_context() 88 | connect_info = rpc.call(ctxt, 'consoleauth', 89 | {'method': 'check_token', 90 | 'args': {'token': token}}) 91 | 92 | if not connect_info: 93 | raise Exception("Invalid Token") 94 | 95 | host = connect_info['host'] 96 | port = int(connect_info['port']) 97 | 98 | # Connect to the target 99 | self.msg("connecting to: %s:%s" % ( 100 | host, port)) 101 | tsock = self.socket(host, port, 102 | connect=True) 103 | 104 | # Handshake as necessary 105 | if connect_info.get('internal_access_path'): 106 | tsock.send("CONNECT %s HTTP/1.1\r\n\r\n" % 107 | connect_info['internal_access_path']) 108 | while True: 109 | data = tsock.recv(4096, socket.MSG_PEEK) 110 | if data.find("\r\n\r\n") != -1: 111 | if not data.split("\r\n")[0].find("200"): 112 | raise Exception("Invalid Connection Info") 113 | tsock.recv(len(data)) 114 | break 115 | 116 | if self.verbose and not self.daemon: 117 | print(self.traffic_legend) 118 | 119 | # Start proxying 120 | try: 121 | self.do_proxy(tsock) 122 | except: 123 | if tsock: 124 | tsock.shutdown(socket.SHUT_RDWR) 125 | tsock.close() 126 | self.vmsg("%s:%s: Target closed" % (host, port)) 127 | raise 128 | 129 | 130 | if __name__ == '__main__': 131 | if CONF.ssl_only and not os.path.exists(CONF.cert): 132 | parser.error("SSL only and %s not found" % CONF.cert) 133 | 134 | # Setup flags 135 | config.parse_args(sys.argv) 136 | 137 | # Create and start the NovaWebSockets proxy 138 | server = NovaWebSocketProxy(listen_host=CONF.novncproxy_host, 139 | listen_port=CONF.novncproxy_port, 140 | source_is_ipv6=CONF.source_is_ipv6, 141 | verbose=CONF.verbose, 142 | cert=CONF.cert, 143 | key=CONF.key, 144 | ssl_only=CONF.ssl_only, 145 | daemon=CONF.daemon, 146 | record=CONF.record, 147 | web=CONF.web, 148 | target_host='ignore', 149 | target_port='ignore', 150 | wrap_mode='exit', 151 | wrap_cmd=None) 152 | server.start_server() 153 | -------------------------------------------------------------------------------- /novnc/utils/parse.js: -------------------------------------------------------------------------------- 1 | // Utility to parse keysymdef.h to produce mappings from Unicode codepoints to keysyms 2 | "use strict"; 3 | 4 | var fs = require('fs'); 5 | 6 | var show_help = process.argv.length === 2; 7 | var use_keynames = false; 8 | var filename; 9 | 10 | for (var i = 2; i < process.argv.length; ++i) { 11 | switch (process.argv[i]) { 12 | case "--help": 13 | case "-h": 14 | show_help = true; 15 | break; 16 | case "--debug-names": 17 | case "-d": 18 | use_keynames = true; 19 | break; 20 | case "--file": 21 | case "-f": 22 | default: 23 | filename = process.argv[i]; 24 | } 25 | } 26 | 27 | if (!filename) { 28 | show_help = true; 29 | console.log("Error: No filename specified\n"); 30 | } 31 | 32 | if (show_help) { 33 | console.log("Parses a *nix keysymdef.h to generate Unicode code point mappings"); 34 | console.log("Usage: node parse.js [options] filename:"); 35 | console.log(" -h [ --help ] Produce this help message"); 36 | console.log(" -d [ --debug-names ] Preserve keysym names for debugging (Increases file size by ~40KB)"); 37 | console.log(" filename The keysymdef.h file to parse"); 38 | return; 39 | } 40 | 41 | // Set this to false to omit key names from the generated keysymdef.js 42 | // This reduces the file size by around 40kb, but may hinder debugging 43 | 44 | var buf = fs.readFileSync(filename); 45 | var str = buf.toString('utf8'); 46 | 47 | var re = /^\#define XK_([a-zA-Z_0-9]+)\s+0x([0-9a-fA-F]+)\s*(\/\*\s*(.*)\s*\*\/)?\s*$/m; 48 | 49 | var arr = str.split('\n'); 50 | 51 | var keysyms = {}; 52 | var codepoints = {}; 53 | 54 | for (var i = 0; i < arr.length; ++i) { 55 | var result = re.exec(arr[i]); 56 | if (result){ 57 | var keyname = result[1]; 58 | var keysym = parseInt(result[2], 16); 59 | var remainder = result[3]; 60 | 61 | keysyms[keysym] = keyname; 62 | 63 | var unicodeRes = /U\+([0-9a-fA-F]+)/.exec(remainder); 64 | if (unicodeRes) { 65 | var unicode = parseInt(unicodeRes[1], 16); 66 | if (!codepoints[unicode]){ 67 | codepoints[unicode] = keysym; 68 | } 69 | } 70 | else { 71 | console.log("no unicode codepoint found:", arr[i]); 72 | } 73 | } 74 | else { 75 | console.log("line is not a keysym:", arr[i]); 76 | } 77 | } 78 | 79 | var out = "// This file describes mappings from Unicode codepoints to the keysym values\n" + 80 | "// (and optionally, key names) expected by the RFB protocol\n" + 81 | "// How this file was generated:\n" + 82 | "// " + process.argv.join(" ") + "\n" + 83 | "var keysyms = (function(){\n" + 84 | " \"use strict\";\n" + 85 | " var keynames = {keysyms};\n" + 86 | " var codepoints = {codepoints};\n" + 87 | "\n" + 88 | " function lookup(k) { return k ? {keysym: k, keyname: keynames ? keynames[k] : k} : undefined; }\n" + 89 | " return {\n" + 90 | " fromUnicode : function(u) { return lookup(codepoints[u]); },\n" + 91 | " lookup : lookup\n" + 92 | " };\n" + 93 | "})();\n"; 94 | out = out.replace('{keysyms}', use_keynames ? JSON.stringify(keysyms) : "null"); 95 | out = out.replace('{codepoints}', JSON.stringify(codepoints)); 96 | 97 | fs.writeFileSync("keysymdef.js", out); 98 | -------------------------------------------------------------------------------- /novnc/utils/rebind: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | usage() { 4 | echo "Usage: $(basename $0) OLD_PORT NEW_PORT COMMAND_LINE" 5 | echo 6 | echo "Launch COMMAND_LINE, but intercept system calls to bind" 7 | echo "to OLD_PORT and instead bind them to localhost:NEW_PORT" 8 | exit 2 9 | } 10 | 11 | # Parameter defaults 12 | mydir=$(readlink -f $(dirname ${0})) 13 | 14 | export REBIND_PORT_OLD="${1}"; shift 15 | export REBIND_PORT_NEW="${1}"; shift 16 | 17 | LD_PRELOAD=${mydir}/rebind.so "${@}" 18 | 19 | -------------------------------------------------------------------------------- /novnc/utils/rebind.c: -------------------------------------------------------------------------------- 1 | /* 2 | * rebind: Intercept bind calls and bind to a different port 3 | * Copyright 2010 Joel Martin 4 | * Licensed under MPL-2.0 (see docs/LICENSE.MPL-2.0) 5 | * 6 | * Overload (LD_PRELOAD) bind system call. If REBIND_PORT_OLD and 7 | * REBIND_PORT_NEW environment variables are set then bind on the new 8 | * port (of localhost) instead of the old port. 9 | * 10 | * This allows a bridge/proxy (such as websockify) to run on the old port and 11 | * translate traffic to/from the new port. 12 | * 13 | * Usage: 14 | * LD_PRELOAD=./rebind.so \ 15 | * REBIND_PORT_OLD=23 \ 16 | * REBIND_PORT_NEW=2023 \ 17 | * program 18 | */ 19 | 20 | //#define DO_DEBUG 1 21 | 22 | #include 23 | #include 24 | 25 | #define __USE_GNU 1 // Pull in RTLD_NEXT 26 | #include 27 | 28 | #include 29 | #include 30 | 31 | 32 | #if defined(DO_DEBUG) 33 | #define DEBUG(...) \ 34 | fprintf(stderr, "wswrapper: "); \ 35 | fprintf(stderr, __VA_ARGS__); 36 | #else 37 | #define DEBUG(...) 38 | #endif 39 | 40 | 41 | int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) 42 | { 43 | static void * (*func)(); 44 | int do_move = 0; 45 | struct sockaddr_in * addr_in = (struct sockaddr_in *)addr; 46 | struct sockaddr_in addr_tmp; 47 | socklen_t addrlen_tmp; 48 | char * PORT_OLD, * PORT_NEW, * end1, * end2; 49 | int ret, oldport, newport, askport = htons(addr_in->sin_port); 50 | uint32_t askaddr = htons(addr_in->sin_addr.s_addr); 51 | if (!func) func = (void *(*)()) dlsym(RTLD_NEXT, "bind"); 52 | 53 | DEBUG(">> bind(%d, _, %d), askaddr %d, askport %d\n", 54 | sockfd, addrlen, askaddr, askport); 55 | 56 | /* Determine if we should move this socket */ 57 | if (addr_in->sin_family == AF_INET) { 58 | // TODO: support IPv6 59 | PORT_OLD = getenv("REBIND_OLD_PORT"); 60 | PORT_NEW = getenv("REBIND_NEW_PORT"); 61 | if (PORT_OLD && (*PORT_OLD != '\0') && 62 | PORT_NEW && (*PORT_NEW != '\0')) { 63 | oldport = strtol(PORT_OLD, &end1, 10); 64 | newport = strtol(PORT_NEW, &end2, 10); 65 | if (oldport && (*end1 == '\0') && 66 | newport && (*end2 == '\0') && 67 | (oldport == askport)) { 68 | do_move = 1; 69 | } 70 | } 71 | } 72 | 73 | if (! do_move) { 74 | /* Just pass everything right through to the real bind */ 75 | ret = (int) func(sockfd, addr, addrlen); 76 | DEBUG("<< bind(%d, _, %d) ret %d\n", sockfd, addrlen, ret); 77 | return ret; 78 | } 79 | 80 | DEBUG("binding fd %d on localhost:%d instead of 0x%x:%d\n", 81 | sockfd, newport, ntohl(addr_in->sin_addr.s_addr), oldport); 82 | 83 | /* Use a temporary location for the new address information */ 84 | addrlen_tmp = sizeof(addr_tmp); 85 | memcpy(&addr_tmp, addr, addrlen_tmp); 86 | 87 | /* Bind to other port on the loopback instead */ 88 | addr_tmp.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 89 | addr_tmp.sin_port = htons(newport); 90 | ret = (int) func(sockfd, &addr_tmp, addrlen_tmp); 91 | 92 | DEBUG("<< bind(%d, _, %d) ret %d\n", sockfd, addrlen, ret); 93 | return ret; 94 | } 95 | -------------------------------------------------------------------------------- /novnc/utils/u2x11: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Convert "U+..." commented entries in /usr/include/X11/keysymdef.h 4 | # into JavaScript for use by noVNC. Note this is likely to produce 5 | # a few duplicate properties with clashing values, that will need 6 | # resolving manually. 7 | # 8 | # Colin Dean 9 | # 10 | 11 | regex="^#define[ \t]+XK_[A-Za-z0-9_]+[ \t]+0x([0-9a-fA-F]+)[ \t]+\/\*[ \t]+U\+([0-9a-fA-F]+)[ \t]+[^*]+.[ \t]+\*\/[ \t]*$" 12 | echo "unicodeTable = {" 13 | while read line; do 14 | if echo "${line}" | egrep -qs "${regex}"; then 15 | 16 | x11=$(echo "${line}" | sed -r "s/${regex}/\1/") 17 | vnc=$(echo "${line}" | sed -r "s/${regex}/\2/") 18 | 19 | if echo "${vnc}" | egrep -qs "^00[2-9A-F][0-9A-F]$"; then 20 | : # skip ISO Latin-1 (U+0020 to U+00FF) as 1-to-1 mapping 21 | else 22 | # note 1-to-1 is possible (e.g. for Euro symbol, U+20AC) 23 | echo " 0x${vnc} : 0x${x11}," 24 | fi 25 | fi 26 | done < /usr/include/X11/keysymdef.h | uniq 27 | echo "};" 28 | 29 | -------------------------------------------------------------------------------- /novnc/utils/web.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | ''' 3 | A super simple HTTP/HTTPS webserver for python. Automatically detect 4 | 5 | You can make a cert/key with openssl using: 6 | openssl req -new -x509 -days 365 -nodes -out self.pem -keyout self.pem 7 | as taken from http://docs.python.org/dev/library/ssl.html#certificates 8 | 9 | ''' 10 | 11 | import traceback, sys 12 | import socket 13 | import ssl 14 | #import http.server as server # python 3.X 15 | import SimpleHTTPServer as server # python 2.X 16 | 17 | def do_request(connstream, from_addr): 18 | x = object() 19 | server.SimpleHTTPRequestHandler(connstream, from_addr, x) 20 | connstream.close() 21 | 22 | def serve(): 23 | bindsocket = socket.socket() 24 | bindsocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 25 | #bindsocket.bind(('localhost', PORT)) 26 | bindsocket.bind(('', PORT)) 27 | bindsocket.listen(5) 28 | 29 | print("serving on port", PORT) 30 | 31 | while True: 32 | try: 33 | newsocket, from_addr = bindsocket.accept() 34 | peek = newsocket.recv(1024, socket.MSG_PEEK) 35 | if peek.startswith("\x16"): 36 | connstream = ssl.wrap_socket( 37 | newsocket, 38 | server_side=True, 39 | certfile='self.pem', 40 | ssl_version=ssl.PROTOCOL_TLSv1) 41 | else: 42 | connstream = newsocket 43 | 44 | do_request(connstream, from_addr) 45 | 46 | except Exception: 47 | traceback.print_exc() 48 | 49 | try: 50 | PORT = int(sys.argv[1]) 51 | except: 52 | print "%s port" % sys.argv[0] 53 | sys.exit(2) 54 | 55 | serve() 56 | -------------------------------------------------------------------------------- /novnc/utils/websockify.py: -------------------------------------------------------------------------------- 1 | websockify -------------------------------------------------------------------------------- /novnc/utils/wsproxy.py: -------------------------------------------------------------------------------- 1 | websockify -------------------------------------------------------------------------------- /novnc/vnc.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 15 | noVNC 16 | 17 | 18 | 19 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 45 | 46 | 47 | 48 | 49 |
50 | 51 |
52 | 55 |
56 | 58 | 60 | 62 | 64 | 67 | 71 | 75 |
76 | 78 | 80 | 82 | 84 | 86 |
87 |
88 |
89 | 90 |
Loading
91 | 92 | 93 |
94 | 97 | 100 | 103 | 106 | 109 | 112 |
113 | 114 | 115 | 116 |
117 | noVNC is a browser based VNC client implemented using HTML5 Canvas 118 | and WebSockets. You will either need a VNC server with WebSockets 119 | support (such as libvncserver) 120 | or you will need to use 121 | websockify 122 | to bridge between your browser and VNC server. See the noVNC 123 | README 124 | and website 125 | for more information. 126 |
127 | 128 |
129 | 130 | 131 |
132 |
133 | 134 | 135 |
136 | 138 |
139 | 141 |
142 | 143 | 144 |
145 | 146 | 147 | 148 | 149 | 150 |
151 | 152 | 153 |
154 | 155 |
    156 |
  • Encrypt
  • 157 |
  • True Color
  • 158 |
  • Local Cursor
  • 159 |
  • Clip to Window
  • 160 |
  • Shared Mode
  • 161 |
  • View Only
  • 162 |
  • Path
  • 163 |
  • Repeater ID
  • 164 |
    165 | 166 |
  • 170 |
  • 171 | 172 | 173 |
  • 176 |
  • 177 |
    178 |
  • 179 |
180 |
181 |
182 | 183 | 184 |
185 |
    186 |
  • 187 |
  • 188 |
  • 189 |
  • 190 |
191 |
192 | 193 |
194 | 195 | 196 |
197 |
198 | 199 |

no
VNC

200 | 201 | 202 |
203 | 204 | Canvas not supported. 205 | 206 |
207 | 208 |
209 | 210 | 211 | 212 | 213 | 214 | -------------------------------------------------------------------------------- /novnc/vnc_auto.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 15 | noVNC 16 | 17 | 18 | 19 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 34 | 35 | 36 | 37 | 38 | 39 | 43 | 44 | 45 | 46 | 47 |
48 |
49 | 50 | 53 | 65 |
51 | Loading 52 |
54 | 56 | 57 | 59 | 61 | 63 | 64 |
66 |
67 | 68 | Canvas not supported. 69 | 70 |
71 | 72 | 207 | 208 | 209 | 210 | -------------------------------------------------------------------------------- /supervisord.conf: -------------------------------------------------------------------------------- 1 | [supervisord] 2 | nodaemon=true 3 | 4 | [program:X11] 5 | command=/usr/bin/Xvfb :0 -screen 0 %(ENV_RES)s 6 | autorestart=true 7 | 8 | [program:x11vnc] 9 | command=/usr/bin/x11vnc 10 | autorestart=true 11 | 12 | [program:novnc] 13 | command=/root/novnc/utils/launch.sh --vnc localhost:5900 --listen 8080 14 | autorestart=true 15 | 16 | [program:fluxbox] 17 | command=/usr/bin/fluxbox 18 | autorestart=true 19 | 20 | [program:chromium] 21 | command=/usr/bin/chromium-browser --no-sandbox -test-type --window-position=0,0 --window-size=1024,722 22 | autorestart=true 23 | 24 | 25 | -------------------------------------------------------------------------------- /supervisord.conf.arm: -------------------------------------------------------------------------------- 1 | [supervisord] 2 | nodaemon=true 3 | 4 | [program:X11] 5 | command=/usr/bin/Xvfb :0 -screen 0 %(ENV_RES)s 6 | autorestart=true 7 | 8 | [program:x11vnc] 9 | command=/usr/bin/x11vnc 10 | autorestart=true 11 | 12 | [program:novnc] 13 | command=/root/novnc/utils/launch.sh --vnc localhost:5900 --listen 8080 14 | autorestart=true 15 | 16 | [program:fluxbox] 17 | command=/usr/bin/fluxbox 18 | autorestart=true 19 | 20 | [program:chromium-browser] 21 | command=/usr/bin/chromium-browser --no-sandbox --user-data-dir --no-sandbox -test-type --window-position=0,0 --window-size=1024,722 22 | autorestart=true 23 | --------------------------------------------------------------------------------