1 Index: invirt-vnc-client/InvirtTrustManager.java
2 ===================================================================
3 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
4 +++ invirt-vnc-client/InvirtTrustManager.java 2008-10-31 06:09:10.000000000 -0400
6 +// This code is based on http://svntrac.hanhuy.com/repo/browser/hanhuy/trunk/cms/src/com/hanhuy/ria/client/RIATrustManager.java
8 + * Copyright 2006 Perry Nguyen <pfnguyen@hanhuy.com>
9 + * Licensed under the Apache License, Version 2.0 (the "License");
10 + * you may not use this file except in compliance with the License.
11 + * You may obtain a copy of the License at
13 + * http://www.apache.org/licenses/LICENSE-2.0
15 + * Unless required by applicable law or agreed to in writing, software
16 + * distributed under the License is distributed on an "AS IS" BASIS,
17 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 + * See the License for the specific language governing permissions and
19 + * limitations under the License.
21 +import java.io.IOException;
22 +import java.io.InputStream;
23 +import java.security.KeyStore;
24 +import java.security.KeyStoreException;
25 +import java.security.NoSuchAlgorithmException;
26 +import java.security.cert.CertificateException;
27 +import java.security.cert.X509Certificate;
28 +import java.util.Enumeration;
29 +import java.util.logging.Level;
30 +import java.util.logging.Logger;
32 +import javax.net.ssl.TrustManager;
33 +import javax.net.ssl.TrustManagerFactory;
34 +import javax.net.ssl.X509TrustManager;
36 +public class InvirtTrustManager implements X509TrustManager {
37 + private X509TrustManager trustManager;
38 + private final static char[] KEY_STORE_PASSWORD =
39 + { 'f', 'o', 'o', 'b', 'a', 'r' };
40 + private final static String KEY_STORE_RESOURCE =
43 + private KeyStore loadKeyStore() throws Exception {
44 + InputStream in = getClass().getClassLoader().getResourceAsStream(
45 + KEY_STORE_RESOURCE);
49 + //log.severe("Unable to open KeyStore");
50 + throw new NullPointerException();
52 + ks = KeyStore.getInstance(KeyStore.getDefaultType());
53 + ks.load(in, KEY_STORE_PASSWORD);
54 + /*if (log.isLoggable(Level.FINEST)) {
55 + for (Enumeration<String> aliases = ks.aliases();
56 + aliases.hasMoreElements();) {
57 + String alias = aliases.nextElement();
58 + log.finest("ALIAS: " + alias);
61 + } catch (NoSuchAlgorithmException e) {
63 + } catch (CertificateException e) {
65 + } catch (IOException e) {
67 + } catch (KeyStoreException e) {
74 + catch (IOException e) { } // ignore
78 + private void createTrustManager() {
81 + KeyStore keystore = loadKeyStore();
82 + TrustManagerFactory factory = TrustManagerFactory.getInstance(
83 + TrustManagerFactory.getDefaultAlgorithm());
84 + factory.init(keystore);
85 + TrustManager[] trustManagers = factory.getTrustManagers();
86 + if (trustManagers.length == 0)
87 + throw new IllegalStateException("No trust manager found");
88 + setTrustManager((X509TrustManager) trustManagers[0]);
89 + } catch (NoSuchAlgorithmException e) {
91 + } catch (KeyStoreException e) {
94 + } catch (Exception e) {
95 + e.printStackTrace();
98 + private void throwError(Exception e) throws Exception {
99 + //HttpClientError error = new HttpClientError(e.getMessage());
100 + //error.initCause(e);
103 + public X509TrustManager getTrustManager() {
104 + if (trustManager == null)
105 + createTrustManager();
106 + return trustManager;
109 + public void setTrustManager(X509TrustManager trustManager) {
110 + this.trustManager = trustManager;
113 + public void checkClientTrusted(X509Certificate[] chain, String authType)
114 + throws CertificateException {
115 + getTrustManager().checkClientTrusted(chain, authType);
118 + public void checkServerTrusted(X509Certificate[] chain, String authType)
119 + throws CertificateException {
120 + getTrustManager().checkServerTrusted(chain, authType);
124 + public X509Certificate[] getAcceptedIssuers() {
125 + return getTrustManager().getAcceptedIssuers();
129 \ No newline at end of file
130 Index: invirt-vnc-client/Makefile
131 ===================================================================
132 --- invirt-vnc-client.orig/Makefile 2008-10-31 06:09:10.000000000 -0400
133 +++ invirt-vnc-client/Makefile 2008-10-31 06:09:10.000000000 -0400
135 DesCipher.class CapabilityInfo.class CapsContainer.class \
136 RecordingFrame.class SessionRecorder.class \
137 SocketFactory.class HTTPConnectSocketFactory.class \
138 + VNCProxyConnectSocketFactory.class VNCProxyConnectSocket.class \
139 HTTPConnectSocket.class ReloginPanel.class \
140 - InStream.class MemInStream.class ZlibInStream.class
141 + InStream.class MemInStream.class ZlibInStream.class \
142 + VNCProxyConnectSocketWrapper.class SocketWrapper.class SocketWrapper\$$WrappingSocketImpl.class InvirtTrustManager.class
144 SOURCES = VncViewer.java RfbProto.java AuthPanel.java VncCanvas.java \
147 DesCipher.java CapabilityInfo.java CapsContainer.java \
148 RecordingFrame.java SessionRecorder.java \
149 SocketFactory.java HTTPConnectSocketFactory.java \
150 + VNCProxyConnectSocketFactory.java VNCProxyConnectSocket.java \
151 HTTPConnectSocket.java ReloginPanel.java \
152 - InStream.java MemInStream.java ZlibInStream.java
153 + InStream.java MemInStream.java ZlibInStream.java \
154 + VNCProxyConnectSocketWrapper.java SocketWrapper.java InvirtTrustManager.java
156 all: $(CLASSES) $(ARCHIVE)
158 Index: invirt-vnc-client/RfbProto.java
159 ===================================================================
160 --- invirt-vnc-client.orig/RfbProto.java 2007-04-26 22:36:00.000000000 -0400
161 +++ invirt-vnc-client/RfbProto.java 2008-10-31 06:09:10.000000000 -0400
162 @@ -208,11 +208,13 @@
165 if (viewer.socketFactory == null) {
166 + System.out.println("Null socketFactory");
167 sock = new Socket(host, port);
170 Class factoryClass = Class.forName(viewer.socketFactory);
171 SocketFactory factory = (SocketFactory)factoryClass.newInstance();
172 + System.out.println("Using socketFactory " + factory);
173 if (viewer.inAnApplet)
174 sock = factory.createSocket(host, port, viewer);
180 - System.out.println("RFB socket closed");
181 + System.out.println("RFB socket closed " + sock);
185 Index: invirt-vnc-client/SocketWrapper.java
186 ===================================================================
187 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
188 +++ invirt-vnc-client/SocketWrapper.java 2008-10-31 06:09:10.000000000 -0400
191 + * Written by Dawid Kurzyniec and released to the public domain, as explained
192 + * at http://creativecommons.org/licenses/publicdomain
194 +// Upstream is at http://www.dcl.mathcs.emory.edu/downloads/h2o/doc/api/edu/emory/mathcs/util/net/SocketWrapper.html
196 +//package edu.emory.mathcs.util.net;
200 +import java.nio.channels.*;
203 + * Wrapper for sockets which enables to add functionality in subclasses
204 + * on top of existing, connected sockets. It is useful when direct subclassing
205 + * of delegate socket class is not possible, e.g. if the delegate socket is
206 + * created by a library. Possible usage example is socket factory chaining.
207 + * This class delegates all socket-related requests to the wrapped delegate,
210 + * @author Dawid Kurzyniec
213 +public abstract class SocketWrapper extends Socket {
216 + * the wrapped delegate socket.
218 + protected final Socket delegate;
221 + * Creates new socket wrapper for a given socket. The delegate
222 + * must be connected and bound and it must not be closed.
223 + * @param delegate the delegate socket to wrap
224 + * @throws SocketException if the delegate socket is closed, not bound,
227 + protected SocketWrapper(Socket delegate) throws SocketException {
228 + super(new WrappingSocketImpl(delegate));
229 + this.delegate = delegate;
230 + System.out.println("Creating SocketWrapper $Rev$");
233 + public SocketChannel getChannel() {
234 + return delegate.getChannel();
238 + * Returns true, indicating that the socket is bound.
242 + public boolean isBound() {
246 + public boolean isClosed() {
247 + return super.isClosed() || delegate.isClosed();
251 + * Returns true, indicating that the socket is connected.
255 + public boolean isConnected() {
259 + public boolean isInputShutdown() {
260 + return super.isInputShutdown() || delegate.isInputShutdown();
263 + public boolean isOutputShutdown() {
264 + return super.isInputShutdown() || delegate.isOutputShutdown();
267 + private static class WrappingSocketImpl extends SocketImpl {
268 + private final Socket delegate;
269 + WrappingSocketImpl(Socket delegate) throws SocketException {
270 + if (delegate == null) {
271 + throw new NullPointerException();
273 + if (delegate.isClosed()) {
274 + throw new SocketException("Delegate server socket is closed");
276 + if (!(delegate.isBound())) {
277 + throw new SocketException("Delegate server socket is not bound");
279 + if (!(delegate.isConnected())) {
280 + throw new SocketException("Delegate server socket is not connected");
282 + this.delegate = delegate;
285 + protected void create(boolean stream) {}
287 + protected void connect(String host, int port) {
288 + // delegate is always connected, thus this method is never called
289 + throw new UnsupportedOperationException();
292 + protected void connect(InetAddress address, int port) {
293 + // delegate is always connected, thus this method is never called
294 + throw new UnsupportedOperationException();
297 + protected void connect(SocketAddress address, int timeout) {
298 + // delegate is always connected, thus this method is never called
299 + throw new UnsupportedOperationException();
302 + protected void bind(InetAddress host, int port) {
303 + // delegate is always bound, thus this method is never called
304 + throw new UnsupportedOperationException();
307 + protected void listen(int backlog) {
308 + // this wrapper is never used by a ServerSocket
309 + throw new UnsupportedOperationException();
312 + protected void accept(SocketImpl s) {
313 + // this wrapper is never used by a ServerSocket
314 + throw new UnsupportedOperationException();
317 + protected InputStream getInputStream() throws IOException {
318 + return delegate.getInputStream();
321 + protected OutputStream getOutputStream() throws IOException {
322 + return delegate.getOutputStream();
325 + protected int available() throws IOException {
326 + return getInputStream().available();
329 + protected void close() throws IOException {
330 + System.out.println("Calling delegate.close");
334 + protected void shutdownInput() throws IOException {
335 + delegate.shutdownInput();
338 + protected void shutdownOutput() throws IOException {
339 + delegate.shutdownOutput();
342 + protected FileDescriptor getFileDescriptor() {
343 + // this wrapper is never used by a ServerSocket
344 + throw new UnsupportedOperationException();
347 + protected InetAddress getInetAddress() {
348 + return delegate.getInetAddress();
351 + protected int getPort() {
352 + return delegate.getPort();
355 + protected boolean supportsUrgentData() {
356 + return false; // must be overridden in sub-class
359 + protected void sendUrgentData (int data) throws IOException {
360 + delegate.sendUrgentData(data);
363 + protected int getLocalPort() {
364 + return delegate.getLocalPort();
367 + public Object getOption(int optID) throws SocketException {
369 + case SocketOptions.IP_TOS:
370 + return new Integer(delegate.getTrafficClass());
371 + case SocketOptions.SO_BINDADDR:
372 + return delegate.getLocalAddress();
373 + case SocketOptions.SO_KEEPALIVE:
374 + return Boolean.valueOf(delegate.getKeepAlive());
375 + case SocketOptions.SO_LINGER:
376 + return new Integer(delegate.getSoLinger());
377 + case SocketOptions.SO_OOBINLINE:
378 + return Boolean.valueOf(delegate.getOOBInline());
379 + case SocketOptions.SO_RCVBUF:
380 + return new Integer(delegate.getReceiveBufferSize());
381 + case SocketOptions.SO_REUSEADDR:
382 + return Boolean.valueOf(delegate.getReuseAddress());
383 + case SocketOptions.SO_SNDBUF:
384 + return new Integer(delegate.getSendBufferSize());
385 + case SocketOptions.SO_TIMEOUT:
386 + return new Integer(delegate.getSoTimeout());
387 + case SocketOptions.TCP_NODELAY:
388 + return Boolean.valueOf(delegate.getTcpNoDelay());
389 + case SocketOptions.SO_BROADCAST:
391 + throw new IllegalArgumentException("Unsupported option type");
395 + public void setOption(int optID, Object value) throws SocketException {
397 + case SocketOptions.SO_BINDADDR:
398 + throw new IllegalArgumentException("Socket is bound");
399 + case SocketOptions.SO_KEEPALIVE:
400 + delegate.setKeepAlive(((Boolean)value).booleanValue());
402 + case SocketOptions.SO_LINGER:
403 + if (value instanceof Boolean) {
404 + delegate.setSoLinger(((Boolean)value).booleanValue(), 0);
407 + delegate.setSoLinger(true, ((Integer)value).intValue());
410 + case SocketOptions.SO_OOBINLINE:
411 + delegate.setOOBInline(((Boolean)value).booleanValue());
413 + case SocketOptions.SO_RCVBUF:
414 + delegate.setReceiveBufferSize(((Integer)value).intValue());
416 + case SocketOptions.SO_REUSEADDR:
417 + delegate.setReuseAddress(((Boolean)value).booleanValue());
419 + case SocketOptions.SO_SNDBUF:
420 + delegate.setSendBufferSize(((Integer)value).intValue());
422 + case SocketOptions.SO_TIMEOUT:
423 + delegate.setSoTimeout(((Integer)value).intValue());
425 + case SocketOptions.TCP_NODELAY:
426 + delegate.setTcpNoDelay(((Boolean)value).booleanValue());
428 + case SocketOptions.SO_BROADCAST:
430 + throw new IllegalArgumentException("Unsupported option type");
435 + public void close() throws IOException {
436 + System.out.println("Calling SocketWrapper.delegate.close");
440 + public boolean equals(Object obj) {
441 + if (!(obj instanceof SocketWrapper)) return false;
442 + SocketWrapper that = (SocketWrapper)obj;
443 + return this.delegate.equals(that.delegate);
446 + public int hashCode() {
447 + return delegate.hashCode() ^ 0x01010101;
449 + public String toString() {
450 + return "<SocketWrapper " + super.toString() + "(delegating to " + delegate.toString() + ")" + ">";
453 \ No newline at end of file
454 Index: invirt-vnc-client/VNCProxyConnectSocket.java
455 ===================================================================
456 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
457 +++ invirt-vnc-client/VNCProxyConnectSocket.java 2008-10-31 06:09:10.000000000 -0400
460 +// Copyright (C) 2002 Constantin Kaplinsky, Inc. All Rights Reserved.
461 +// Copyright 2007 MIT Student Information Processing Board
463 +// This is free software; you can redistribute it and/or modify
464 +// it under the terms of the GNU General Public License as published by
465 +// the Free Software Foundation; either version 2 of the License, or
466 +// (at your option) any later version.
468 +// This software is distributed in the hope that it will be useful,
469 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
470 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
471 +// GNU General Public License for more details.
473 +// You should have received a copy of the GNU General Public License
474 +// along with this software; if not, write to the Free Software
475 +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
480 +// VNCProxySocket.java together with VNCProxySocketFactory.java
481 +// implement an alternate way to connect to VNC servers via one or two
482 +// VNCProxy proxies supporting the VNCProxy VNCCONNECT method.
488 +class VNCProxyConnectSocket extends Socket {
490 + public VNCProxyConnectSocket(String host, int port,
491 + String vmname, String authtoken)
492 + throws IOException {
494 + // Connect to the specified HTTP proxy
497 + // Send the CONNECT request
498 + getOutputStream().write(("CONNECTVNC " + vmname +
499 + " VNCProxy/1.0\r\nAuth-token: " + authtoken +
500 + "\r\n\r\n").getBytes());
502 + // Read the first line of the response
503 + DataInputStream is = new DataInputStream(getInputStream());
504 + String str = is.readLine();
506 + // Check the HTTP error code -- it should be "200" on success
507 + if (!str.startsWith("VNCProxy/1.0 200 ")) {
508 + if (str.startsWith("VNCProxy/1.0 "))
509 + str = str.substring(13);
510 + throw new IOException("Proxy reports \"" + str + "\"");
513 + // Success -- skip remaining HTTP headers
515 + str = is.readLine();
516 + } while (str.length() != 0);
520 Index: invirt-vnc-client/VNCProxyConnectSocketFactory.java
521 ===================================================================
522 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
523 +++ invirt-vnc-client/VNCProxyConnectSocketFactory.java 2008-10-31 06:09:10.000000000 -0400
526 +// Copyright (C) 2002 Constantin Kaplinsky, Inc. All Rights Reserved.
527 +// Copyright 2007 MIT Student Information Processing Board
529 +// This is free software; you can redistribute it and/or modify
530 +// it under the terms of the GNU General Public License as published by
531 +// the Free Software Foundation; either version 2 of the License, or
532 +// (at your option) any later version.
534 +// This software is distributed in the hope that it will be useful,
535 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
536 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
537 +// GNU General Public License for more details.
539 +// You should have received a copy of the GNU General Public License
540 +// along with this software; if not, write to the Free Software
541 +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
546 +// VNCProxyConnectSocketFactory.java together with VNCProxyConnectSocket.java
547 +// implement an alternate way to connect to VNC servers via one or two
548 +// VNCProxy proxies supporting the VNCProxy CONNECT method.
551 +import java.applet.*;
553 +import javax.net.ssl.*;
556 +class VNCProxyConnectSocketFactory implements SocketFactory {
558 + SSLSocketFactory factory;
560 + public VNCProxyConnectSocketFactory() {
562 + SSLContext c = SSLContext.getInstance("SSL");
564 + new TrustManager[] { new InvirtTrustManager() },
567 + (SSLSocketFactory)c.getSocketFactory();
568 + } catch (Exception e) {
569 + e.printStackTrace();
573 + public Socket createSocket(String host, int port, Applet applet)
574 + throws IOException {
576 + return createSocket(host, port,
577 + applet.getParameter("VMNAME"),
578 + applet.getParameter("AUTHTOKEN"));
581 + public Socket createSocket(String host, int port, String[] args)
582 + throws IOException {
584 + return createSocket(host, port,
585 + readArg(args, "VMNAME"),
586 + readArg(args, "AUTHTOKEN"));
589 + public Socket createSocket(String host, int port,
590 + String vmname, String authtoken)
591 + throws IOException {
593 + if (vmname == null || authtoken == null) {
594 + System.out.println("Incomplete parameter list for VNCProxyConnectSocket");
595 + return new Socket(host, port);
598 + System.out.println("VNCProxy CONNECT via proxy " + host +
599 + " port " + port + " to vm " + vmname);
600 + SSLSocket ssls = (SSLSocket)factory.createSocket(host, port);
601 + ssls.startHandshake();
602 + VNCProxyConnectSocketWrapper s =
603 + new VNCProxyConnectSocketWrapper(ssls, vmname, authtoken);
608 + private String readArg(String[] args, String name) {
610 + for (int i = 0; i < args.length; i += 2) {
611 + if (args[i].equalsIgnoreCase(name)) {
614 + } catch (Exception e) {
623 Index: invirt-vnc-client/VNCProxyConnectSocketWrapper.java
624 ===================================================================
625 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
626 +++ invirt-vnc-client/VNCProxyConnectSocketWrapper.java 2008-10-31 06:09:10.000000000 -0400
629 +// Copyright (C) 2002 Constantin Kaplinsky, Inc. All Rights Reserved.
630 +// Copyright 2007 MIT Student Information Processing Board
632 +// This is free software; you can redistribute it and/or modify
633 +// it under the terms of the GNU General Public License as published by
634 +// the Free Software Foundation; either version 2 of the License, or
635 +// (at your option) any later version.
637 +// This software is distributed in the hope that it will be useful,
638 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
639 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
640 +// GNU General Public License for more details.
642 +// You should have received a copy of the GNU General Public License
643 +// along with this software; if not, write to the Free Software
644 +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
649 +// VNCProxySocket.java together with VNCProxySocketFactory.java
650 +// implement an alternate way to connect to VNC servers via one or two
651 +// VNCProxy proxies supporting the VNCProxy VNCCONNECT method.
657 +class VNCProxyConnectSocketWrapper extends SocketWrapper {
659 + public VNCProxyConnectSocketWrapper(Socket sock,
660 + String vmname, String authtoken)
661 + throws IOException {
665 + // Send the CONNECT request
666 + getOutputStream().write(("CONNECTVNC " + vmname +
667 + " VNCProxy/1.0\r\nAuth-token: " + authtoken +
668 + "\r\n\r\n").getBytes());
670 + // Read the first line of the response
671 + DataInputStream is = new DataInputStream(getInputStream());
672 + String str = is.readLine();
674 + // Check the HTTP error code -- it should be "200" on success
675 + if (!str.startsWith("VNCProxy/1.0 200 ")) {
676 + if (str.startsWith("VNCProxy/1.0 "))
677 + str = str.substring(13);
678 + throw new IOException("Proxy reports \"" + str + "\"");
681 + // Success -- skip remaining HTTP headers
683 + str = is.readLine();
684 + } while (str.length() != 0);