]>
Commit | Line | Data |
---|---|---|
e6d0212c DM |
1 | |
2 | Unfortunately the java certificate store does not correctly access | |
3 | the browser certificate store (firefox, chrome). We also tunnel VNC | |
4 | traffic from other cluster nodes. | |
5 | ||
6 | So we implement our own trust manager, and allow to pass the server | |
7 | certificate (or CA who signed the server certificate) as applet | |
8 | parameter "PVECert" (newline encoded as '|'). | |
9 | ||
75f214c0 | 10 | Index: tigervnc/java/src/com/tigervnc/vncviewer/X509Tunnel.java |
e6d0212c | 11 | =================================================================== |
75f214c0 DM |
12 | --- tigervnc.orig/java/src/com/tigervnc/vncviewer/X509Tunnel.java 2013-06-03 08:17:17.000000000 +0200 |
13 | +++ tigervnc/java/src/com/tigervnc/vncviewer/X509Tunnel.java 2013-06-03 08:22:52.000000000 +0200 | |
e6d0212c DM |
14 | @@ -26,13 +26,23 @@ |
15 | import javax.net.ssl.*; | |
16 | import java.security.*; | |
17 | import java.security.cert.*; | |
18 | +import java.security.cert.Certificate; | |
19 | +import java.security.cert.CertificateFactory; | |
20 | +import java.io.*; | |
21 | ||
22 | public class X509Tunnel extends TLSTunnelBase | |
23 | { | |
24 | ||
25 | - public X509Tunnel (Socket sock_) | |
26 | + Certificate pvecert; | |
27 | + | |
28 | + public X509Tunnel (Socket sock_, String certstr) throws CertificateException | |
29 | { | |
30 | super (sock_); | |
31 | + | |
32 | + if (certstr != null) { | |
33 | + CertificateFactory cf = CertificateFactory.getInstance("X.509"); | |
34 | + pvecert = cf.generateCertificate(new StringBufferInputStream(certstr)); | |
35 | + } | |
36 | } | |
37 | ||
38 | protected void setParam (SSLSocket sock) | |
75f214c0 | 39 | @@ -52,9 +62,48 @@ |
e6d0212c DM |
40 | protected void initContext (SSLContext sc) throws java.security. |
41 | GeneralSecurityException | |
42 | { | |
43 | - TrustManager[] myTM = new TrustManager[] | |
44 | - { | |
45 | - new MyX509TrustManager ()}; | |
46 | + TrustManager[] myTM; | |
47 | + | |
48 | + if (pvecert != null) { | |
49 | + myTM = new TrustManager[] { | |
50 | + new X509TrustManager() { | |
51 | + public java.security.cert.X509Certificate[] | |
52 | + getAcceptedIssuers() { | |
53 | + return null; | |
54 | + } | |
55 | + public void checkClientTrusted( | |
56 | + java.security.cert.X509Certificate[] certs, | |
57 | + String authType) throws CertificateException { | |
58 | + throw new CertificateException("no clients"); | |
59 | + } | |
60 | + public void checkServerTrusted( | |
61 | + java.security.cert.X509Certificate[] certs, | |
62 | + String authType) throws CertificateException { | |
63 | + | |
64 | + if (certs == null || certs.length < 1) { | |
65 | + throw new CertificateException("no certs"); | |
66 | + } | |
e6d0212c DM |
67 | + PublicKey cakey = pvecert.getPublicKey(); |
68 | + | |
69 | + boolean ca_match; | |
70 | + try { | |
71 | + certs[0].verify(cakey); | |
72 | + ca_match = true; | |
73 | + } catch (Exception e) { | |
74 | + ca_match = false; | |
75 | + } | |
76 | + | |
77 | + if (!ca_match && !pvecert.equals(certs[0])) { | |
78 | + throw new CertificateException("certificate does not match"); | |
79 | + } | |
80 | + } | |
81 | + } | |
82 | + }; | |
83 | + } else { | |
84 | + myTM = new TrustManager[] { | |
85 | + new MyX509TrustManager () | |
86 | + }; | |
87 | + } | |
88 | sc.init (null, myTM, null); | |
89 | } | |
90 | ||
75f214c0 | 91 | @@ -100,4 +149,5 @@ |
e6d0212c DM |
92 | return tm.getAcceptedIssuers (); |
93 | } | |
94 | } | |
95 | + | |
96 | } | |
75f214c0 | 97 | Index: tigervnc/java/src/com/tigervnc/vncviewer/RfbProto.java |
e6d0212c | 98 | =================================================================== |
75f214c0 DM |
99 | --- tigervnc.orig/java/src/com/tigervnc/vncviewer/RfbProto.java 2013-06-03 08:17:17.000000000 +0200 |
100 | +++ tigervnc/java/src/com/tigervnc/vncviewer/RfbProto.java 2013-06-03 08:19:05.000000000 +0200 | |
e6d0212c DM |
101 | @@ -411,7 +411,8 @@ |
102 | } | |
103 | ||
104 | void authenticateX509() throws Exception { | |
105 | - X509Tunnel tunnel = new X509Tunnel(sock); | |
106 | + | |
107 | + X509Tunnel tunnel = new X509Tunnel(sock, viewer.PVECert); | |
108 | tunnel.setup (this); | |
109 | } | |
110 | ||
75f214c0 | 111 | Index: tigervnc/java/src/com/tigervnc/vncviewer/VncViewer.java |
e6d0212c | 112 | =================================================================== |
75f214c0 DM |
113 | --- tigervnc.orig/java/src/com/tigervnc/vncviewer/VncViewer.java 2013-06-03 08:19:03.000000000 +0200 |
114 | +++ tigervnc/java/src/com/tigervnc/vncviewer/VncViewer.java 2013-06-03 08:19:05.000000000 +0200 | |
6b53b0de | 115 | @@ -91,6 +91,8 @@ |
e6d0212c DM |
116 | int debugStatsExcludeUpdates; |
117 | int debugStatsMeasureUpdates; | |
118 | ||
119 | + String PVECert; | |
120 | + | |
6b53b0de DM |
121 | // Reference to this applet for inter-applet communication. |
122 | public static java.applet.Applet refApplet; | |
e6d0212c | 123 | |
6b53b0de | 124 | @@ -263,7 +265,7 @@ |
e6d0212c DM |
125 | fatalError(e.toString(), e); |
126 | } | |
127 | } | |
128 | - | |
129 | + | |
130 | } | |
131 | ||
132 | // | |
6b53b0de | 133 | @@ -299,7 +301,7 @@ |
e6d0212c DM |
134 | // If the rfbThread is being stopped, ignore any exceptions, |
135 | // otherwise rethrow the exception so it can be handled. | |
136 | // | |
137 | - | |
138 | + | |
139 | void processNormalProtocol() throws Exception { | |
140 | try { | |
141 | vc.processNormalProtocol(); | |
6b53b0de | 142 | @@ -842,6 +844,11 @@ |
e6d0212c DM |
143 | |
144 | // SocketFactory. | |
145 | socketFactory = readParameter("SocketFactory", false); | |
146 | + | |
147 | + String tmpcert = readParameter("PVECert", false); | |
148 | + if (tmpcert != null) { | |
149 | + PVECert = tmpcert.replace('|', '\n'); | |
150 | + } | |
151 | } | |
152 | ||
153 | // | |
6b53b0de | 154 | @@ -991,7 +998,7 @@ |
e6d0212c DM |
155 | } |
156 | ||
157 | synchronized public void fatalError(String str, Exception e) { | |
158 | - | |
159 | + | |
160 | if (rfb != null && rfb.closed()) { | |
161 | // Not necessary to show error message if the error was caused | |
162 | // by I/O problems after the rfb.close() method call. | |
6b53b0de | 163 | @@ -1084,11 +1091,11 @@ |
e6d0212c DM |
164 | public void enableInput(boolean enable) { |
165 | vc.enableInput(enable); | |
166 | } | |
167 | - | |
168 | + | |
169 | // | |
170 | // Resize framebuffer if autoScale is enabled. | |
171 | // | |
172 | - | |
173 | + | |
174 | public void componentResized(ComponentEvent e) { | |
175 | if (e.getComponent() == vncFrame) { | |
176 | if (options.autoScale) { | |
6b53b0de | 177 | @@ -1100,11 +1107,11 @@ |
e6d0212c DM |
178 | } |
179 | } | |
180 | } | |
181 | - | |
182 | + | |
183 | // | |
184 | // Ignore component events we're not interested in. | |
185 | // | |
186 | - | |
187 | + | |
188 | public void componentShown(ComponentEvent e) { } | |
189 | public void componentMoved(ComponentEvent e) { } | |
190 | public void componentHidden(ComponentEvent e) { } |