source: other-projects/trunk/gs3-release-maker/tasks/sshtaskdef/src/mindbright/application/MindVNC.java@ 14627

Last change on this file since 14627 was 14627, checked in by oranfry, 17 years ago

initial import of the gs3-release-maker

File size: 10.9 KB
Line 
1//
2// Copyright (C) 1997, 1998 Olivetti & Oracle Research Laboratory
3//
4// This is free software; you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation; either version 2 of the License, or
7// (at your option) any later version.
8//
9// This software is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this software; if not, write to the Free Software
16// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
17// USA.
18//
19
20//
21// MindVNC.java - the VNC viewer class. This class mainly just sets up the
22// user interface, leaving it to the vncCanvas to do the actual rendering of
23// a VNC desktop.
24//
25package mindbright.application;
26
27import java.awt.*;
28import java.awt.event.*;
29import java.io.*;
30
31import mindbright.ssh.*;
32import mindbright.vnc.*;
33
34public class MindVNC extends java.applet.Applet
35 implements java.lang.Runnable
36{
37 boolean inAnApplet = true;
38 boolean separateFrame;
39
40 Container cont;
41
42 //
43 // main() is called when run as a java program from the command line. It
44 // simply creates a frame and runs the applet inside it.
45 //
46
47 public static void main(String[] argv) {
48 MindVNC v = new MindVNC();
49 v.mainArgs = argv;
50 v.inAnApplet = false;
51
52 v.f = new Frame("MindVNC v0.1");
53 v.f.add("Center", v);
54
55 v.init();
56 v.start();
57 }
58
59 Frame f;
60 String[] mainArgs;
61
62 String sshHost;
63 int sshPort;
64 String vncHost;
65 int vncPort;
66 String sshUser;
67 String sshPasswd;
68
69 ScrollPane sp;
70 vncCanvas vc;
71 public rfbProto rfb;
72 Thread rfbThread;
73 GridBagLayout gridbag;
74 Panel buttonPanel;
75 Button disconnectButton;
76 Button optionsButton;
77 Button clipboardButton;
78 Button ctrlAltDelButton;
79 authenticationPanel authenticator;
80
81 public optionsFrame options;
82 public clipboardFrame clipboard;
83
84 //
85 // init()
86 //
87
88 public void init() {
89
90 readParameters();
91
92 if(inAnApplet && separateFrame)
93 cont = f = new Frame("MindVNC v0.1");
94 else
95 cont = this;
96
97 if(f != null) {
98 f.addWindowListener(new WindowAdapter() {
99 public void windowClosing(WindowEvent e) { f.dispose(); rfbThread.stop();
100 if(!inAnApplet) System.exit(1); }
101 });
102 }
103
104
105 options = new optionsFrame(this);
106 clipboard = new clipboardFrame(this);
107 authenticator = new authenticationPanel();
108
109 rfbThread = new Thread(this);
110 rfbThread.start();
111 }
112
113 public void update(Graphics g) {
114 }
115
116 //
117 // run() - executed by the rfbThread to deal with the RFB socket.
118 //
119
120 public void run() {
121
122 gridbag = new GridBagLayout();
123 cont.setLayout(gridbag);
124
125 buttonPanel = new Panel();
126 buttonPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
127 disconnectButton = new Button("Disconnect");
128 buttonPanel.add(disconnectButton);
129 optionsButton = new Button("Options");
130 buttonPanel.add(optionsButton);
131 clipboardButton = new Button("Clipboard");
132 buttonPanel.add(clipboardButton);
133 ctrlAltDelButton = new Button("Send Ctrl-Alt-Del");
134 buttonPanel.add(ctrlAltDelButton);
135
136 GridBagConstraints gbc = new GridBagConstraints();
137 gbc.gridwidth = GridBagConstraints.REMAINDER;
138 gbc.anchor = GridBagConstraints.NORTHWEST;
139 gridbag.setConstraints(buttonPanel,gbc);
140 cont.add(buttonPanel);
141
142 disconnectButton.addActionListener(new ActionListener() {
143 public void actionPerformed(ActionEvent e) {
144 buttonPressed(0);
145 }
146 });
147 optionsButton.addActionListener(new ActionListener() {
148 public void actionPerformed(ActionEvent e) {
149 buttonPressed(1);
150 }
151 });
152 clipboardButton.addActionListener(new ActionListener() {
153 public void actionPerformed(ActionEvent e) {
154 buttonPressed(2);
155 }
156 });
157 ctrlAltDelButton.addActionListener(new ActionListener() {
158 public void actionPerformed(ActionEvent e) {
159 buttonPressed(3);
160 }
161 });
162
163
164 while(true) {
165
166 disconnectButton.disable();
167 clipboardButton.disable();
168 ctrlAltDelButton.disable();
169
170 try {
171 connectAndAuthenticate();
172
173 rfb.doProtocolInitialisation(options.encodings, options.nEncodings);
174
175 vc = new vncCanvas(this);
176
177 sp = new ScrollPane(ScrollPane.SCROLLBARS_AS_NEEDED);
178 gbc.weightx = 1.0;
179 gbc.weighty = 1.0;
180 gbc.fill = GridBagConstraints.BOTH;
181 gridbag.setConstraints(sp,gbc);
182 cont.add(sp);
183
184 if(f != null) {
185 int sbw = sp.getVScrollbarWidth();
186 int sbh = sp.getHScrollbarHeight();
187 Dimension max = Toolkit.getDefaultToolkit().getScreenSize();
188 Insets fIns = f.getInsets();
189 max.width -= (fIns.left + fIns.right + sbw);
190 max.height -= (fIns.top + fIns.bottom + sbh);
191 int w = max.width > rfb.framebufferWidth + 4 ? rfb.framebufferWidth + 4 : max.width;
192 int h = max.height > rfb.framebufferHeight + 4 ? rfb.framebufferHeight + 4 : max.height;
193 sp.setSize(new Dimension(w, h));
194 } else {
195 sp.setSize(getSize());
196 }
197 sp.add(vc);
198
199 if(f != null) {
200 f.setTitle(rfb.desktopName);
201 f.pack();
202 } else {
203 validate();
204 }
205
206 disconnectButton.enable();
207 clipboardButton.enable();
208 ctrlAltDelButton.enable();
209
210 vc.processNormalProtocol();
211 cont.remove(sp);
212
213 } catch (Exception e) {
214 e.printStackTrace();
215 fatalError(e.toString());
216 }
217 }
218 }
219
220
221 //
222 // Connect to the RFB server and authenticate the user.
223 //
224
225 void connectAndAuthenticate() throws IOException {
226
227 GridBagConstraints gbc = new GridBagConstraints();
228 gbc.gridwidth = GridBagConstraints.REMAINDER;
229 gbc.anchor = GridBagConstraints.NORTHWEST;
230 gbc.weightx = 1.0;
231 gbc.weighty = 1.0;
232 gbc.ipadx = 100;
233 gbc.ipady = 50;
234 gridbag.setConstraints(authenticator,gbc);
235 cont.add(authenticator);
236
237 validate();
238 if(f != null) {
239 f.pack();
240 f.show();
241 }
242
243 boolean authenticationDone = false;
244
245 while (!authenticationDone) {
246
247 synchronized(authenticator) {
248 try {
249 authenticator.wait();
250 } catch (InterruptedException e) {
251 }
252 }
253
254 sshUser = authenticator.sshUser.getText();
255 sshPasswd = authenticator.sshPassword.getText();
256 vncHost = authenticator.vncHost.getText();
257 vncPort = 5900;
258
259 int ix;
260 if((ix = vncHost.indexOf(':')) != -1) {
261 try {
262 vncPort += Integer.parseInt(vncHost.substring(ix + 1));
263 } catch (NumberFormatException e) {
264 authenticator.retry("VNC host-string format error");
265 continue;
266 }
267 vncHost = vncHost.substring(0, ix);
268 }
269
270 try {
271 rfb = new rfbProto(sshHost, sshPort, sshUser, sshPasswd, vncHost, vncPort, this);
272 } catch (java.net.ConnectException e) {
273 System.out.println("Connect...");
274 authenticator.retry("VNC host, connection refused");
275 continue;
276 } catch (java.io.IOException e) {
277 System.out.println("IO...");
278 authenticator.retry("SSH error: " + e.getMessage());
279 continue;
280 }
281
282 if(rfb.connectAndAuthenticate(authenticator))
283 break;
284 }
285
286 cont.remove(authenticator);
287 }
288
289 int getInt(byte[] b, int o) {
290 int i = ( ( b[o + 0] & 0xff ) << 24 ) |
291 ( ( b[o + 1] & 0xff ) << 16 ) |
292 ( ( b[o + 2] & 0xff ) << 8 ) |
293 ( b[o + 3] & 0xff );
294 return i;
295 }
296
297 void putInt(byte[] b, int o, int i) {
298 b[o + 0] = (byte) ( i >>> 24 );
299 b[o + 1] = (byte) ( i >>> 16 );
300 b[o + 2] = (byte) ( i >>> 8 );
301 b[o + 3] = (byte) i;
302 }
303
304 //
305 // setCutText() - send the given cut text to the RFB server.
306 //
307
308 public void setCutText(String text) {
309 try {
310 if ((rfb != null) && rfb.inNormalProtocol) {
311 rfb.writeClientCutText(text);
312 }
313 } catch (Exception e) {
314 e.printStackTrace();
315 }
316 }
317
318
319 //
320 // Respond to button presses
321 //
322
323 public void buttonPressed(int buttonNum) {
324 switch(buttonNum) {
325 case 0:
326 rfb.close();
327 rfb = null;
328 break;
329 case 1:
330 if (options.isVisible()) {
331 options.hide();
332 } else {
333 options.show();
334 }
335 break;
336 case 2:
337 if (clipboard.isVisible()) {
338 clipboard.hide();
339 } else {
340 clipboard.show();
341 }
342 break;
343 case 3:
344 rfb.sendCtrlAltDel();
345 }
346 }
347
348
349 //
350 // Detect when the focus goes in and out of the applet. See
351 // vncCanvas.handleEvent() for details of why this is necessary.
352 //
353
354 public boolean gotFocus = false;
355
356 public boolean gotFocus(Event evt, Object what) {
357 gotFocus = true;
358 return true;
359 }
360 public boolean lostFocus(Event evt, Object what) {
361 gotFocus = false;
362 return true;
363 }
364
365
366 //
367 // encryptBytes() - encrypt some bytes in memory using a password. Note that
368 // the mapping from password to key must be the same as that used on the rfb
369 // server side.
370 //
371 // Note also that IDEA encrypts data in 8-byte blocks, so here we will ignore
372 // any data beyond the last 8-byte boundary leaving it to the calling
373 // function to pad the data appropriately.
374 //
375
376 void encryptBytes(byte[] bytes, String passwd) {
377 byte[] key = new byte[8];
378 passwd.getBytes(0, passwd.length(), key, 0);
379
380 for (int i = passwd.length(); i < 8; i++) {
381 key[i] = (byte)0;
382 }
383
384 DesCipher des = new DesCipher(key);
385
386 des.encrypt(bytes,0,bytes,0);
387 des.encrypt(bytes,8,bytes,8);
388 }
389
390
391 //
392 // readParameters() - read parameters from the html source or from the
393 // command line. On the command line, the arguments are just a sequence of
394 // param_name/param_value pairs where the names and values correspond to
395 // those expected in the html applet tag source.
396 //
397
398 public void readParameters() {
399 sshHost = readParameter("sshhost", !inAnApplet);
400 if (sshHost == null) {
401 sshHost = getCodeBase().getHost();
402 if (sshHost.equals("")) {
403 fatalError("Not able to determine sshhost");
404 }
405 }
406
407 String s = readParameter("sshport", false);
408 if(s != null)
409 sshPort = Integer.parseInt(s);
410 else
411 sshPort = SSH.DEFAULTPORT;
412
413 try {
414 separateFrame = (new Boolean(getParameter("sepframe"))).booleanValue();
415 } catch (Exception e) {
416 separateFrame = true;
417 }
418
419 }
420
421 public String readParameter(String name, boolean required) {
422 if (inAnApplet) {
423 String s = getParameter(name);
424 if ((s == null) && required) {
425 fatalError(name + " parameter not specified");
426 }
427 return s;
428 }
429
430 for (int i = 0; i < mainArgs.length; i += 2) {
431 if (mainArgs[i].equalsIgnoreCase(name)) {
432 try {
433 return mainArgs[i+1];
434 } catch (Exception e) {
435 if (required) {
436 fatalError(name + " parameter not specified");
437 }
438 return null;
439 }
440 }
441 }
442 if (required) {
443 fatalError(name + " parameter not specified");
444 }
445 return null;
446 }
447
448 //
449 // fatalError() - print out a fatal error message.
450 //
451
452 public void fatalError(String s) {
453 System.out.println(s);
454
455 if (inAnApplet) {
456 cont.removeAll();
457 Label l = new Label(s);
458
459 setLayout(new FlowLayout(FlowLayout.LEFT, 30, 30));
460 cont.add(l);
461 validate();
462 Thread.currentThread().stop();
463 } else {
464 System.exit(1);
465 }
466 }
467}
Note: See TracBrowser for help on using the repository browser.