From bcb39a3295741f6dddd5d7e3a1db23b62baa38b4 Mon Sep 17 00:00:00 2001 From: Evan Broder Date: Fri, 31 Oct 2008 06:20:51 -0400 Subject: [PATCH] Isolate our patches to the VNC client from the upstream TightVNC source svn path=/trunk/packages/invirt-vnc-client/; revision=1438 --- ButtonPanel.java | 23 +- InvirtTrustManager.java | 122 ---- Makefile | 10 +- RfbProto.java | 4 +- SocketWrapper.java | 262 --------- VNCProxyConnectSocket.java | 61 -- VNCProxyConnectSocketFactory.java | 98 ---- VNCProxyConnectSocketWrapper.java | 60 -- VncCanvas.java | 4 - config.todo | 1 - debian/changelog | 6 + debian/control | 2 +- debian/patches/add-control-alt-checkboxes.patch | 83 +++ debian/patches/invirt-ssl-proxy.patch | 685 +++++++++++++++++++++++ debian/patches/makefile-source-version.patch | 13 + debian/patches/series | 3 + debian/rules | 1 + 17 files changed, 797 insertions(+), 641 deletions(-) delete mode 100644 InvirtTrustManager.java delete mode 100644 SocketWrapper.java delete mode 100644 VNCProxyConnectSocket.java delete mode 100644 VNCProxyConnectSocketFactory.java delete mode 100644 VNCProxyConnectSocketWrapper.java delete mode 100644 config.todo create mode 100644 debian/patches/add-control-alt-checkboxes.patch create mode 100644 debian/patches/invirt-ssl-proxy.patch create mode 100644 debian/patches/makefile-source-version.patch create mode 100644 debian/patches/series diff --git a/ButtonPanel.java b/ButtonPanel.java index 73f2446..5cae865 100644 --- a/ButtonPanel.java +++ b/ButtonPanel.java @@ -27,7 +27,7 @@ import java.awt.*; import java.awt.event.*; import java.io.*; -class ButtonPanel extends Panel implements ActionListener, ItemListener { +class ButtonPanel extends Panel implements ActionListener { VncViewer viewer; Button disconnectButton; @@ -36,8 +36,6 @@ class ButtonPanel extends Panel implements ActionListener, ItemListener { Button clipboardButton; Button ctrlAltDelButton; Button refreshButton; - Checkbox altCheckbox; - Checkbox ctrlCheckbox; ButtonPanel(VncViewer v) { viewer = v; @@ -67,15 +65,6 @@ class ButtonPanel extends Panel implements ActionListener, ItemListener { refreshButton.setEnabled(false); add(refreshButton); refreshButton.addActionListener(this); - - altCheckbox = new Checkbox("Alt"); - altCheckbox.setEnabled(false); - add(altCheckbox); - altCheckbox.addItemListener(this); - ctrlCheckbox = new Checkbox("Control"); - ctrlCheckbox.setEnabled(false); - add(ctrlCheckbox); - ctrlCheckbox.addItemListener(this); } // @@ -114,8 +103,6 @@ class ButtonPanel extends Panel implements ActionListener, ItemListener { public void enableRemoteAccessControls(boolean enable) { ctrlAltDelButton.setEnabled(enable); - ctrlCheckbox.setEnabled(enable); - altCheckbox.setEnabled(enable); } // @@ -163,13 +150,5 @@ class ButtonPanel extends Panel implements ActionListener, ItemListener { } } } - public void itemStateChanged(ItemEvent evt) { - viewer.moveFocusToDesktop(); - int state = evt.getStateChange(); - int extraModifiers = 0; - if (altCheckbox.getState()) { extraModifiers |= InputEvent.ALT_MASK; } - if (ctrlCheckbox.getState()) { extraModifiers |= InputEvent.CTRL_MASK; } - viewer.vc.extraModifiers = extraModifiers; - } } diff --git a/InvirtTrustManager.java b/InvirtTrustManager.java deleted file mode 100644 index 97ab55b..0000000 --- a/InvirtTrustManager.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright 2006 Perry Nguyen - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import java.io.IOException; -import java.io.InputStream; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; -import java.util.Enumeration; -import java.util.logging.Level; -import java.util.logging.Logger; - -import javax.net.ssl.TrustManager; -import javax.net.ssl.TrustManagerFactory; -import javax.net.ssl.X509TrustManager; - -public class InvirtTrustManager implements X509TrustManager { - private X509TrustManager trustManager; - private final static char[] KEY_STORE_PASSWORD = - { 'f', 'o', 'o', 'b', 'a', 'r' }; - private final static String KEY_STORE_RESOURCE = - "trust.store"; - - private KeyStore loadKeyStore() throws Exception { - InputStream in = getClass().getClassLoader().getResourceAsStream( - KEY_STORE_RESOURCE); - KeyStore ks = null; - try { - if (in == null) { - //log.severe("Unable to open KeyStore"); - throw new NullPointerException(); - } - ks = KeyStore.getInstance(KeyStore.getDefaultType()); - ks.load(in, KEY_STORE_PASSWORD); - /*if (log.isLoggable(Level.FINEST)) { - for (Enumeration aliases = ks.aliases(); - aliases.hasMoreElements();) { - String alias = aliases.nextElement(); - log.finest("ALIAS: " + alias); - } - }*/ - } catch (NoSuchAlgorithmException e) { - throwError(e); - } catch (CertificateException e) { - throwError(e); - } catch (IOException e) { - throwError(e); - } catch (KeyStoreException e) { - throwError(e); - } finally { - try { - if (in != null) - in.close(); - } - catch (IOException e) { } // ignore - } - return ks; - } - private void createTrustManager() { - try { - try { - KeyStore keystore = loadKeyStore(); - TrustManagerFactory factory = TrustManagerFactory.getInstance( - TrustManagerFactory.getDefaultAlgorithm()); - factory.init(keystore); - TrustManager[] trustManagers = factory.getTrustManagers(); - if (trustManagers.length == 0) - throw new IllegalStateException("No trust manager found"); - setTrustManager((X509TrustManager) trustManagers[0]); - } catch (NoSuchAlgorithmException e) { - throwError(e); - } catch (KeyStoreException e) { - throwError(e); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - private void throwError(Exception e) throws Exception { - //HttpClientError error = new HttpClientError(e.getMessage()); - //error.initCause(e); - throw e; - } - public X509TrustManager getTrustManager() { - if (trustManager == null) - createTrustManager(); - return trustManager; - } - - public void setTrustManager(X509TrustManager trustManager) { - this.trustManager = trustManager; - } - - public void checkClientTrusted(X509Certificate[] chain, String authType) - throws CertificateException { - getTrustManager().checkClientTrusted(chain, authType); - } - - public void checkServerTrusted(X509Certificate[] chain, String authType) - throws CertificateException { - getTrustManager().checkServerTrusted(chain, authType); - - } - - public X509Certificate[] getAcceptedIssuers() { - return getTrustManager().getAcceptedIssuers(); - } - -} \ No newline at end of file diff --git a/Makefile b/Makefile index 259ee2c..f236eae 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ CP = cp JC = javac -JCFLAGS = -target 1.1 -source 1.2 +JCFLAGS = -target 1.1 JAR = jar ARCHIVE = VncViewer.jar MANIFEST = MANIFEST.MF @@ -17,10 +17,8 @@ CLASSES = VncViewer.class RfbProto.class AuthPanel.class VncCanvas.class \ DesCipher.class CapabilityInfo.class CapsContainer.class \ RecordingFrame.class SessionRecorder.class \ SocketFactory.class HTTPConnectSocketFactory.class \ - VNCProxyConnectSocketFactory.class VNCProxyConnectSocket.class \ HTTPConnectSocket.class ReloginPanel.class \ - InStream.class MemInStream.class ZlibInStream.class \ - VNCProxyConnectSocketWrapper.class SocketWrapper.class SocketWrapper\$$WrappingSocketImpl.class InvirtTrustManager.class + InStream.class MemInStream.class ZlibInStream.class SOURCES = VncViewer.java RfbProto.java AuthPanel.java VncCanvas.java \ VncCanvas2.java \ @@ -28,10 +26,8 @@ SOURCES = VncViewer.java RfbProto.java AuthPanel.java VncCanvas.java \ DesCipher.java CapabilityInfo.java CapsContainer.java \ RecordingFrame.java SessionRecorder.java \ SocketFactory.java HTTPConnectSocketFactory.java \ - VNCProxyConnectSocketFactory.java VNCProxyConnectSocket.java \ HTTPConnectSocket.java ReloginPanel.java \ - InStream.java MemInStream.java ZlibInStream.java \ - VNCProxyConnectSocketWrapper.java SocketWrapper.java InvirtTrustManager.java + InStream.java MemInStream.java ZlibInStream.java all: $(CLASSES) $(ARCHIVE) diff --git a/RfbProto.java b/RfbProto.java index c0f500a..1ca25c0 100644 --- a/RfbProto.java +++ b/RfbProto.java @@ -208,13 +208,11 @@ class RfbProto { port = p; if (viewer.socketFactory == null) { - System.out.println("Null socketFactory"); sock = new Socket(host, port); } else { try { Class factoryClass = Class.forName(viewer.socketFactory); SocketFactory factory = (SocketFactory)factoryClass.newInstance(); - System.out.println("Using socketFactory " + factory); if (viewer.inAnApplet) sock = factory.createSocket(host, port, viewer); else @@ -238,7 +236,7 @@ class RfbProto { try { sock.close(); closed = true; - System.out.println("RFB socket closed " + sock); + System.out.println("RFB socket closed"); if (rec != null) { rec.close(); rec = null; diff --git a/SocketWrapper.java b/SocketWrapper.java deleted file mode 100644 index e488b28..0000000 --- a/SocketWrapper.java +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Written by Dawid Kurzyniec and released to the public domain, as explained - * at http://creativecommons.org/licenses/publicdomain - */ - -//package edu.emory.mathcs.util.net; - -import java.io.*; -import java.net.*; -import java.nio.channels.*; - -/** - * Wrapper for sockets which enables to add functionality in subclasses - * on top of existing, connected sockets. It is useful when direct subclassing - * of delegate socket class is not possible, e.g. if the delegate socket is - * created by a library. Possible usage example is socket factory chaining. - * This class delegates all socket-related requests to the wrapped delegate, - * as of JDK 1.4. - * - * @author Dawid Kurzyniec - * @version 1.4 - */ -public abstract class SocketWrapper extends Socket { - - /** - * the wrapped delegate socket. - */ - protected final Socket delegate; - - /** - * Creates new socket wrapper for a given socket. The delegate - * must be connected and bound and it must not be closed. - * @param delegate the delegate socket to wrap - * @throws SocketException if the delegate socket is closed, not bound, - * or not connected - */ - protected SocketWrapper(Socket delegate) throws SocketException { - super(new WrappingSocketImpl(delegate)); - this.delegate = delegate; - System.out.println("Creating SocketWrapper $Rev$"); - } - - public SocketChannel getChannel() { - return delegate.getChannel(); - } - - /** - * Returns true, indicating that the socket is bound. - * - * @return true - */ - public boolean isBound() { - return true; - } - - public boolean isClosed() { - return super.isClosed() || delegate.isClosed(); - } - - /** - * Returns true, indicating that the socket is connected. - * - * @return true - */ - public boolean isConnected() { - return true; - } - - public boolean isInputShutdown() { - return super.isInputShutdown() || delegate.isInputShutdown(); - } - - public boolean isOutputShutdown() { - return super.isInputShutdown() || delegate.isOutputShutdown(); - } - - private static class WrappingSocketImpl extends SocketImpl { - private final Socket delegate; - WrappingSocketImpl(Socket delegate) throws SocketException { - if (delegate == null) { - throw new NullPointerException(); - } - if (delegate.isClosed()) { - throw new SocketException("Delegate server socket is closed"); - } - if (!(delegate.isBound())) { - throw new SocketException("Delegate server socket is not bound"); - } - if (!(delegate.isConnected())) { - throw new SocketException("Delegate server socket is not connected"); - } - this.delegate = delegate; - } - - protected void create(boolean stream) {} - - protected void connect(String host, int port) { - // delegate is always connected, thus this method is never called - throw new UnsupportedOperationException(); - } - - protected void connect(InetAddress address, int port) { - // delegate is always connected, thus this method is never called - throw new UnsupportedOperationException(); - } - - protected void connect(SocketAddress address, int timeout) { - // delegate is always connected, thus this method is never called - throw new UnsupportedOperationException(); - } - - protected void bind(InetAddress host, int port) { - // delegate is always bound, thus this method is never called - throw new UnsupportedOperationException(); - } - - protected void listen(int backlog) { - // this wrapper is never used by a ServerSocket - throw new UnsupportedOperationException(); - } - - protected void accept(SocketImpl s) { - // this wrapper is never used by a ServerSocket - throw new UnsupportedOperationException(); - } - - protected InputStream getInputStream() throws IOException { - return delegate.getInputStream(); - } - - protected OutputStream getOutputStream() throws IOException { - return delegate.getOutputStream(); - } - - protected int available() throws IOException { - return getInputStream().available(); - } - - protected void close() throws IOException { - System.out.println("Calling delegate.close"); - delegate.close(); - } - - protected void shutdownInput() throws IOException { - delegate.shutdownInput(); - } - - protected void shutdownOutput() throws IOException { - delegate.shutdownOutput(); - } - - protected FileDescriptor getFileDescriptor() { - // this wrapper is never used by a ServerSocket - throw new UnsupportedOperationException(); - } - - protected InetAddress getInetAddress() { - return delegate.getInetAddress(); - } - - protected int getPort() { - return delegate.getPort(); - } - - protected boolean supportsUrgentData() { - return false; // must be overridden in sub-class - } - - protected void sendUrgentData (int data) throws IOException { - delegate.sendUrgentData(data); - } - - protected int getLocalPort() { - return delegate.getLocalPort(); - } - - public Object getOption(int optID) throws SocketException { - switch (optID) { - case SocketOptions.IP_TOS: - return new Integer(delegate.getTrafficClass()); - case SocketOptions.SO_BINDADDR: - return delegate.getLocalAddress(); - case SocketOptions.SO_KEEPALIVE: - return Boolean.valueOf(delegate.getKeepAlive()); - case SocketOptions.SO_LINGER: - return new Integer(delegate.getSoLinger()); - case SocketOptions.SO_OOBINLINE: - return Boolean.valueOf(delegate.getOOBInline()); - case SocketOptions.SO_RCVBUF: - return new Integer(delegate.getReceiveBufferSize()); - case SocketOptions.SO_REUSEADDR: - return Boolean.valueOf(delegate.getReuseAddress()); - case SocketOptions.SO_SNDBUF: - return new Integer(delegate.getSendBufferSize()); - case SocketOptions.SO_TIMEOUT: - return new Integer(delegate.getSoTimeout()); - case SocketOptions.TCP_NODELAY: - return Boolean.valueOf(delegate.getTcpNoDelay()); - case SocketOptions.SO_BROADCAST: - default: - throw new IllegalArgumentException("Unsupported option type"); - } - } - - public void setOption(int optID, Object value) throws SocketException { - switch (optID) { - case SocketOptions.SO_BINDADDR: - throw new IllegalArgumentException("Socket is bound"); - case SocketOptions.SO_KEEPALIVE: - delegate.setKeepAlive(((Boolean)value).booleanValue()); - break; - case SocketOptions.SO_LINGER: - if (value instanceof Boolean) { - delegate.setSoLinger(((Boolean)value).booleanValue(), 0); - } - else { - delegate.setSoLinger(true, ((Integer)value).intValue()); - } - break; - case SocketOptions.SO_OOBINLINE: - delegate.setOOBInline(((Boolean)value).booleanValue()); - break; - case SocketOptions.SO_RCVBUF: - delegate.setReceiveBufferSize(((Integer)value).intValue()); - break; - case SocketOptions.SO_REUSEADDR: - delegate.setReuseAddress(((Boolean)value).booleanValue()); - break; - case SocketOptions.SO_SNDBUF: - delegate.setSendBufferSize(((Integer)value).intValue()); - break; - case SocketOptions.SO_TIMEOUT: - delegate.setSoTimeout(((Integer)value).intValue()); - break; - case SocketOptions.TCP_NODELAY: - delegate.setTcpNoDelay(((Boolean)value).booleanValue()); - break; - case SocketOptions.SO_BROADCAST: - default: - throw new IllegalArgumentException("Unsupported option type"); - } - } - } - - public void close() throws IOException { - System.out.println("Calling SocketWrapper.delegate.close"); - delegate.close(); - } - - public boolean equals(Object obj) { - if (!(obj instanceof SocketWrapper)) return false; - SocketWrapper that = (SocketWrapper)obj; - return this.delegate.equals(that.delegate); - } - - public int hashCode() { - return delegate.hashCode() ^ 0x01010101; - } - public String toString() { - return ""; - } -} \ No newline at end of file diff --git a/VNCProxyConnectSocket.java b/VNCProxyConnectSocket.java deleted file mode 100644 index 595acd5..0000000 --- a/VNCProxyConnectSocket.java +++ /dev/null @@ -1,61 +0,0 @@ -// -// Copyright (C) 2002 Constantin Kaplinsky, Inc. All Rights Reserved. -// Copyright 2007 MIT Student Information Processing Board -// -// This is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This software is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this software; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, -// USA. -// - -// -// VNCProxySocket.java together with VNCProxySocketFactory.java -// implement an alternate way to connect to VNC servers via one or two -// VNCProxy proxies supporting the VNCProxy VNCCONNECT method. -// - -import java.net.*; -import java.io.*; - -class VNCProxyConnectSocket extends Socket { - - public VNCProxyConnectSocket(String host, int port, - String vmname, String authtoken) - throws IOException { - - // Connect to the specified HTTP proxy - super(host, port); - - // Send the CONNECT request - getOutputStream().write(("CONNECTVNC " + vmname + - " VNCProxy/1.0\r\nAuth-token: " + authtoken + - "\r\n\r\n").getBytes()); - - // Read the first line of the response - DataInputStream is = new DataInputStream(getInputStream()); - String str = is.readLine(); - - // Check the HTTP error code -- it should be "200" on success - if (!str.startsWith("VNCProxy/1.0 200 ")) { - if (str.startsWith("VNCProxy/1.0 ")) - str = str.substring(13); - throw new IOException("Proxy reports \"" + str + "\""); - } - - // Success -- skip remaining HTTP headers - do { - str = is.readLine(); - } while (str.length() != 0); - } -} - diff --git a/VNCProxyConnectSocketFactory.java b/VNCProxyConnectSocketFactory.java deleted file mode 100644 index 2f06536..0000000 --- a/VNCProxyConnectSocketFactory.java +++ /dev/null @@ -1,98 +0,0 @@ -// -// Copyright (C) 2002 Constantin Kaplinsky, Inc. All Rights Reserved. -// Copyright 2007 MIT Student Information Processing Board -// -// This is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This software is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this software; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, -// USA. -// - -// -// VNCProxyConnectSocketFactory.java together with VNCProxyConnectSocket.java -// implement an alternate way to connect to VNC servers via one or two -// VNCProxy proxies supporting the VNCProxy CONNECT method. -// - -import java.applet.*; -import java.net.*; -import javax.net.ssl.*; -import java.io.*; - -class VNCProxyConnectSocketFactory implements SocketFactory { - - SSLSocketFactory factory; - - public VNCProxyConnectSocketFactory() { - try { - SSLContext c = SSLContext.getInstance("SSL"); - c.init(null, - new TrustManager[] { new InvirtTrustManager() }, - null); - factory = - (SSLSocketFactory)c.getSocketFactory(); - } catch (Exception e) { - e.printStackTrace(); - } - } - - public Socket createSocket(String host, int port, Applet applet) - throws IOException { - - return createSocket(host, port, - applet.getParameter("VMNAME"), - applet.getParameter("AUTHTOKEN")); - } - - public Socket createSocket(String host, int port, String[] args) - throws IOException { - - return createSocket(host, port, - readArg(args, "VMNAME"), - readArg(args, "AUTHTOKEN")); - } - - public Socket createSocket(String host, int port, - String vmname, String authtoken) - throws IOException { - - if (vmname == null || authtoken == null) { - System.out.println("Incomplete parameter list for VNCProxyConnectSocket"); - return new Socket(host, port); - } - - System.out.println("VNCProxy CONNECT via proxy " + host + - " port " + port + " to vm " + vmname); - SSLSocket ssls = (SSLSocket)factory.createSocket(host, port); - ssls.startHandshake(); - VNCProxyConnectSocketWrapper s = - new VNCProxyConnectSocketWrapper(ssls, vmname, authtoken); - - return (Socket)s; - } - - private String readArg(String[] args, String name) { - - for (int i = 0; i < args.length; i += 2) { - if (args[i].equalsIgnoreCase(name)) { - try { - return args[i+1]; - } catch (Exception e) { - return null; - } - } - } - return null; - } -} - diff --git a/VNCProxyConnectSocketWrapper.java b/VNCProxyConnectSocketWrapper.java deleted file mode 100644 index 69a0fa8..0000000 --- a/VNCProxyConnectSocketWrapper.java +++ /dev/null @@ -1,60 +0,0 @@ -// -// Copyright (C) 2002 Constantin Kaplinsky, Inc. All Rights Reserved. -// Copyright 2007 MIT Student Information Processing Board -// -// This is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 of the License, or -// (at your option) any later version. -// -// This software is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this software; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, -// USA. -// - -// -// VNCProxySocket.java together with VNCProxySocketFactory.java -// implement an alternate way to connect to VNC servers via one or two -// VNCProxy proxies supporting the VNCProxy VNCCONNECT method. -// - -import java.net.*; -import java.io.*; - -class VNCProxyConnectSocketWrapper extends SocketWrapper { - - public VNCProxyConnectSocketWrapper(Socket sock, - String vmname, String authtoken) - throws IOException { - - super(sock); - - // Send the CONNECT request - getOutputStream().write(("CONNECTVNC " + vmname + - " VNCProxy/1.0\r\nAuth-token: " + authtoken + - "\r\n\r\n").getBytes()); - - // Read the first line of the response - DataInputStream is = new DataInputStream(getInputStream()); - String str = is.readLine(); - - // Check the HTTP error code -- it should be "200" on success - if (!str.startsWith("VNCProxy/1.0 200 ")) { - if (str.startsWith("VNCProxy/1.0 ")) - str = str.substring(13); - throw new IOException("Proxy reports \"" + str + "\""); - } - - // Success -- skip remaining HTTP headers - do { - str = is.readLine(); - } while (str.length() != 0); - } -} - diff --git a/VncCanvas.java b/VncCanvas.java index 4cb7d63..df84409 100644 --- a/VncCanvas.java +++ b/VncCanvas.java @@ -79,7 +79,6 @@ class VncCanvas extends Canvas // True if we process keyboard and mouse events. boolean inputEnabled; - int extraModifiers = 0; // // The constructors. @@ -1511,9 +1510,6 @@ class VncCanvas extends Canvas // Input enabled. synchronized(rfb) { try { - if (extraModifiers != 0) { - evt.setModifiers(evt.getModifiers() | extraModifiers); - } rfb.writeKeyEvent(evt); } catch (Exception e) { e.printStackTrace(); diff --git a/config.todo b/config.todo deleted file mode 100644 index 8b5b2ce..0000000 --- a/config.todo +++ /dev/null @@ -1 +0,0 @@ -all: separate our changes from upstream diff --git a/debian/changelog b/debian/changelog index 6230edc..da08cb2 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +invirt-vnc-client (0.0.6) unstable; urgency=low + + * Isolate our patches from the upstream source + + -- Evan Broder Fri, 31 Oct 2008 06:10:38 -0400 + invirt-vnc-client (0.0.5) unstable; urgency=low * Small typo fixes in invirt-update-vnc-cert diff --git a/debian/control b/debian/control index 4a63481..bcb8562 100644 --- a/debian/control +++ b/debian/control @@ -2,7 +2,7 @@ Source: invirt-vnc-client Section: base Priority: extra Maintainer: Invirt project -Build-Depends: cdbs (>= 0.4.23-1.1), debhelper (>= 4.1.0), subversion, sun-java6-jdk | java-compiler +Build-Depends: cdbs (>= 0.4.23-1.1), debhelper (>= 4.1.0), quilt, sun-java6-jdk | java-compiler Standards-Version: 3.7.2 Package: invirt-vnc-client diff --git a/debian/patches/add-control-alt-checkboxes.patch b/debian/patches/add-control-alt-checkboxes.patch new file mode 100644 index 0000000..3a9e797 --- /dev/null +++ b/debian/patches/add-control-alt-checkboxes.patch @@ -0,0 +1,83 @@ +Index: invirt-vnc-client/ButtonPanel.java +=================================================================== +--- invirt-vnc-client.orig/ButtonPanel.java 2008-10-31 06:08:45.000000000 -0400 ++++ invirt-vnc-client/ButtonPanel.java 2008-10-31 06:09:10.000000000 -0400 +@@ -27,7 +27,7 @@ + import java.awt.event.*; + import java.io.*; + +-class ButtonPanel extends Panel implements ActionListener { ++class ButtonPanel extends Panel implements ActionListener, ItemListener { + + VncViewer viewer; + Button disconnectButton; +@@ -36,6 +36,8 @@ + Button clipboardButton; + Button ctrlAltDelButton; + Button refreshButton; ++ Checkbox altCheckbox; ++ Checkbox ctrlCheckbox; + + ButtonPanel(VncViewer v) { + viewer = v; +@@ -65,6 +67,15 @@ + refreshButton.setEnabled(false); + add(refreshButton); + refreshButton.addActionListener(this); ++ ++ altCheckbox = new Checkbox("Alt"); ++ altCheckbox.setEnabled(false); ++ add(altCheckbox); ++ altCheckbox.addItemListener(this); ++ ctrlCheckbox = new Checkbox("Control"); ++ ctrlCheckbox.setEnabled(false); ++ add(ctrlCheckbox); ++ ctrlCheckbox.addItemListener(this); + } + + // +@@ -103,6 +114,8 @@ + + public void enableRemoteAccessControls(boolean enable) { + ctrlAltDelButton.setEnabled(enable); ++ ctrlCheckbox.setEnabled(enable); ++ altCheckbox.setEnabled(enable); + } + + // +@@ -150,5 +163,13 @@ + } + } + } ++ public void itemStateChanged(ItemEvent evt) { ++ viewer.moveFocusToDesktop(); ++ int state = evt.getStateChange(); ++ int extraModifiers = 0; ++ if (altCheckbox.getState()) { extraModifiers |= InputEvent.ALT_MASK; } ++ if (ctrlCheckbox.getState()) { extraModifiers |= InputEvent.CTRL_MASK; } ++ viewer.vc.extraModifiers = extraModifiers; ++ } + } + +Index: invirt-vnc-client/VncCanvas.java +=================================================================== +--- invirt-vnc-client.orig/VncCanvas.java 2008-10-31 06:08:45.000000000 -0400 ++++ invirt-vnc-client/VncCanvas.java 2008-10-31 06:09:10.000000000 -0400 +@@ -79,6 +79,7 @@ + + // True if we process keyboard and mouse events. + boolean inputEnabled; ++ int extraModifiers = 0; + + // + // The constructors. +@@ -1510,6 +1511,9 @@ + // Input enabled. + synchronized(rfb) { + try { ++ if (extraModifiers != 0) { ++ evt.setModifiers(evt.getModifiers() | extraModifiers); ++ } + rfb.writeKeyEvent(evt); + } catch (Exception e) { + e.printStackTrace(); diff --git a/debian/patches/invirt-ssl-proxy.patch b/debian/patches/invirt-ssl-proxy.patch new file mode 100644 index 0000000..f777283 --- /dev/null +++ b/debian/patches/invirt-ssl-proxy.patch @@ -0,0 +1,685 @@ +Index: invirt-vnc-client/InvirtTrustManager.java +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ invirt-vnc-client/InvirtTrustManager.java 2008-10-31 06:09:10.000000000 -0400 +@@ -0,0 +1,122 @@ ++/* ++ * Copyright 2006 Perry Nguyen ++ * Licensed under the Apache License, Version 2.0 (the "License"); ++ * you may not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ * See the License for the specific language governing permissions and ++ * limitations under the License. ++ */ ++import java.io.IOException; ++import java.io.InputStream; ++import java.security.KeyStore; ++import java.security.KeyStoreException; ++import java.security.NoSuchAlgorithmException; ++import java.security.cert.CertificateException; ++import java.security.cert.X509Certificate; ++import java.util.Enumeration; ++import java.util.logging.Level; ++import java.util.logging.Logger; ++ ++import javax.net.ssl.TrustManager; ++import javax.net.ssl.TrustManagerFactory; ++import javax.net.ssl.X509TrustManager; ++ ++public class InvirtTrustManager implements X509TrustManager { ++ private X509TrustManager trustManager; ++ private final static char[] KEY_STORE_PASSWORD = ++ { 'f', 'o', 'o', 'b', 'a', 'r' }; ++ private final static String KEY_STORE_RESOURCE = ++ "trust.store"; ++ ++ private KeyStore loadKeyStore() throws Exception { ++ InputStream in = getClass().getClassLoader().getResourceAsStream( ++ KEY_STORE_RESOURCE); ++ KeyStore ks = null; ++ try { ++ if (in == null) { ++ //log.severe("Unable to open KeyStore"); ++ throw new NullPointerException(); ++ } ++ ks = KeyStore.getInstance(KeyStore.getDefaultType()); ++ ks.load(in, KEY_STORE_PASSWORD); ++ /*if (log.isLoggable(Level.FINEST)) { ++ for (Enumeration aliases = ks.aliases(); ++ aliases.hasMoreElements();) { ++ String alias = aliases.nextElement(); ++ log.finest("ALIAS: " + alias); ++ } ++ }*/ ++ } catch (NoSuchAlgorithmException e) { ++ throwError(e); ++ } catch (CertificateException e) { ++ throwError(e); ++ } catch (IOException e) { ++ throwError(e); ++ } catch (KeyStoreException e) { ++ throwError(e); ++ } finally { ++ try { ++ if (in != null) ++ in.close(); ++ } ++ catch (IOException e) { } // ignore ++ } ++ return ks; ++ } ++ private void createTrustManager() { ++ try { ++ try { ++ KeyStore keystore = loadKeyStore(); ++ TrustManagerFactory factory = TrustManagerFactory.getInstance( ++ TrustManagerFactory.getDefaultAlgorithm()); ++ factory.init(keystore); ++ TrustManager[] trustManagers = factory.getTrustManagers(); ++ if (trustManagers.length == 0) ++ throw new IllegalStateException("No trust manager found"); ++ setTrustManager((X509TrustManager) trustManagers[0]); ++ } catch (NoSuchAlgorithmException e) { ++ throwError(e); ++ } catch (KeyStoreException e) { ++ throwError(e); ++ } ++ } catch (Exception e) { ++ e.printStackTrace(); ++ } ++ } ++ private void throwError(Exception e) throws Exception { ++ //HttpClientError error = new HttpClientError(e.getMessage()); ++ //error.initCause(e); ++ throw e; ++ } ++ public X509TrustManager getTrustManager() { ++ if (trustManager == null) ++ createTrustManager(); ++ return trustManager; ++ } ++ ++ public void setTrustManager(X509TrustManager trustManager) { ++ this.trustManager = trustManager; ++ } ++ ++ public void checkClientTrusted(X509Certificate[] chain, String authType) ++ throws CertificateException { ++ getTrustManager().checkClientTrusted(chain, authType); ++ } ++ ++ public void checkServerTrusted(X509Certificate[] chain, String authType) ++ throws CertificateException { ++ getTrustManager().checkServerTrusted(chain, authType); ++ ++ } ++ ++ public X509Certificate[] getAcceptedIssuers() { ++ return getTrustManager().getAcceptedIssuers(); ++ } ++ ++} +\ No newline at end of file +Index: invirt-vnc-client/Makefile +=================================================================== +--- invirt-vnc-client.orig/Makefile 2008-10-31 06:09:10.000000000 -0400 ++++ invirt-vnc-client/Makefile 2008-10-31 06:09:10.000000000 -0400 +@@ -17,8 +17,10 @@ + DesCipher.class CapabilityInfo.class CapsContainer.class \ + RecordingFrame.class SessionRecorder.class \ + SocketFactory.class HTTPConnectSocketFactory.class \ ++ VNCProxyConnectSocketFactory.class VNCProxyConnectSocket.class \ + HTTPConnectSocket.class ReloginPanel.class \ +- InStream.class MemInStream.class ZlibInStream.class ++ InStream.class MemInStream.class ZlibInStream.class \ ++ VNCProxyConnectSocketWrapper.class SocketWrapper.class SocketWrapper\$$WrappingSocketImpl.class InvirtTrustManager.class + + SOURCES = VncViewer.java RfbProto.java AuthPanel.java VncCanvas.java \ + VncCanvas2.java \ +@@ -26,8 +28,10 @@ + DesCipher.java CapabilityInfo.java CapsContainer.java \ + RecordingFrame.java SessionRecorder.java \ + SocketFactory.java HTTPConnectSocketFactory.java \ ++ VNCProxyConnectSocketFactory.java VNCProxyConnectSocket.java \ + HTTPConnectSocket.java ReloginPanel.java \ +- InStream.java MemInStream.java ZlibInStream.java ++ InStream.java MemInStream.java ZlibInStream.java \ ++ VNCProxyConnectSocketWrapper.java SocketWrapper.java InvirtTrustManager.java + + all: $(CLASSES) $(ARCHIVE) + +Index: invirt-vnc-client/RfbProto.java +=================================================================== +--- invirt-vnc-client.orig/RfbProto.java 2007-04-26 22:36:00.000000000 -0400 ++++ invirt-vnc-client/RfbProto.java 2008-10-31 06:09:10.000000000 -0400 +@@ -208,11 +208,13 @@ + port = p; + + if (viewer.socketFactory == null) { ++ System.out.println("Null socketFactory"); + sock = new Socket(host, port); + } else { + try { + Class factoryClass = Class.forName(viewer.socketFactory); + SocketFactory factory = (SocketFactory)factoryClass.newInstance(); ++ System.out.println("Using socketFactory " + factory); + if (viewer.inAnApplet) + sock = factory.createSocket(host, port, viewer); + else +@@ -236,7 +238,7 @@ + try { + sock.close(); + closed = true; +- System.out.println("RFB socket closed"); ++ System.out.println("RFB socket closed " + sock); + if (rec != null) { + rec.close(); + rec = null; +Index: invirt-vnc-client/SocketWrapper.java +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ invirt-vnc-client/SocketWrapper.java 2008-10-31 06:09:10.000000000 -0400 +@@ -0,0 +1,262 @@ ++/* ++ * Written by Dawid Kurzyniec and released to the public domain, as explained ++ * at http://creativecommons.org/licenses/publicdomain ++ */ ++ ++//package edu.emory.mathcs.util.net; ++ ++import java.io.*; ++import java.net.*; ++import java.nio.channels.*; ++ ++/** ++ * Wrapper for sockets which enables to add functionality in subclasses ++ * on top of existing, connected sockets. It is useful when direct subclassing ++ * of delegate socket class is not possible, e.g. if the delegate socket is ++ * created by a library. Possible usage example is socket factory chaining. ++ * This class delegates all socket-related requests to the wrapped delegate, ++ * as of JDK 1.4. ++ * ++ * @author Dawid Kurzyniec ++ * @version 1.4 ++ */ ++public abstract class SocketWrapper extends Socket { ++ ++ /** ++ * the wrapped delegate socket. ++ */ ++ protected final Socket delegate; ++ ++ /** ++ * Creates new socket wrapper for a given socket. The delegate ++ * must be connected and bound and it must not be closed. ++ * @param delegate the delegate socket to wrap ++ * @throws SocketException if the delegate socket is closed, not bound, ++ * or not connected ++ */ ++ protected SocketWrapper(Socket delegate) throws SocketException { ++ super(new WrappingSocketImpl(delegate)); ++ this.delegate = delegate; ++ System.out.println("Creating SocketWrapper $Rev$"); ++ } ++ ++ public SocketChannel getChannel() { ++ return delegate.getChannel(); ++ } ++ ++ /** ++ * Returns true, indicating that the socket is bound. ++ * ++ * @return true ++ */ ++ public boolean isBound() { ++ return true; ++ } ++ ++ public boolean isClosed() { ++ return super.isClosed() || delegate.isClosed(); ++ } ++ ++ /** ++ * Returns true, indicating that the socket is connected. ++ * ++ * @return true ++ */ ++ public boolean isConnected() { ++ return true; ++ } ++ ++ public boolean isInputShutdown() { ++ return super.isInputShutdown() || delegate.isInputShutdown(); ++ } ++ ++ public boolean isOutputShutdown() { ++ return super.isInputShutdown() || delegate.isOutputShutdown(); ++ } ++ ++ private static class WrappingSocketImpl extends SocketImpl { ++ private final Socket delegate; ++ WrappingSocketImpl(Socket delegate) throws SocketException { ++ if (delegate == null) { ++ throw new NullPointerException(); ++ } ++ if (delegate.isClosed()) { ++ throw new SocketException("Delegate server socket is closed"); ++ } ++ if (!(delegate.isBound())) { ++ throw new SocketException("Delegate server socket is not bound"); ++ } ++ if (!(delegate.isConnected())) { ++ throw new SocketException("Delegate server socket is not connected"); ++ } ++ this.delegate = delegate; ++ } ++ ++ protected void create(boolean stream) {} ++ ++ protected void connect(String host, int port) { ++ // delegate is always connected, thus this method is never called ++ throw new UnsupportedOperationException(); ++ } ++ ++ protected void connect(InetAddress address, int port) { ++ // delegate is always connected, thus this method is never called ++ throw new UnsupportedOperationException(); ++ } ++ ++ protected void connect(SocketAddress address, int timeout) { ++ // delegate is always connected, thus this method is never called ++ throw new UnsupportedOperationException(); ++ } ++ ++ protected void bind(InetAddress host, int port) { ++ // delegate is always bound, thus this method is never called ++ throw new UnsupportedOperationException(); ++ } ++ ++ protected void listen(int backlog) { ++ // this wrapper is never used by a ServerSocket ++ throw new UnsupportedOperationException(); ++ } ++ ++ protected void accept(SocketImpl s) { ++ // this wrapper is never used by a ServerSocket ++ throw new UnsupportedOperationException(); ++ } ++ ++ protected InputStream getInputStream() throws IOException { ++ return delegate.getInputStream(); ++ } ++ ++ protected OutputStream getOutputStream() throws IOException { ++ return delegate.getOutputStream(); ++ } ++ ++ protected int available() throws IOException { ++ return getInputStream().available(); ++ } ++ ++ protected void close() throws IOException { ++ System.out.println("Calling delegate.close"); ++ delegate.close(); ++ } ++ ++ protected void shutdownInput() throws IOException { ++ delegate.shutdownInput(); ++ } ++ ++ protected void shutdownOutput() throws IOException { ++ delegate.shutdownOutput(); ++ } ++ ++ protected FileDescriptor getFileDescriptor() { ++ // this wrapper is never used by a ServerSocket ++ throw new UnsupportedOperationException(); ++ } ++ ++ protected InetAddress getInetAddress() { ++ return delegate.getInetAddress(); ++ } ++ ++ protected int getPort() { ++ return delegate.getPort(); ++ } ++ ++ protected boolean supportsUrgentData() { ++ return false; // must be overridden in sub-class ++ } ++ ++ protected void sendUrgentData (int data) throws IOException { ++ delegate.sendUrgentData(data); ++ } ++ ++ protected int getLocalPort() { ++ return delegate.getLocalPort(); ++ } ++ ++ public Object getOption(int optID) throws SocketException { ++ switch (optID) { ++ case SocketOptions.IP_TOS: ++ return new Integer(delegate.getTrafficClass()); ++ case SocketOptions.SO_BINDADDR: ++ return delegate.getLocalAddress(); ++ case SocketOptions.SO_KEEPALIVE: ++ return Boolean.valueOf(delegate.getKeepAlive()); ++ case SocketOptions.SO_LINGER: ++ return new Integer(delegate.getSoLinger()); ++ case SocketOptions.SO_OOBINLINE: ++ return Boolean.valueOf(delegate.getOOBInline()); ++ case SocketOptions.SO_RCVBUF: ++ return new Integer(delegate.getReceiveBufferSize()); ++ case SocketOptions.SO_REUSEADDR: ++ return Boolean.valueOf(delegate.getReuseAddress()); ++ case SocketOptions.SO_SNDBUF: ++ return new Integer(delegate.getSendBufferSize()); ++ case SocketOptions.SO_TIMEOUT: ++ return new Integer(delegate.getSoTimeout()); ++ case SocketOptions.TCP_NODELAY: ++ return Boolean.valueOf(delegate.getTcpNoDelay()); ++ case SocketOptions.SO_BROADCAST: ++ default: ++ throw new IllegalArgumentException("Unsupported option type"); ++ } ++ } ++ ++ public void setOption(int optID, Object value) throws SocketException { ++ switch (optID) { ++ case SocketOptions.SO_BINDADDR: ++ throw new IllegalArgumentException("Socket is bound"); ++ case SocketOptions.SO_KEEPALIVE: ++ delegate.setKeepAlive(((Boolean)value).booleanValue()); ++ break; ++ case SocketOptions.SO_LINGER: ++ if (value instanceof Boolean) { ++ delegate.setSoLinger(((Boolean)value).booleanValue(), 0); ++ } ++ else { ++ delegate.setSoLinger(true, ((Integer)value).intValue()); ++ } ++ break; ++ case SocketOptions.SO_OOBINLINE: ++ delegate.setOOBInline(((Boolean)value).booleanValue()); ++ break; ++ case SocketOptions.SO_RCVBUF: ++ delegate.setReceiveBufferSize(((Integer)value).intValue()); ++ break; ++ case SocketOptions.SO_REUSEADDR: ++ delegate.setReuseAddress(((Boolean)value).booleanValue()); ++ break; ++ case SocketOptions.SO_SNDBUF: ++ delegate.setSendBufferSize(((Integer)value).intValue()); ++ break; ++ case SocketOptions.SO_TIMEOUT: ++ delegate.setSoTimeout(((Integer)value).intValue()); ++ break; ++ case SocketOptions.TCP_NODELAY: ++ delegate.setTcpNoDelay(((Boolean)value).booleanValue()); ++ break; ++ case SocketOptions.SO_BROADCAST: ++ default: ++ throw new IllegalArgumentException("Unsupported option type"); ++ } ++ } ++ } ++ ++ public void close() throws IOException { ++ System.out.println("Calling SocketWrapper.delegate.close"); ++ delegate.close(); ++ } ++ ++ public boolean equals(Object obj) { ++ if (!(obj instanceof SocketWrapper)) return false; ++ SocketWrapper that = (SocketWrapper)obj; ++ return this.delegate.equals(that.delegate); ++ } ++ ++ public int hashCode() { ++ return delegate.hashCode() ^ 0x01010101; ++ } ++ public String toString() { ++ return ""; ++ } ++} +\ No newline at end of file +Index: invirt-vnc-client/VNCProxyConnectSocket.java +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ invirt-vnc-client/VNCProxyConnectSocket.java 2008-10-31 06:09:10.000000000 -0400 +@@ -0,0 +1,61 @@ ++// ++// Copyright (C) 2002 Constantin Kaplinsky, Inc. All Rights Reserved. ++// Copyright 2007 MIT Student Information Processing Board ++// ++// This is free software; you can redistribute it and/or modify ++// it under the terms of the GNU General Public License as published by ++// the Free Software Foundation; either version 2 of the License, or ++// (at your option) any later version. ++// ++// This software is distributed in the hope that it will be useful, ++// but WITHOUT ANY WARRANTY; without even the implied warranty of ++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++// GNU General Public License for more details. ++// ++// You should have received a copy of the GNU General Public License ++// along with this software; if not, write to the Free Software ++// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, ++// USA. ++// ++ ++// ++// VNCProxySocket.java together with VNCProxySocketFactory.java ++// implement an alternate way to connect to VNC servers via one or two ++// VNCProxy proxies supporting the VNCProxy VNCCONNECT method. ++// ++ ++import java.net.*; ++import java.io.*; ++ ++class VNCProxyConnectSocket extends Socket { ++ ++ public VNCProxyConnectSocket(String host, int port, ++ String vmname, String authtoken) ++ throws IOException { ++ ++ // Connect to the specified HTTP proxy ++ super(host, port); ++ ++ // Send the CONNECT request ++ getOutputStream().write(("CONNECTVNC " + vmname + ++ " VNCProxy/1.0\r\nAuth-token: " + authtoken + ++ "\r\n\r\n").getBytes()); ++ ++ // Read the first line of the response ++ DataInputStream is = new DataInputStream(getInputStream()); ++ String str = is.readLine(); ++ ++ // Check the HTTP error code -- it should be "200" on success ++ if (!str.startsWith("VNCProxy/1.0 200 ")) { ++ if (str.startsWith("VNCProxy/1.0 ")) ++ str = str.substring(13); ++ throw new IOException("Proxy reports \"" + str + "\""); ++ } ++ ++ // Success -- skip remaining HTTP headers ++ do { ++ str = is.readLine(); ++ } while (str.length() != 0); ++ } ++} ++ +Index: invirt-vnc-client/VNCProxyConnectSocketFactory.java +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ invirt-vnc-client/VNCProxyConnectSocketFactory.java 2008-10-31 06:09:10.000000000 -0400 +@@ -0,0 +1,98 @@ ++// ++// Copyright (C) 2002 Constantin Kaplinsky, Inc. All Rights Reserved. ++// Copyright 2007 MIT Student Information Processing Board ++// ++// This is free software; you can redistribute it and/or modify ++// it under the terms of the GNU General Public License as published by ++// the Free Software Foundation; either version 2 of the License, or ++// (at your option) any later version. ++// ++// This software is distributed in the hope that it will be useful, ++// but WITHOUT ANY WARRANTY; without even the implied warranty of ++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++// GNU General Public License for more details. ++// ++// You should have received a copy of the GNU General Public License ++// along with this software; if not, write to the Free Software ++// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, ++// USA. ++// ++ ++// ++// VNCProxyConnectSocketFactory.java together with VNCProxyConnectSocket.java ++// implement an alternate way to connect to VNC servers via one or two ++// VNCProxy proxies supporting the VNCProxy CONNECT method. ++// ++ ++import java.applet.*; ++import java.net.*; ++import javax.net.ssl.*; ++import java.io.*; ++ ++class VNCProxyConnectSocketFactory implements SocketFactory { ++ ++ SSLSocketFactory factory; ++ ++ public VNCProxyConnectSocketFactory() { ++ try { ++ SSLContext c = SSLContext.getInstance("SSL"); ++ c.init(null, ++ new TrustManager[] { new InvirtTrustManager() }, ++ null); ++ factory = ++ (SSLSocketFactory)c.getSocketFactory(); ++ } catch (Exception e) { ++ e.printStackTrace(); ++ } ++ } ++ ++ public Socket createSocket(String host, int port, Applet applet) ++ throws IOException { ++ ++ return createSocket(host, port, ++ applet.getParameter("VMNAME"), ++ applet.getParameter("AUTHTOKEN")); ++ } ++ ++ public Socket createSocket(String host, int port, String[] args) ++ throws IOException { ++ ++ return createSocket(host, port, ++ readArg(args, "VMNAME"), ++ readArg(args, "AUTHTOKEN")); ++ } ++ ++ public Socket createSocket(String host, int port, ++ String vmname, String authtoken) ++ throws IOException { ++ ++ if (vmname == null || authtoken == null) { ++ System.out.println("Incomplete parameter list for VNCProxyConnectSocket"); ++ return new Socket(host, port); ++ } ++ ++ System.out.println("VNCProxy CONNECT via proxy " + host + ++ " port " + port + " to vm " + vmname); ++ SSLSocket ssls = (SSLSocket)factory.createSocket(host, port); ++ ssls.startHandshake(); ++ VNCProxyConnectSocketWrapper s = ++ new VNCProxyConnectSocketWrapper(ssls, vmname, authtoken); ++ ++ return (Socket)s; ++ } ++ ++ private String readArg(String[] args, String name) { ++ ++ for (int i = 0; i < args.length; i += 2) { ++ if (args[i].equalsIgnoreCase(name)) { ++ try { ++ return args[i+1]; ++ } catch (Exception e) { ++ return null; ++ } ++ } ++ } ++ return null; ++ } ++} ++ +Index: invirt-vnc-client/VNCProxyConnectSocketWrapper.java +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ invirt-vnc-client/VNCProxyConnectSocketWrapper.java 2008-10-31 06:09:10.000000000 -0400 +@@ -0,0 +1,60 @@ ++// ++// Copyright (C) 2002 Constantin Kaplinsky, Inc. All Rights Reserved. ++// Copyright 2007 MIT Student Information Processing Board ++// ++// This is free software; you can redistribute it and/or modify ++// it under the terms of the GNU General Public License as published by ++// the Free Software Foundation; either version 2 of the License, or ++// (at your option) any later version. ++// ++// This software is distributed in the hope that it will be useful, ++// but WITHOUT ANY WARRANTY; without even the implied warranty of ++// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++// GNU General Public License for more details. ++// ++// You should have received a copy of the GNU General Public License ++// along with this software; if not, write to the Free Software ++// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, ++// USA. ++// ++ ++// ++// VNCProxySocket.java together with VNCProxySocketFactory.java ++// implement an alternate way to connect to VNC servers via one or two ++// VNCProxy proxies supporting the VNCProxy VNCCONNECT method. ++// ++ ++import java.net.*; ++import java.io.*; ++ ++class VNCProxyConnectSocketWrapper extends SocketWrapper { ++ ++ public VNCProxyConnectSocketWrapper(Socket sock, ++ String vmname, String authtoken) ++ throws IOException { ++ ++ super(sock); ++ ++ // Send the CONNECT request ++ getOutputStream().write(("CONNECTVNC " + vmname + ++ " VNCProxy/1.0\r\nAuth-token: " + authtoken + ++ "\r\n\r\n").getBytes()); ++ ++ // Read the first line of the response ++ DataInputStream is = new DataInputStream(getInputStream()); ++ String str = is.readLine(); ++ ++ // Check the HTTP error code -- it should be "200" on success ++ if (!str.startsWith("VNCProxy/1.0 200 ")) { ++ if (str.startsWith("VNCProxy/1.0 ")) ++ str = str.substring(13); ++ throw new IOException("Proxy reports \"" + str + "\""); ++ } ++ ++ // Success -- skip remaining HTTP headers ++ do { ++ str = is.readLine(); ++ } while (str.length() != 0); ++ } ++} ++ diff --git a/debian/patches/makefile-source-version.patch b/debian/patches/makefile-source-version.patch new file mode 100644 index 0000000..c985b62 --- /dev/null +++ b/debian/patches/makefile-source-version.patch @@ -0,0 +1,13 @@ +Index: invirt-vnc-client/Makefile +=================================================================== +--- invirt-vnc-client.orig/Makefile 2008-10-31 06:08:46.000000000 -0400 ++++ invirt-vnc-client/Makefile 2008-10-31 06:09:17.000000000 -0400 +@@ -4,7 +4,7 @@ + + CP = cp + JC = javac +-JCFLAGS = -target 1.1 ++JCFLAGS = -target 1.1 -source 1.2 + JAR = jar + ARCHIVE = VncViewer.jar + MANIFEST = MANIFEST.MF diff --git a/debian/patches/series b/debian/patches/series new file mode 100644 index 0000000..94c002c --- /dev/null +++ b/debian/patches/series @@ -0,0 +1,3 @@ +makefile-source-version.patch +add-control-alt-checkboxes.patch +invirt-ssl-proxy.patch diff --git a/debian/rules b/debian/rules index 3a557cf..533190a 100755 --- a/debian/rules +++ b/debian/rules @@ -1,6 +1,7 @@ #!/usr/bin/make -f include /usr/share/cdbs/1/rules/debhelper.mk +include /usr/share/cdbs/1/rules/patchsys-quilt.mk include /usr/share/cdbs/1/class/makefile.mk DEB_MAKE_INSTALL_TARGET = install INSTALL_DIR=$(DEB_DESTDIR)/usr/share/invirt-vnc-client -- 1.7.9.5