source: trunk/packages/invirt-vnc-client/debian/patches/invirt-ssl-proxy.patch @ 1438

Last change on this file since 1438 was 1438, checked in by broder, 16 years ago

Isolate our patches to the VNC client from the upstream TightVNC
source

File size: 24.3 KB
  • new file invirt-vnc-client/InvirtTrustManager.java

    - +  
     1/*
     2 * Copyright 2006 Perry Nguyen <pfnguyen@hanhuy.com>
     3 * Licensed under the Apache License, Version 2.0 (the "License");
     4 * you may not use this file except in compliance with the License.
     5 * You may obtain a copy of the License at
     6 *
     7 *     http://www.apache.org/licenses/LICENSE-2.0
     8 *
     9 * Unless required by applicable law or agreed to in writing, software
     10 * distributed under the License is distributed on an "AS IS" BASIS,
     11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 * See the License for the specific language governing permissions and
     13 * limitations under the License.
     14 */
     15import java.io.IOException;
     16import java.io.InputStream;
     17import java.security.KeyStore;
     18import java.security.KeyStoreException;
     19import java.security.NoSuchAlgorithmException;
     20import java.security.cert.CertificateException;
     21import java.security.cert.X509Certificate;
     22import java.util.Enumeration;
     23import java.util.logging.Level;
     24import java.util.logging.Logger;
     25
     26import javax.net.ssl.TrustManager;
     27import javax.net.ssl.TrustManagerFactory;
     28import javax.net.ssl.X509TrustManager;
     29
     30public class InvirtTrustManager implements X509TrustManager {
     31    private X509TrustManager trustManager;
     32    private final static char[] KEY_STORE_PASSWORD =
     33        { 'f', 'o', 'o', 'b', 'a', 'r' };
     34    private final static String KEY_STORE_RESOURCE =
     35        "trust.store";
     36
     37    private KeyStore loadKeyStore() throws Exception {
     38        InputStream in = getClass().getClassLoader().getResourceAsStream(
     39                KEY_STORE_RESOURCE);
     40        KeyStore ks = null;
     41        try {
     42            if (in == null) {
     43                //log.severe("Unable to open KeyStore");
     44                throw new NullPointerException();
     45            }
     46            ks = KeyStore.getInstance(KeyStore.getDefaultType());
     47            ks.load(in, KEY_STORE_PASSWORD);
     48            /*if (log.isLoggable(Level.FINEST)) {
     49                for (Enumeration<String> aliases = ks.aliases();
     50                aliases.hasMoreElements();) {
     51                    String alias = aliases.nextElement();
     52                    log.finest("ALIAS: " + alias);
     53                }
     54                }*/
     55        } catch (NoSuchAlgorithmException e) {
     56            throwError(e);
     57        } catch (CertificateException e) {
     58            throwError(e);
     59        } catch (IOException e) {
     60            throwError(e);
     61        } catch (KeyStoreException e) {
     62            throwError(e);
     63        } finally {
     64            try {
     65                if (in != null)
     66                    in.close();
     67            }
     68            catch (IOException e) { } // ignore
     69        }
     70        return ks;
     71    }
     72    private void createTrustManager() {
     73        try {
     74            try {
     75                KeyStore keystore = loadKeyStore();
     76                TrustManagerFactory factory = TrustManagerFactory.getInstance(
     77                                                                              TrustManagerFactory.getDefaultAlgorithm());
     78                factory.init(keystore);
     79                TrustManager[] trustManagers = factory.getTrustManagers();
     80                if (trustManagers.length == 0)
     81                    throw new IllegalStateException("No trust manager found");
     82                setTrustManager((X509TrustManager) trustManagers[0]);
     83            } catch (NoSuchAlgorithmException e) {
     84                throwError(e);
     85            } catch (KeyStoreException e) {
     86                throwError(e);
     87            }
     88        } catch (Exception e) {
     89            e.printStackTrace();
     90        }
     91    }
     92    private void throwError(Exception e) throws Exception {
     93        //HttpClientError error = new HttpClientError(e.getMessage());
     94        //error.initCause(e);
     95        throw e;
     96    }
     97    public X509TrustManager getTrustManager() {
     98        if (trustManager == null)
     99            createTrustManager();
     100        return trustManager;
     101    }
     102
     103    public void setTrustManager(X509TrustManager trustManager) {
     104        this.trustManager = trustManager;
     105    }
     106
     107    public void checkClientTrusted(X509Certificate[] chain, String authType)
     108            throws CertificateException {
     109        getTrustManager().checkClientTrusted(chain, authType);
     110    }
     111
     112    public void checkServerTrusted(X509Certificate[] chain, String authType)
     113            throws CertificateException {
     114        getTrustManager().checkServerTrusted(chain, authType);
     115
     116    }
     117
     118    public X509Certificate[] getAcceptedIssuers() {
     119        return getTrustManager().getAcceptedIssuers();
     120    }
     121
     122}
     123 No newline at end of file
  • invirt-vnc-client

    old new  
    1717          DesCipher.class CapabilityInfo.class CapsContainer.class \
    1818          RecordingFrame.class SessionRecorder.class \
    1919          SocketFactory.class HTTPConnectSocketFactory.class \
     20          VNCProxyConnectSocketFactory.class VNCProxyConnectSocket.class \
    2021          HTTPConnectSocket.class ReloginPanel.class \
    21           InStream.class MemInStream.class ZlibInStream.class
     22          InStream.class MemInStream.class ZlibInStream.class \
     23          VNCProxyConnectSocketWrapper.class SocketWrapper.class SocketWrapper\$$WrappingSocketImpl.class InvirtTrustManager.class
    2224
    2325SOURCES = VncViewer.java RfbProto.java AuthPanel.java VncCanvas.java \
    2426          VncCanvas2.java \
     
    2628          DesCipher.java CapabilityInfo.java CapsContainer.java \
    2729          RecordingFrame.java SessionRecorder.java \
    2830          SocketFactory.java HTTPConnectSocketFactory.java \
     31          VNCProxyConnectSocketFactory.java VNCProxyConnectSocket.java \
    2932          HTTPConnectSocket.java ReloginPanel.java \
    30           InStream.java MemInStream.java ZlibInStream.java
     33          InStream.java MemInStream.java ZlibInStream.java \
     34          VNCProxyConnectSocketWrapper.java SocketWrapper.java InvirtTrustManager.java
    3135
    3236all: $(CLASSES) $(ARCHIVE)
    3337
  • invirt-vnc-client

    old new  
    208208    port = p;
    209209
    210210    if (viewer.socketFactory == null) {
     211        System.out.println("Null socketFactory");
    211212      sock = new Socket(host, port);
    212213    } else {
    213214      try {
    214215        Class factoryClass = Class.forName(viewer.socketFactory);
    215216        SocketFactory factory = (SocketFactory)factoryClass.newInstance();
     217        System.out.println("Using socketFactory " + factory);
    216218        if (viewer.inAnApplet)
    217219          sock = factory.createSocket(host, port, viewer);
    218220        else
     
    236238    try {
    237239      sock.close();
    238240      closed = true;
    239       System.out.println("RFB socket closed");
     241      System.out.println("RFB socket closed " + sock);
    240242      if (rec != null) {
    241243        rec.close();
    242244        rec = null;
  • new file invirt-vnc-client/SocketWrapper.java

    - +  
     1/*
     2 * Written by Dawid Kurzyniec and released to the public domain, as explained
     3 * at http://creativecommons.org/licenses/publicdomain
     4 */
     5
     6//package edu.emory.mathcs.util.net;
     7
     8import java.io.*;
     9import java.net.*;
     10import java.nio.channels.*;
     11
     12/**
     13 * Wrapper for sockets which enables to add functionality in subclasses
     14 * on top of existing, connected sockets. It is useful when direct subclassing
     15 * of delegate socket class is not possible, e.g. if the delegate socket is
     16 * created by a library. Possible usage example is socket factory chaining.
     17 * This class delegates all socket-related requests to the wrapped delegate,
     18 * as of JDK 1.4.
     19 *
     20 * @author Dawid Kurzyniec
     21 * @version 1.4
     22 */
     23public abstract class SocketWrapper extends Socket {
     24
     25    /**
     26     * the wrapped delegate socket.
     27     */
     28    protected final Socket delegate;
     29
     30    /**
     31     * Creates new socket wrapper for a given socket. The delegate
     32     * must be connected and bound and it must not be closed.
     33     * @param delegate the delegate socket to wrap
     34     * @throws SocketException if the delegate socket is closed, not bound,
     35     *                         or not connected
     36     */
     37    protected SocketWrapper(Socket delegate) throws SocketException {
     38        super(new WrappingSocketImpl(delegate));
     39        this.delegate = delegate;
     40        System.out.println("Creating SocketWrapper $Rev$");
     41    }
     42
     43    public SocketChannel getChannel() {
     44        return delegate.getChannel();
     45    }
     46
     47    /**
     48     * Returns true, indicating that the socket is bound.
     49     *
     50     * @return true
     51     */
     52    public boolean isBound() {
     53        return true;
     54    }
     55
     56    public boolean isClosed() {
     57        return super.isClosed() || delegate.isClosed();
     58    }
     59
     60    /**
     61     * Returns true, indicating that the socket is connected.
     62     *
     63     * @return true
     64     */
     65    public boolean isConnected() {
     66        return true;
     67    }
     68
     69    public boolean isInputShutdown() {
     70        return super.isInputShutdown() || delegate.isInputShutdown();
     71    }
     72
     73    public boolean isOutputShutdown() {
     74        return super.isInputShutdown() || delegate.isOutputShutdown();
     75    }
     76
     77    private static class WrappingSocketImpl extends SocketImpl {
     78        private final Socket delegate;
     79        WrappingSocketImpl(Socket delegate) throws SocketException {
     80            if (delegate == null) {
     81                throw new NullPointerException();
     82            }
     83            if (delegate.isClosed()) {
     84                throw new SocketException("Delegate server socket is closed");
     85            }
     86            if (!(delegate.isBound())) {
     87                throw new SocketException("Delegate server socket is not bound");
     88            }
     89            if (!(delegate.isConnected())) {
     90                throw new SocketException("Delegate server socket is not connected");
     91            }
     92            this.delegate = delegate;
     93        }
     94
     95        protected void create(boolean stream) {}
     96
     97        protected void connect(String host, int port) {
     98            // delegate is always connected, thus this method is never called
     99            throw new UnsupportedOperationException();
     100        }
     101
     102        protected void connect(InetAddress address, int port) {
     103            // delegate is always connected, thus this method is never called
     104            throw new UnsupportedOperationException();
     105        }
     106
     107        protected void connect(SocketAddress address, int timeout) {
     108            // delegate is always connected, thus this method is never called
     109            throw new UnsupportedOperationException();
     110        }
     111
     112        protected void bind(InetAddress host, int port) {
     113            // delegate is always bound, thus this method is never called
     114            throw new UnsupportedOperationException();
     115        }
     116
     117        protected void listen(int backlog) {
     118            // this wrapper is never used by a ServerSocket
     119            throw new UnsupportedOperationException();
     120        }
     121
     122        protected void accept(SocketImpl s) {
     123            // this wrapper is never used by a ServerSocket
     124            throw new UnsupportedOperationException();
     125        }
     126
     127        protected InputStream getInputStream() throws IOException {
     128            return delegate.getInputStream();
     129        }
     130
     131        protected OutputStream getOutputStream() throws IOException {
     132            return delegate.getOutputStream();
     133        }
     134
     135        protected int available() throws IOException {
     136            return getInputStream().available();
     137        }
     138
     139        protected void close() throws IOException {
     140            System.out.println("Calling delegate.close");
     141            delegate.close();
     142        }
     143
     144        protected void shutdownInput() throws IOException {
     145            delegate.shutdownInput();
     146        }
     147
     148        protected void shutdownOutput() throws IOException {
     149            delegate.shutdownOutput();
     150        }
     151
     152        protected FileDescriptor getFileDescriptor() {
     153            // this wrapper is never used by a ServerSocket
     154            throw new UnsupportedOperationException();
     155        }
     156
     157        protected InetAddress getInetAddress() {
     158            return delegate.getInetAddress();
     159        }
     160
     161        protected int getPort() {
     162            return delegate.getPort();
     163        }
     164
     165        protected boolean supportsUrgentData() {
     166            return false; // must be overridden in sub-class
     167        }
     168
     169        protected void sendUrgentData (int data) throws IOException {
     170            delegate.sendUrgentData(data);
     171        }
     172
     173        protected int getLocalPort() {
     174            return delegate.getLocalPort();
     175        }
     176
     177        public Object getOption(int optID) throws SocketException {
     178            switch (optID) {
     179                case SocketOptions.IP_TOS:
     180                    return new Integer(delegate.getTrafficClass());
     181                case SocketOptions.SO_BINDADDR:
     182                    return delegate.getLocalAddress();
     183                case SocketOptions.SO_KEEPALIVE:
     184                    return Boolean.valueOf(delegate.getKeepAlive());
     185                case SocketOptions.SO_LINGER:
     186                    return new Integer(delegate.getSoLinger());
     187                case SocketOptions.SO_OOBINLINE:
     188                    return Boolean.valueOf(delegate.getOOBInline());
     189                case SocketOptions.SO_RCVBUF:
     190                    return new Integer(delegate.getReceiveBufferSize());
     191                case SocketOptions.SO_REUSEADDR:
     192                    return Boolean.valueOf(delegate.getReuseAddress());
     193                case SocketOptions.SO_SNDBUF:
     194                    return new Integer(delegate.getSendBufferSize());
     195                case SocketOptions.SO_TIMEOUT:
     196                    return new Integer(delegate.getSoTimeout());
     197                case SocketOptions.TCP_NODELAY:
     198                    return Boolean.valueOf(delegate.getTcpNoDelay());
     199                case SocketOptions.SO_BROADCAST:
     200                default:
     201                    throw new IllegalArgumentException("Unsupported option type");
     202            }
     203        }
     204
     205        public void setOption(int optID, Object value) throws SocketException {
     206            switch (optID) {
     207                case SocketOptions.SO_BINDADDR:
     208                    throw new IllegalArgumentException("Socket is bound");
     209                case SocketOptions.SO_KEEPALIVE:
     210                    delegate.setKeepAlive(((Boolean)value).booleanValue());
     211                    break;
     212                case SocketOptions.SO_LINGER:
     213                    if (value instanceof Boolean) {
     214                        delegate.setSoLinger(((Boolean)value).booleanValue(), 0);
     215                    }
     216                    else {
     217                        delegate.setSoLinger(true, ((Integer)value).intValue());
     218                    }
     219                    break;
     220                case SocketOptions.SO_OOBINLINE:
     221                    delegate.setOOBInline(((Boolean)value).booleanValue());
     222                    break;
     223                case SocketOptions.SO_RCVBUF:
     224                    delegate.setReceiveBufferSize(((Integer)value).intValue());
     225                    break;
     226                case SocketOptions.SO_REUSEADDR:
     227                    delegate.setReuseAddress(((Boolean)value).booleanValue());
     228                    break;
     229                case SocketOptions.SO_SNDBUF:
     230                    delegate.setSendBufferSize(((Integer)value).intValue());
     231                    break;
     232                case SocketOptions.SO_TIMEOUT:
     233                    delegate.setSoTimeout(((Integer)value).intValue());
     234                    break;
     235                case SocketOptions.TCP_NODELAY:
     236                    delegate.setTcpNoDelay(((Boolean)value).booleanValue());
     237                    break;
     238                case SocketOptions.SO_BROADCAST:
     239                default:
     240                    throw new IllegalArgumentException("Unsupported option type");
     241            }
     242        }
     243    }
     244
     245    public void close() throws IOException {
     246        System.out.println("Calling SocketWrapper.delegate.close");
     247        delegate.close();
     248    }
     249
     250    public boolean equals(Object obj) {
     251        if (!(obj instanceof SocketWrapper)) return false;
     252        SocketWrapper that = (SocketWrapper)obj;
     253        return this.delegate.equals(that.delegate);
     254    }
     255
     256    public int hashCode() {
     257        return delegate.hashCode() ^ 0x01010101;
     258    }
     259    public String toString() {
     260        return "<SocketWrapper " + super.toString() + "(delegating to " + delegate.toString() +  ")" + ">";
     261    }
     262}
     263 No newline at end of file
  • new file invirt-vnc-client/VNCProxyConnectSocket.java

    - +  
     1//
     2//  Copyright (C) 2002 Constantin Kaplinsky, Inc.  All Rights Reserved.
     3//  Copyright 2007 MIT Student Information Processing Board
     4//
     5//  This is free software; you can redistribute it and/or modify
     6//  it under the terms of the GNU General Public License as published by
     7//  the Free Software Foundation; either version 2 of the License, or
     8//  (at your option) any later version.
     9//
     10//  This software is distributed in the hope that it will be useful,
     11//  but WITHOUT ANY WARRANTY; without even the implied warranty of
     12//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13//  GNU General Public License for more details.
     14//
     15//  You should have received a copy of the GNU General Public License
     16//  along with this software; if not, write to the Free Software
     17//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
     18//  USA.
     19//
     20
     21//
     22// VNCProxySocket.java together with VNCProxySocketFactory.java
     23// implement an alternate way to connect to VNC servers via one or two
     24// VNCProxy proxies supporting the VNCProxy VNCCONNECT method.
     25//
     26
     27import java.net.*;
     28import java.io.*;
     29
     30class VNCProxyConnectSocket extends Socket {
     31
     32  public VNCProxyConnectSocket(String host, int port,
     33                               String vmname, String authtoken)
     34    throws IOException {
     35
     36    // Connect to the specified HTTP proxy
     37    super(host, port);
     38
     39    // Send the CONNECT request
     40    getOutputStream().write(("CONNECTVNC " + vmname +
     41                             " VNCProxy/1.0\r\nAuth-token: " + authtoken +
     42                             "\r\n\r\n").getBytes());
     43
     44    // Read the first line of the response
     45    DataInputStream is = new DataInputStream(getInputStream());
     46    String str = is.readLine();
     47
     48    // Check the HTTP error code -- it should be "200" on success
     49    if (!str.startsWith("VNCProxy/1.0 200 ")) {
     50      if (str.startsWith("VNCProxy/1.0 "))
     51        str = str.substring(13);
     52      throw new IOException("Proxy reports \"" + str + "\"");
     53    }
     54
     55    // Success -- skip remaining HTTP headers
     56    do {
     57      str = is.readLine();
     58    } while (str.length() != 0);
     59  }
     60}
     61
  • new file invirt-vnc-client/VNCProxyConnectSocketFactory.java

    - +  
     1//
     2//  Copyright (C) 2002 Constantin Kaplinsky, Inc.  All Rights Reserved.
     3//  Copyright 2007 MIT Student Information Processing Board
     4//
     5//  This is free software; you can redistribute it and/or modify
     6//  it under the terms of the GNU General Public License as published by
     7//  the Free Software Foundation; either version 2 of the License, or
     8//  (at your option) any later version.
     9//
     10//  This software is distributed in the hope that it will be useful,
     11//  but WITHOUT ANY WARRANTY; without even the implied warranty of
     12//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13//  GNU General Public License for more details.
     14//
     15//  You should have received a copy of the GNU General Public License
     16//  along with this software; if not, write to the Free Software
     17//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
     18//  USA.
     19//
     20
     21//
     22// VNCProxyConnectSocketFactory.java together with VNCProxyConnectSocket.java
     23// implement an alternate way to connect to VNC servers via one or two
     24// VNCProxy proxies supporting the VNCProxy CONNECT method.
     25//
     26
     27import java.applet.*;
     28import java.net.*;
     29import javax.net.ssl.*;
     30import java.io.*;
     31
     32class VNCProxyConnectSocketFactory implements SocketFactory {
     33
     34    SSLSocketFactory factory;
     35   
     36    public VNCProxyConnectSocketFactory() {
     37        try {
     38            SSLContext c = SSLContext.getInstance("SSL");
     39            c.init(null,
     40                   new TrustManager[] { new InvirtTrustManager() },
     41                   null);
     42            factory =
     43                (SSLSocketFactory)c.getSocketFactory();
     44        } catch (Exception e) {
     45            e.printStackTrace();
     46        }
     47    }
     48
     49  public Socket createSocket(String host, int port, Applet applet)
     50    throws IOException {
     51
     52    return createSocket(host, port,
     53                        applet.getParameter("VMNAME"),
     54                        applet.getParameter("AUTHTOKEN"));
     55  }
     56
     57  public Socket createSocket(String host, int port, String[] args)
     58    throws IOException {
     59
     60    return createSocket(host, port,
     61                        readArg(args, "VMNAME"),
     62                        readArg(args, "AUTHTOKEN"));
     63  }
     64
     65  public Socket createSocket(String host, int port,
     66                             String vmname, String authtoken)
     67    throws IOException {
     68
     69    if (vmname == null || authtoken == null) {
     70      System.out.println("Incomplete parameter list for VNCProxyConnectSocket");
     71      return new Socket(host, port);
     72    }
     73
     74    System.out.println("VNCProxy CONNECT via proxy " + host +
     75                       " port " + port + " to vm " + vmname);
     76    SSLSocket ssls = (SSLSocket)factory.createSocket(host, port);
     77    ssls.startHandshake();
     78    VNCProxyConnectSocketWrapper s =
     79      new VNCProxyConnectSocketWrapper(ssls, vmname, authtoken);
     80
     81    return (Socket)s;
     82  }
     83
     84  private String readArg(String[] args, String name) {
     85
     86    for (int i = 0; i < args.length; i += 2) {
     87      if (args[i].equalsIgnoreCase(name)) {
     88        try {
     89          return args[i+1];
     90        } catch (Exception e) {
     91          return null;
     92        }
     93      }
     94    }
     95    return null;
     96  }
     97}
     98
  • new file invirt-vnc-client/VNCProxyConnectSocketWrapper.java

    - +  
     1//
     2//  Copyright (C) 2002 Constantin Kaplinsky, Inc.  All Rights Reserved.
     3//  Copyright 2007 MIT Student Information Processing Board
     4//
     5//  This is free software; you can redistribute it and/or modify
     6//  it under the terms of the GNU General Public License as published by
     7//  the Free Software Foundation; either version 2 of the License, or
     8//  (at your option) any later version.
     9//
     10//  This software is distributed in the hope that it will be useful,
     11//  but WITHOUT ANY WARRANTY; without even the implied warranty of
     12//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13//  GNU General Public License for more details.
     14//
     15//  You should have received a copy of the GNU General Public License
     16//  along with this software; if not, write to the Free Software
     17//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
     18//  USA.
     19//
     20
     21//
     22// VNCProxySocket.java together with VNCProxySocketFactory.java
     23// implement an alternate way to connect to VNC servers via one or two
     24// VNCProxy proxies supporting the VNCProxy VNCCONNECT method.
     25//
     26
     27import java.net.*;
     28import java.io.*;
     29
     30class VNCProxyConnectSocketWrapper extends SocketWrapper {
     31
     32  public VNCProxyConnectSocketWrapper(Socket sock,
     33                               String vmname, String authtoken)
     34    throws IOException {
     35
     36    super(sock);
     37
     38    // Send the CONNECT request
     39    getOutputStream().write(("CONNECTVNC " + vmname +
     40                             " VNCProxy/1.0\r\nAuth-token: " + authtoken +
     41                             "\r\n\r\n").getBytes());
     42
     43    // Read the first line of the response
     44    DataInputStream is = new DataInputStream(getInputStream());
     45    String str = is.readLine();
     46
     47    // Check the HTTP error code -- it should be "200" on success
     48    if (!str.startsWith("VNCProxy/1.0 200 ")) {
     49      if (str.startsWith("VNCProxy/1.0 "))
     50        str = str.substring(13);
     51      throw new IOException("Proxy reports \"" + str + "\"");
     52    }
     53
     54    // Success -- skip remaining HTTP headers
     55    do {
     56      str = is.readLine();
     57    } while (str.length() != 0);
     58  }
     59}
     60
Note: See TracBrowser for help on using the repository browser.