diff -Naur JavaViewer.orig/ButtonPanel.java JavaViewer/ButtonPanel.java
--- JavaViewer.orig/ButtonPanel.java 2004-12-12 20:51:02.000000000 -0500
+++ JavaViewer/ButtonPanel.java 2007-05-31 15:40:45.000000000 -0400
@@ -43,30 +43,36 @@
viewer = v;
setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
- disconnectButton = new Button("Disconnect");
+ if (v.ftpOnly) {
+ disconnectButton = new Button("Quit");
+ } else {
+ disconnectButton = new Button("Close");
+ }
disconnectButton.setEnabled(false);
add(disconnectButton);
disconnectButton.addActionListener(this);
- optionsButton = new Button("Options");
- add(optionsButton);
- optionsButton.addActionListener(this);
- clipboardButton = new Button("Clipboard");
- clipboardButton.setEnabled(false);
- add(clipboardButton);
- clipboardButton.addActionListener(this);
- if (viewer.rec != null) {
- recordButton = new Button("Record");
- add(recordButton);
- recordButton.addActionListener(this);
- }
- ctrlAltDelButton = new Button("Send Ctrl-Alt-Del");
- ctrlAltDelButton.setEnabled(false);
- add(ctrlAltDelButton);
- ctrlAltDelButton.addActionListener(this);
- refreshButton = new Button("Refresh");
- refreshButton.setEnabled(false);
- add(refreshButton);
- refreshButton.addActionListener(this);
+ if (!v.ftpOnly) {
+ optionsButton = new Button("Options");
+ add(optionsButton);
+ optionsButton.addActionListener(this);
+ clipboardButton = new Button("Clipboard");
+ clipboardButton.setEnabled(false);
+ add(clipboardButton);
+ clipboardButton.addActionListener(this);
+ if (viewer.rec != null) {
+ recordButton = new Button("Record");
+ add(recordButton);
+ recordButton.addActionListener(this);
+ }
+ ctrlAltDelButton = new Button("Send Ctrl-Alt-Del");
+ ctrlAltDelButton.setEnabled(false);
+ add(ctrlAltDelButton);
+ ctrlAltDelButton.addActionListener(this);
+ refreshButton = new Button("Refresh");
+ refreshButton.setEnabled(false);
+ add(refreshButton);
+ refreshButton.addActionListener(this);
+ }
ftpButton = new Button("File Transfer");
ftpButton.setEnabled(false);
add(ftpButton);
@@ -79,9 +85,10 @@
public void enableButtons() {
disconnectButton.setEnabled(true);
+ ftpButton.setEnabled(true);
+ if (viewer.ftpOnly) {return;}
clipboardButton.setEnabled(true);
refreshButton.setEnabled(true);
- ftpButton.setEnabled(true);
}
//
@@ -89,6 +96,9 @@
//
public void disableButtonsOnDisconnect() {
+ ftpButton.setEnabled(false);
+ if (viewer.ftpOnly) {return;}
+
remove(disconnectButton);
disconnectButton = new Button("Hide desktop");
disconnectButton.setEnabled(true);
@@ -99,7 +109,6 @@
clipboardButton.setEnabled(false);
ctrlAltDelButton.setEnabled(false);
refreshButton.setEnabled(false);
- ftpButton.setEnabled(false);
validate();
}
@@ -110,6 +119,7 @@
//
public void enableRemoteAccessControls(boolean enable) {
+ if (viewer.ftpOnly) {return;}
ctrlAltDelButton.setEnabled(enable);
}
@@ -163,9 +173,19 @@
}
else if (evt.getSource() == ftpButton)
{
- viewer.ftp.setVisible(!viewer.ftp.isVisible());
+// begin runge/x11vnc
+ if (viewer.ftpOnly) {
+ viewer.vncFrame.setVisible(false);
+ }
+ viewer.ftp.setSavedLocations();
+ if (viewer.ftp.isVisible()) {
+ viewer.ftp.doClose();
+ } else {
+ viewer.ftp.doOpen();
+ }
+// end runge/x11vnc
viewer.rfb.readServerDriveList();
-
+
}
}
}
diff -Naur JavaViewer.orig/FTPFrame.java JavaViewer/FTPFrame.java
--- JavaViewer.orig/FTPFrame.java 2005-03-15 23:53:14.000000000 -0500
+++ JavaViewer/FTPFrame.java 2009-01-13 09:48:30.000000000 -0500
@@ -24,8 +24,17 @@
import java.io.*;
import java.util.ArrayList;
import java.util.Vector;
+import java.util.Date;
import javax.swing.*;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.*;
+
+// begin runge/x11vnc
+import java.util.Arrays;
+// end runge/x11vnc
+
/*
* Created on Feb 25, 2004
@@ -74,12 +83,31 @@
public javax.swing.JTextField connectionStatus = null;
public boolean updateDriveList;
private Vector remoteList = null;
+ private Vector remoteListInfo = null;
private Vector localList = null;
+ private Vector localListInfo = null;
private File currentLocalDirectory = null; // Holds the current local Directory
private File currentRemoteDirectory = null; // Holds the current remote Directory
private File localSelection = null; // Holds the currently selected local file
private String remoteSelection = null; // Holds the currently selected remote file
public String selectedTable = null;
+
+// begin runge/x11vnc
+ private javax.swing.JButton viewButton = null;
+ private javax.swing.JButton refreshButton = null;
+ public File saveLocalDirectory = null;
+ public long saveLocalDirectoryTime = 0;
+ public int saveLocalDirectoryCount = 0;
+ public String saveRemoteDirectory = null;
+ public long saveRemoteDirectoryTime = 0;
+ public int saveRemoteDirectoryCount = 0;
+ private boolean localCurrentIsDir = true;
+ private int lastRemoteIndex = -1;
+ private int lastLocalIndex = -1;
+ private boolean doingShortcutDir = false;
+ private boolean gotShortcutDir = false;
+ private boolean ignore_events = false;
+// end runge/x11vnc
// sf@2004 - Separate directories and files for better lisibility
private ArrayList DirsList;
@@ -125,11 +153,61 @@
void refreshRemoteLocation()
{
+
+//System.out.println("refreshRemoteLocation1");
remoteList.clear();
+ remoteListInfo.clear();
remoteFileTable.setListData(remoteList);
+System.out.println("refreshRemoteLocation '" + remoteLocation.getText() + "'"); // runge/x11vnc
viewer.rfb.readServerDirectory(remoteLocation.getText());
}
+// begin runge/x11vnc
+ public void setSavedLocations() {
+ saveLocalDirectory = currentLocalDirectory;
+ saveLocalDirectoryTime = System.currentTimeMillis();
+ saveLocalDirectoryCount = 0;
+
+ if (remoteLocation != null) {
+ saveRemoteDirectory = remoteLocation.getText();
+System.out.println("RemoteSave '" + saveRemoteDirectory + "'");
+ }
+ saveRemoteDirectoryTime = System.currentTimeMillis();
+ saveRemoteDirectoryCount = 0;
+ }
+
+ private File saveLocalHack(File dir) {
+ saveLocalDirectoryCount++;
+//System.out.println("L " + saveLocalDirectoryCount + " dt: " + (System.currentTimeMillis() - saveLocalDirectoryTime) + " - " + saveLocalDirectory);
+ if (System.currentTimeMillis() > saveLocalDirectoryTime + 2000 || saveLocalDirectoryCount > 2) {
+ saveLocalDirectory = null;
+ }
+ if (saveLocalDirectory != null) {
+ currentLocalDirectory = saveLocalDirectory;
+ localLocation.setText(saveLocalDirectory.toString());
+ return saveLocalDirectory;
+ } else {
+ return dir;
+ }
+ }
+
+ private String saveRemoteHack(String indrive) {
+ saveRemoteDirectoryCount++;
+//System.out.println("R " + saveRemoteDirectoryCount + " - " + saveRemoteDirectory);
+ if (saveRemoteDirectory != null && saveRemoteDirectoryCount > 1) {
+ saveRemoteDirectory = null;
+ }
+ if (saveRemoteDirectory != null) {
+ if (! saveRemoteDirectory.equals("")) {
+System.out.println("saveRemoteHack setText + refreshRemoteLocation '" + saveRemoteDirectory + "'");
+ return saveRemoteDirectory;
+ }
+ }
+ return indrive;
+ }
+// end runge/x11vnc
+
+
/*
* Prints the list of drives on the remote directory and returns a String[].
* str takes as string like A:fC:lD:lE:lF:lG:cH:c
@@ -143,6 +221,9 @@
int size = str.length();
String driveType = null;
String[] drive = new String[str.length() / 3];
+ int idx = 0, C_drive = -1, O_drive = -1;
+
+System.out.println("ComboBox: Str '" + str + "'");
// Loop through the string to create a String[]
for (int i = 0; i < size; i = i + 3) {
@@ -150,26 +231,68 @@
driveType = str.substring(i + 2, i + 3);
if (driveType.compareTo("f") == 0)
drive[i / 3] += "\\ Floppy";
- if (driveType.compareTo("l") == 0)
+ if (driveType.compareTo("l") == 0) {
drive[i / 3] += "\\ Local Disk";
+ if (drive[i/3].substring(0,1).toUpperCase().equals("C")) {
+ C_drive = idx;
+ } else if (O_drive < 0) {
+ O_drive = idx;
+ }
+ }
if (driveType.compareTo("c") == 0)
drive[i / 3] += "\\ CD-ROM";
if (driveType.compareTo("n") == 0)
drive[i / 3] += "\\ Network";
remoteDrivesComboBox.addItem(drive[i / 3]);
+System.out.println("ComboBox: Add " + idx + " '" + drive[i/3] + "'");
+ idx++;
+ }
+
+ // runge
+ if (viewer.ftpDropDown != null) {
+ String[] dd = viewer.ftpDropDown.split("\\.");
+ for (int i=0; i < dd.length; i++) {
+ if (!dd[i].equals("")) {
+ String s = dd[i];
+ if (s.startsWith("TOP_")) {
+ s = s.substring(4);
+ remoteDrivesComboBox.insertItemAt(" [" + s + "]", 0);
+ } else {
+ remoteDrivesComboBox.addItem(" [" + s + "]");
+ }
+ }
+ }
+ } else {
+ remoteDrivesComboBox.addItem(" [My Documents]");
+ remoteDrivesComboBox.addItem(" [Desktop]");
+ remoteDrivesComboBox.addItem(" [Home]");
}
+
//sf@ - Select Drive C:as default if possible
boolean bFound = false;
- for(int i = 0; i < remoteDrivesComboBox.getItemCount() ; i++)
- {
- if(remoteDrivesComboBox.getItemAt(i).toString().substring(0,1).toUpperCase().equals("C"))
- {
- remoteDrivesComboBox.setSelectedIndex(i);
+
+ if (false) {
+ for(int i = 0; i < remoteDrivesComboBox.getItemCount() ; i++) {
+ if(remoteDrivesComboBox.getItemAt(i).toString().substring(0,1).toUpperCase().equals("C")) {
+ remoteDrivesComboBox.setSelectedIndex(i);
+ bFound = true;
+ }
+ }
+ } else {
+ if (C_drive >= 0) {
+ remoteDrivesComboBox.setSelectedIndex(C_drive);
+ bFound = true;
+System.out.println("ComboBox: C_drive index: " + C_drive);
+ } else if (O_drive >= 0) {
+ remoteDrivesComboBox.setSelectedIndex(O_drive);
bFound = true;
+System.out.println("ComboBox: Other_drive index: " + O_drive);
}
}
+
if (!bFound) remoteDrivesComboBox.setSelectedIndex(0);
+
updateDriveList = false;
return drive;
}
@@ -185,6 +308,8 @@
stopButton.setVisible(true);
stopButton.setEnabled(true);
receiveButton.setEnabled(false);
+ viewButton.setEnabled(false); // runge/x11vnc
+ refreshButton.setEnabled(false);
remoteTopButton.setEnabled(false);
sendButton.setEnabled(false);
remoteFileTable.setEnabled(false);
@@ -207,6 +332,8 @@
stopButton.setVisible(false);
stopButton.setEnabled(false);
receiveButton.setEnabled(true);
+ viewButton.setEnabled(true); // runge/x11vnc
+ refreshButton.setEnabled(true);
remoteTopButton.setEnabled(true);
sendButton.setEnabled(true);
remoteFileTable.setEnabled(true);
@@ -221,10 +348,11 @@
/*
* Print Directory prints out all the contents of a directory
*/
- void printDirectory(ArrayList a) {
+ void printDirectory(ArrayList a, ArrayList b) {
for (int i = 0; i < a.size(); i++) {
remoteList.addElement(a.get(i));
+ remoteListInfo.addElement(b.get(i));
}
remoteFileTable.setListData(remoteList);
}
@@ -235,10 +363,12 @@
* @return void
*/
private void initialize() {
+ ignore_events = true;
this.setSize(794, 500);
this.setContentPane(getJContentPane());
+ ignore_events = false;
updateDriveList = true;
- }
+ }
/**
* This method initializes jContentPane. This is the main content pane
*
@@ -253,6 +383,33 @@
jContentPane.add(getRemotePanel(), java.awt.BorderLayout.EAST);
jContentPane.add(getLocalPanel(), java.awt.BorderLayout.WEST);
jContentPane.add(getButtonPanel(), java.awt.BorderLayout.CENTER);
+
+ KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
+ AbstractAction escapeAction = new AbstractAction() {
+ public void actionPerformed(ActionEvent actionEvent) {
+ System.out.println("Escape Pressed");
+ if (viewer.ftpOnly) {
+ System.out.println("exiting...");
+ System.exit(0);
+ } else {
+ doClose();
+ }
+ }
+ };
+ jContentPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(stroke, "escapeAction");
+ jContentPane.getInputMap().put(stroke, "escapeAction");
+ jContentPane.getActionMap().put("escapeAction", escapeAction);
+
+ stroke = KeyStroke.getKeyStroke(KeyEvent.VK_R, InputEvent.CTRL_MASK);
+ AbstractAction resetAction = new AbstractAction() {
+ public void actionPerformed(ActionEvent actionEvent) {
+ System.out.println("Ctrl-R Pressed");
+ doReset();
+ }
+ };
+ jContentPane.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(stroke, "resetAction");
+ jContentPane.getInputMap().put(stroke, "resetAction");
+ jContentPane.getActionMap().put("resetAction", resetAction);
}
return jContentPane;
}
@@ -270,6 +427,7 @@
topPanelLocal.add(getLocalMachineLabel(), java.awt.BorderLayout.CENTER);
topPanelLocal.add(getLocalTopButton(), java.awt.BorderLayout.EAST);
topPanelLocal.setBackground(java.awt.Color.lightGray);
+//System.out.println("getTopPanelLocal");
}
return topPanelLocal;
}
@@ -288,6 +446,7 @@
topPanelRemote.add(getRemoteMachineLabel(), java.awt.BorderLayout.CENTER);
topPanelRemote.add(getRemoteTopButton(), java.awt.BorderLayout.EAST);
topPanelRemote.setBackground(java.awt.Color.lightGray);
+//System.out.println("getTopPanelRemote");
}
return topPanelRemote;
}
@@ -301,6 +460,7 @@
if (topPanelCenter == null) {
topPanelCenter = new javax.swing.JPanel();
topPanelCenter.add(getDummyButton(), null);
+//System.out.println("getTopPanelCenter");
}
return topPanelCenter;
}
@@ -328,6 +488,7 @@
topPanel.add(getRemoteTopButton(), null);
topPanel.setBackground(java.awt.Color.lightGray);
*/
+//System.out.println("getTopPanel");
}
return topPanel;
}
@@ -348,6 +509,7 @@
statusPanel.add(getJProgressBar(), null);
statusPanel.add(getConnectionStatus(), null);
statusPanel.setBackground(java.awt.Color.lightGray);
+//System.out.println("getStatusPanel");
}
return statusPanel;
@@ -368,6 +530,7 @@
remotePanel.add(getRemoteScrollPane(), null);
remotePanel.add(getRemoteStatus(), null);
remotePanel.setBackground(java.awt.Color.lightGray);
+//System.out.println("getRemotePanel");
}
return remotePanel;
}
@@ -390,6 +553,7 @@
localPanel.setComponentOrientation(
java.awt.ComponentOrientation.UNKNOWN);
localPanel.setName("localPanel");
+//System.out.println("getLocalPanel");
}
return localPanel;
}
@@ -405,12 +569,15 @@
buttonPanel = new javax.swing.JPanel();
buttonPanel.setLayout(null);
buttonPanel.add(getReceiveButton(), null);
+ buttonPanel.add(getRefreshButton(), null); // runge/x11vnc
+ buttonPanel.add(getViewButton(), null); // runge/x11vnc
buttonPanel.add(getNewFolderButton(), null);
buttonPanel.add(getCloseButton(), null);
buttonPanel.add(getDeleteButton(), null);
buttonPanel.add(getSendButton(), null);
buttonPanel.add(getStopButton(), null);
buttonPanel.setBackground(java.awt.Color.lightGray);
+//System.out.println("getButtonPanel");
}
return buttonPanel;
}
@@ -422,10 +589,11 @@
private javax.swing.JButton getSendButton() {
if (sendButton == null) {
sendButton = new javax.swing.JButton();
- sendButton.setBounds(20, 30, 97, 25);
+ sendButton.setBounds(15, 30, 107, 25); // runge/x11vnc
sendButton.setText("Send >>");
sendButton.setName("sendButton");
sendButton.addActionListener(this);
+//System.out.println("getSendButton");
}
return sendButton;
@@ -438,7 +606,7 @@
private javax.swing.JButton getReceiveButton() {
if (receiveButton == null) {
receiveButton = new javax.swing.JButton();
- receiveButton.setBounds(20, 60, 97, 25);
+ receiveButton.setBounds(15, 60, 107, 25); // runge/x11vnc
receiveButton.setText("<< Receive");
receiveButton.setName("receiveButton");
receiveButton.addActionListener(this);
@@ -453,7 +621,7 @@
private javax.swing.JButton getDeleteButton() {
if (deleteButton == null) {
deleteButton = new javax.swing.JButton();
- deleteButton.setBounds(20, 110, 97, 25);
+ deleteButton.setBounds(15, 110, 107, 25); // runge/x11vnc
deleteButton.setText("Delete File");
deleteButton.setName("deleteButton");
deleteButton.addActionListener(this);
@@ -468,7 +636,7 @@
private javax.swing.JButton getNewFolderButton() {
if (newFolderButton == null) {
newFolderButton = new javax.swing.JButton();
- newFolderButton.setBounds(20, 140, 97, 25);
+ newFolderButton.setBounds(15, 140, 107, 25); // runge/x11vnc
newFolderButton.setText("New Folder");
newFolderButton.setName("newFolderButton");
newFolderButton.addActionListener(this);
@@ -476,6 +644,39 @@
return newFolderButton;
}
+// begin runge/x11vnc
+ /**
+ * This method initializes refreshButton
+ *
+ * @return javax.swing.JButton
+ */
+ private javax.swing.JButton getRefreshButton() {
+ if (refreshButton == null) {
+ refreshButton = new javax.swing.JButton();
+ refreshButton.setBounds(15, 170, 107, 25);
+ refreshButton.setText("Refresh");
+ refreshButton.setName("refreshButton");
+ refreshButton.addActionListener(this);
+ }
+ return refreshButton;
+ }
+ /**
+ * This method initializes viewButton
+ *
+ * @return javax.swing.JButton
+ */
+ private javax.swing.JButton getViewButton() {
+ if (viewButton == null) {
+ viewButton = new javax.swing.JButton();
+ viewButton.setBounds(15, 200, 107, 25);
+ viewButton.setText("View File");
+ viewButton.setName("viewButton");
+ viewButton.addActionListener(this);
+ }
+ return viewButton;
+ }
+// end runge/x11vnc
+
/**
* This method initializes stopButton
*
@@ -486,7 +687,7 @@
if (stopButton == null)
{
stopButton = new javax.swing.JButton();
- stopButton.setBounds(20, 200, 97, 25);
+ stopButton.setBounds(15, 230, 107, 25); // runge/x11vnc
stopButton.setText("Stop");
stopButton.setName("stopButton");
stopButton.addActionListener(this);
@@ -503,8 +704,12 @@
private javax.swing.JButton getCloseButton() {
if (closeButton == null) {
closeButton = new javax.swing.JButton();
- closeButton.setBounds(20, 325, 97, 25);
- closeButton.setText("Close");
+ closeButton.setBounds(15, 325, 107, 25); // runge/x11vnc
+ if (viewer.ftpOnly) {
+ closeButton.setText("Quit");
+ } else {
+ closeButton.setText("Close");
+ }
closeButton.setName("closeButton");
closeButton.addActionListener(this);
}
@@ -551,6 +756,7 @@
//Select the second entry (e.g. C:\)
// localDrivesComboBox.setSelectedIndex(1);
localDrivesComboBox.addActionListener(this);
+//System.out.println("getLocalDrivesComboBox");
}
updateDriveList = false;
return localDrivesComboBox;
@@ -567,6 +773,7 @@
remoteDrivesComboBox.setFont(
new java.awt.Font("Dialog", java.awt.Font.PLAIN, 10));
remoteDrivesComboBox.addActionListener(this);
+//System.out.println("getRemoteDrivesComboBox");
}
return remoteDrivesComboBox;
@@ -587,6 +794,7 @@
localMachineLabel.setFont(
new java.awt.Font("Dialog", java.awt.Font.BOLD, 11));
localMachineLabel.setEditable(false);
+//System.out.println("getLocalMachineLabel");
}
return localMachineLabel;
}
@@ -622,6 +830,7 @@
localTopButton.setFont(
new java.awt.Font("Dialog", java.awt.Font.BOLD, 10));
localTopButton.addActionListener(this);
+//System.out.println("getLocalTopButton");
}
return localTopButton;
}
@@ -638,6 +847,7 @@
remoteTopButton.setFont(
new java.awt.Font("Dialog", java.awt.Font.BOLD, 10));
remoteTopButton.addActionListener(this);
+//System.out.println("getRemoteTopButton");
}
return remoteTopButton;
}
@@ -650,9 +860,24 @@
private javax.swing.JList getLocalFileTable() {
if (localFileTable == null) {
localList = new Vector(0);
+ localListInfo = new Vector(0);
localFileTable = new JList(localList);
+ MouseMotionListener mlisten = new MouseMotionAdapter() {
+ public void mouseMoved(MouseEvent e) {
+ int index = localFileTable.locationToIndex(e.getPoint());
+ if (index == lastLocalIndex) {
+ return;
+ } else if (index < 0) {
+ return;
+ }
+ lastLocalIndex = index;
+ connectionStatus.setText((String) localListInfo.get(index));
+ }
+ };
localFileTable.addMouseListener(this);
+ localFileTable.addMouseMotionListener(mlisten);
localFileTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+//System.out.println("getLocalFileTable");
}
return localFileTable;
}
@@ -669,6 +894,7 @@
localScrollPane.setFont(
new java.awt.Font("Dialog", java.awt.Font.PLAIN, 10));
localScrollPane.setName("localFileList");
+//System.out.println("getLocalScrollPane");
}
return localScrollPane;
}
@@ -680,10 +906,25 @@
private javax.swing.JList getRemoteFileTable() {
if (remoteFileTable == null) {
remoteList = new Vector(0);
+ remoteListInfo = new Vector(0);
remoteFileTable = new JList(remoteList);
+ MouseMotionListener mlisten = new MouseMotionAdapter() {
+ public void mouseMoved(MouseEvent e) {
+ int index = remoteFileTable.locationToIndex(e.getPoint());
+ if (index == lastRemoteIndex) {
+ return;
+ } else if (index < 0) {
+ return;
+ }
+ lastRemoteIndex = index;
+ connectionStatus.setText((String) remoteListInfo.get(index));
+ }
+ };
remoteFileTable.addMouseListener(this);
+ remoteFileTable.addMouseMotionListener(mlisten);
remoteFileTable.setSelectedValue("C:\\", false);
remoteFileTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+//System.out.println("getRemoteFileTable");
}
return remoteFileTable;
@@ -698,6 +939,7 @@
remoteScrollPane = new javax.swing.JScrollPane();
remoteScrollPane.setViewportView(getRemoteFileTable());
remoteScrollPane.setPreferredSize(new java.awt.Dimension(325, 418));
+//System.out.println("getRemoteScrollPane");
}
return remoteScrollPane;
}
@@ -716,6 +958,7 @@
remoteLocation.setBackground(new Color(255,255,238));
remoteLocation.setFont(
new java.awt.Font("Dialog", java.awt.Font.PLAIN, 10));
+//System.out.println("getRemoteLocation");
}
return remoteLocation;
}
@@ -732,6 +975,7 @@
localLocation.setBackground( new Color(255,255,238));
localLocation.setFont(
new java.awt.Font("Dialog", java.awt.Font.PLAIN, 10));
+//System.out.println("getLocalLocation");
}
return localLocation;
}
@@ -748,6 +992,7 @@
localStatus.setFont(
new java.awt.Font("Dialog", java.awt.Font.PLAIN, 10));
localStatus.setEditable(false);
+//System.out.println("getLocalStatus");
}
return localStatus;
}
@@ -764,6 +1009,7 @@
remoteStatus.setFont(
new java.awt.Font("Dialog", java.awt.Font.PLAIN, 10));
remoteStatus.setEditable(false);
+//System.out.println("getRemoteStatus");
}
return remoteStatus;
}
@@ -777,9 +1023,10 @@
historyComboBox = new javax.swing.JComboBox();
historyComboBox.setFont(
new java.awt.Font("Dialog", java.awt.Font.BOLD, 10));
- historyComboBox.insertItemAt(new String("Pulldown to view history ..."),0);
+ historyComboBox.insertItemAt(new String("Pulldown to view history; Press Escape to Close/Quit; Press Ctrl-R to Reset Panel."),0);
historyComboBox.setSelectedIndex(0);
historyComboBox.addActionListener(this);
+//System.out.println("getHistoryComboBox");
}
return historyComboBox;
}
@@ -791,6 +1038,7 @@
private javax.swing.JProgressBar getJProgressBar() {
if (jProgressBar == null) {
jProgressBar = new javax.swing.JProgressBar();
+//System.out.println("getJProgressBar");
}
return jProgressBar;
}
@@ -806,6 +1054,7 @@
connectionStatus.setBackground(java.awt.Color.lightGray);
connectionStatus.setFont(
new java.awt.Font("Dialog", java.awt.Font.PLAIN, 10));
+//System.out.println("getConnectionStatus");
}
connectionStatus.setEditable(false);
return connectionStatus;
@@ -815,7 +1064,12 @@
* Implements Action listener.
*/
public void actionPerformed(ActionEvent evt) {
- System.out.println(evt.getSource());
+// System.out.println(evt.getSource());
+
+ if (ignore_events) {
+ System.out.println("ignore_events: " + evt.getSource());
+ return;
+ }
if (evt.getSource() == closeButton)
{ // Close Button
@@ -829,15 +1083,27 @@
{
doReceive();
}
+// begin runge/x11vnc
+ else if (evt.getSource() == viewButton)
+ {
+ doView();
+ }
+// end runge/x11vnc
else if (evt.getSource() == localDrivesComboBox)
{
changeLocalDrive();
}
else if (evt.getSource() == remoteDrivesComboBox)
{
+//System.out.println("remoteDrivesComboBox"); // runge/x11vnc
changeRemoteDrive();
- remoteList.clear();
- remoteFileTable.setListData(remoteList);
+
+ // are these really needed? changeRemoteDrive() does them at the end.
+ if (false) {
+ remoteList.clear();
+ remoteListInfo.clear();
+ remoteFileTable.setListData(remoteList);
+ }
}
else if (evt.getSource() == localTopButton)
{
@@ -845,12 +1111,17 @@
}
else if (evt.getSource() == remoteTopButton)
{
+//System.out.println("remoteTopButton"); // runge/x11vnc
changeRemoteDrive();
}
else if(evt.getSource() == deleteButton)
{
doDelete();
}
+ else if(evt.getSource() == refreshButton)
+ {
+ doRefresh();
+ }
else if(evt.getSource()==newFolderButton)
{
doNewFolder();
@@ -864,7 +1135,7 @@
private void doNewFolder()
{
- String name = JOptionPane.showInputDialog(null,"Enter new directory name", "Create New Directory", JOptionPane.QUESTION_MESSAGE);
+ String name = JOptionPane.showInputDialog(jContentPane,"Enter new directory name", "Create New Directory", JOptionPane.QUESTION_MESSAGE);
if(selectedTable.equals("remote"))
{
name = remoteLocation.getText()+name;
@@ -880,34 +1151,106 @@
historyComboBox.setSelectedIndex(0);
}
}
- private void doClose()
+ public void doClose()
{
+ if (viewer.ftpOnly) {
+ viewer.disconnect();
+ return;
+ }
try {
this.setVisible(false);
- viewer.rfb.writeFramebufferUpdateRequest(
- 0,
- 0,
- viewer.rfb.framebufferWidth,
- viewer.rfb.framebufferHeight,
- true);
+ viewer.rfb.writeFramebufferUpdateRequest(0, 0, viewer.rfb.framebufferWidth,
+ viewer.rfb.framebufferHeight, true);
+
+ if (false) {
+ this.dispose();
+ jContentPane = null;
+ }
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
+ private void unSwing() {
+ jContentPane = null;
+ topPanel = null;
+ topPanelLocal = null;
+ topPanelRemote = null;
+ topPanelCenter = null;
+ statusPanel = null;
+ remotePanel = null;
+ localPanel = null;
+ buttonPanel = null;
+ sendButton = null;
+ receiveButton = null;
+ deleteButton = null;
+ newFolderButton = null;
+ stopButton = null;
+ closeButton = null;
+ dummyButton = null;
+ localDrivesComboBox = null;
+ remoteDrivesComboBox = null;
+ localMachineLabel = null;
+ remoteMachineLabel = null;
+ localTopButton = null;
+ remoteTopButton = null;
+ localScrollPane = null;
+ localFileTable = null;
+ remoteScrollPane = null;
+ remoteFileTable = null;
+ remoteLocation = null;
+ localLocation = null;
+ localStatus = null;
+ remoteStatus = null;
+ historyComboBox = null;
+ jProgressBar = null;
+ connectionStatus = null;
+ viewButton = null;
+ refreshButton = null;
+ }
+
+ public void doReset()
+ {
+ try {
+ this.setVisible(false);
+ this.dispose();
+ jContentPane = null;
+ try {Thread.sleep(500);} catch (InterruptedException e) {}
+ viewer.ftp_init();
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ public void doOpen()
+ {
+ try {
+ this.setVisible(true);
+ if (false) {
+ this.initialize();
+ }
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
private void doDelete()
{
- System.out.println("Delete Button Pressed");
+// System.out.println("Delete Button Pressed");
//Call this method to delete a file at server
if(selectedTable.equals("remote"))
{
- String sFileName = ((String) this.remoteFileTable.getSelectedValue());
+ Object selected = this.remoteFileTable.getSelectedValue();
+ if (selected == null) {
+ return;
+ }
+ String sFileName = ((String) selected);
// sf@2004 - Directory can't be deleted
if (sFileName.substring(0, 2).equals(" [") && sFileName.substring((sFileName.length() - 1), sFileName.length()).equals("]"))
{
- JOptionPane.showMessageDialog(null, (String)"Directory Deletion is not yet available in this version...", "FileTransfer Info", JOptionPane.INFORMATION_MESSAGE);
+ JOptionPane.showMessageDialog(jContentPane, (String)"Directory Deletion is not yet available in this version...", "FileTransfer Info", JOptionPane.INFORMATION_MESSAGE);
return;
}
@@ -916,7 +1259,7 @@
// sf@2004 - Delete prompt
if (remoteList.contains(sFileName))
{
- int r = JOptionPane.showConfirmDialog(null, "Are you sure you want to delete the file \n< " + sFileName + " >\n on Remote Machine ?", "File Transfer Warning", JOptionPane.YES_NO_OPTION);
+ int r = JOptionPane.showConfirmDialog(jContentPane, "Are you sure you want to delete the file \n< " + sFileName + " >\n on Remote Machine ?", "File Transfer Warning", JOptionPane.YES_NO_OPTION);
if (r == JOptionPane.NO_OPTION)
return;
}
@@ -926,18 +1269,22 @@
}
else
{
- String sFileName = ((String) this.localFileTable.getSelectedValue());
+ Object selected = this.localFileTable.getSelectedValue();
+ if (selected == null) {
+ return;
+ }
+ String sFileName = ((String) selected);
// sf@2004 - Directory can't be deleted
if (sFileName.substring(0, 2).equals(" [") && sFileName.substring((sFileName.length() - 1), sFileName.length()).equals("]"))
{
- JOptionPane.showMessageDialog(null, (String)"Directory Deletion is not yet available in this version...", "FileTransfer Info", JOptionPane.INFORMATION_MESSAGE);
+ JOptionPane.showMessageDialog(jContentPane, (String)"Directory Deletion is not yet available in this version...", "FileTransfer Info", JOptionPane.INFORMATION_MESSAGE);
return;
}
// sf@2004 - Delete prompt
if (localList.contains(sFileName))
{
- int r = JOptionPane.showConfirmDialog(null, "Are you sure you want to delete the file \n< " + sFileName + " >\n on Local Machine ?", "File Transfer Warning", JOptionPane.YES_NO_OPTION);
+ int r = JOptionPane.showConfirmDialog(jContentPane, "Are you sure you want to delete the file \n< " + sFileName + " >\n on Local Machine ?", "File Transfer Warning", JOptionPane.YES_NO_OPTION);
if (r == JOptionPane.NO_OPTION)
return;
}
@@ -952,21 +1299,25 @@
private void doReceive()
{
- System.out.println("Received Button Pressed");
+// System.out.println("Received Button Pressed");
- String sFileName = ((String) this.remoteFileTable.getSelectedValue());
+ Object selected = this.remoteFileTable.getSelectedValue();
+ if (selected == null) {
+ return;
+ }
+ String sFileName = ((String) selected);
// sf@2004 - Directory can't be transfered
if (sFileName.substring(0, 2).equals(" [") && sFileName.substring((sFileName.length() - 1), sFileName.length()).equals("]"))
{
- JOptionPane.showMessageDialog(null, (String)"Directory Transfer is not yet available in this version...", "FileTransfer Info", JOptionPane.INFORMATION_MESSAGE);
+ JOptionPane.showMessageDialog(jContentPane, (String)"Directory Transfer is not yet available in this version...", "FileTransfer Info", JOptionPane.INFORMATION_MESSAGE);
return;
}
// sf@2004 - Overwrite prompt
if (localList.contains(sFileName))
{
- int r = JOptionPane.showConfirmDialog(null, "The file < " + sFileName + " >\n already exists on Local Machine\n Are you sure you want to overwrite it ?", "File Transfer Warning", JOptionPane.YES_NO_OPTION);
+ int r = JOptionPane.showConfirmDialog(jContentPane, "The file < " + sFileName + " >\n already exists on Local Machine\n Are you sure you want to overwrite it ?", "File Transfer Warning", JOptionPane.YES_NO_OPTION);
if (r == JOptionPane.NO_OPTION)
return;
}
@@ -979,23 +1330,101 @@
viewer.rfb.requestRemoteFile(remoteFileName,localDestinationPath);
}
+// begin runge/x11vnc
+ private void doRefresh()
+ {
+ System.out.println("Refreshing Local and Remote.");
+ refreshLocalLocation();
+ refreshRemoteLocation();
+ }
+
+ private void doView()
+ {
+// System.out.println("View Button Pressed");
+
+ if (selectedTable == null) {
+ return;
+ }
+ if (selectedTable.equals("remote")) {
+ viewRemote();
+ } else if (selectedTable.equals("local")) {
+ viewLocal();
+ }
+ }
+
+ private File doReceiveTmp()
+ {
+
+ if (remoteFileTable == null) {
+ return null;
+ }
+ Object selected = this.remoteFileTable.getSelectedValue();
+ if (selected == null) {
+ return null;
+ }
+ String sFileName = ((String) selected);
+
+ if (sFileName == null) {
+ return null;
+ }
+
+ // sf@2004 - Directory can't be transfered
+ if (sFileName.substring(0, 2).equals(" [") && sFileName.substring((sFileName.length() - 1), sFileName.length()).equals("]"))
+ {
+ return null;
+ }
+
+ File tmp = null;
+ try {
+ tmp = File.createTempFile("ULTRAFTP", ".txt");
+ } catch (Exception e) {
+ return null;
+ }
+
+ //updateHistory("Downloaded " + localSelection.toString());
+ String remoteFileName = this.remoteLocation.getText();
+ remoteFileName+= ((String) this.remoteFileTable.getSelectedValue()).substring(1);
+ System.out.println("remoteFileName: " + remoteFileName);
+if (false) {
+ char[] b = remoteFileName.toCharArray();
+ for (int n = 0; n < b.length; n++) {
+ System.out.print(Integer.toHexString(b[n]) + " ");
+ }
+ System.out.println("");
+ for (int n = 0; n < b.length; n++) {
+ System.out.print(b[n]);
+ }
+ System.out.println("");
+}
+
+ String localDestinationPath = tmp.getAbsolutePath();
+ viewer.rfb.requestRemoteFile(remoteFileName,localDestinationPath);
+ System.out.println("ReceiveTmp: " + localDestinationPath);
+ return tmp;
+ }
+// end runge/x11vnc
+
private void doSend()
{
- System.out.println("Send Button Pressed");
+// System.out.println("Send Button Pressed");
- String sFileName = ((String) this.localFileTable.getSelectedValue());
+ Object selected = this.localFileTable.getSelectedValue();
+ if (selected == null) {
+ return;
+ }
+ String sFileName = ((String) selected);
// sf@2004 - Directory can't be transfered
if (sFileName.substring(0, 2).equals(" [") && sFileName.substring((sFileName.length() - 1), sFileName.length()).equals("]"))
{
- JOptionPane.showMessageDialog(null, (String)"Directory Transfer is not yet available in this version...", "FileTransfer Info", JOptionPane.INFORMATION_MESSAGE);
+ JOptionPane.showMessageDialog(jContentPane, (String)"Directory Transfer is not yet available in this version...", "FileTransfer Info", JOptionPane.INFORMATION_MESSAGE);
return;
}
// sf@2004 - Overwrite prompt
if (remoteList.contains(sFileName))
{
- int r = JOptionPane.showConfirmDialog(null, "The file < " + sFileName + " >\n already exists on Remote Machine\n Are you sure you want to overwrite it ?", "File Transfer Warning", JOptionPane.YES_NO_OPTION);
+ int r = JOptionPane.showConfirmDialog(jContentPane, "The file < " + sFileName + " >\n already exists on Remote Machine\n Are you sure you want to overwrite it ?", "File Transfer Warning", JOptionPane.YES_NO_OPTION);
if (r == JOptionPane.NO_OPTION)
return;
}
@@ -1013,6 +1442,7 @@
//
private void doStop()
{
+ System.out.println("** Current Transfer Aborted **");
viewer.rfb.fAbort = true;
}
/**
@@ -1024,6 +1454,14 @@
System.out.println("History: " + message);
historyComboBox.insertItemAt(new String(message), 0);
}
+
+ public void receivedRemoteDirectoryName(String str) {
+ if (doingShortcutDir) {
+ if (str.length() > 1) {
+ remoteLocation.setText(str);
+ }
+ }
+ }
/**
* This method updates the file table to the current selection of the remoteComboBox
@@ -1034,11 +1472,44 @@
remoteSelection = null;
if (!updateDriveList) {
- String drive = remoteDrivesComboBox.getSelectedItem().toString().substring(0,1)+ ":\\";
- viewer.rfb.readServerDirectory(drive);
- remoteLocation.setText(drive);
+//System.out.println("changeRemoteDrive-A " + drive); // begin runge/x11vnc
+ Object selected = remoteDrivesComboBox.getSelectedItem();
+ if (selected != null) {
+ String instr = selected.toString();
+ if (instr != null) {
+System.out.println("changeRemoteDrive: instr='" + instr + "'");
+ String drive = instr.substring(0,1)+ ":\\";
+ if (instr.startsWith(" [")) {
+ int idx = instr.lastIndexOf(']');
+ if (idx > 2) {
+ drive = instr.substring(2, idx);
+ } else {
+ drive = instr.substring(2);
+ }
+ if (drive.equals("Home")) {
+ drive = "";
+ }
+ drive += "\\";
+ doingShortcutDir = true;
+ } else {
+ doingShortcutDir = false;
+ drive = saveRemoteHack(drive);
+ }
+ gotShortcutDir = false;
+ viewer.rfb.readServerDirectory(drive);
+ if (!gotShortcutDir) {
+ remoteLocation.setText(drive);
+ }
+ } else {
+System.out.println("changeRemoteDrive: instr null");
+ }
+ } else {
+System.out.println("changeRemoteDrive: selection null");
+ }
+//System.out.println("changeRemoteDrive-B " + drive); // end runge/x11vnc
}
remoteList.clear();
+ remoteListInfo.clear();
remoteFileTable.setListData(remoteList);
}
/**
@@ -1048,6 +1519,7 @@
private void changeLocalDrive()
{
File currentDrive = new File(localDrivesComboBox.getSelectedItem().toString());
+System.out.println("changeLocalDrive " + currentDrive.toString()); // runge/x11vnc
if(currentDrive.canRead())
{
localSelection = null;
@@ -1057,9 +1529,11 @@
else
{
localList.clear();
+ localListInfo.clear();
localStatus.setText("WARNING: Drive " + localDrivesComboBox.getSelectedItem().toString());
connectionStatus.setText(" > WARNING - Local Drive unavailable (possibly restricted access or media not present)");
}
+
}
/**
* Determines which FileTable was double-clicked and updates the table
@@ -1098,10 +1572,18 @@
selectedTable = "remote";
localFileTable.setBackground(new Color(238, 238, 238));
remoteFileTable.setBackground(new Color(255, 255, 255));
- String name = (remoteFileTable.getSelectedValue().toString()).substring(1);
+ Object selected = remoteFileTable.getSelectedValue();
+ if (selected == null) {
+ return;
+ }
+ String selstr = selected.toString();
+ if (selstr == null) {
+ return;
+ }
+ String name = selstr.substring(1);
if( !name.substring(0, 2).equals(" ["))
remoteSelection = remoteLocation.getText() + name.substring(0, name.length());
-
+
}
/*
@@ -1115,10 +1597,38 @@
localFileTable.setBackground(new Color(255, 255, 255));
File currentSelection = new File(currentLocalDirectory, getTrimmedSelection());
- if(currentSelection.isFile())
+// begin runge/x11vnc
+ // localSelection = currentSelection.getAbsoluteFile();
+ if(currentSelection.isFile()) {
localSelection = currentSelection.getAbsoluteFile();
+ localCurrentIsDir = false;
+ } else {
+ localCurrentIsDir = true;
+ }
+// end runge/x11vnc
}
+
+// begin runge/x11vnc
+ private void viewRemote() {
+ File tmp = doReceiveTmp();
+ if (tmp == null) {
+ return;
+ }
+ TextViewer tv = new TextViewer("Remote: " + remoteSelection, tmp, true);
+ }
+ private void viewLocal() {
+ if (localSelection == null) {
+ return;
+ }
+ if (localCurrentIsDir) {
+ return;
+ }
+ File loc = new File(localSelection.toString());
+ TextViewer tv = new TextViewer("Local: " + localSelection.toString(), loc, false);
+ }
+// end runge/x11vnc
+
/**
* Updates the Remote File Table based on selection. Called from mouseClicked handler
*/
@@ -1126,20 +1636,29 @@
String name = null;
String action = null;
String drive = null;
- name = (remoteFileTable.getSelectedValue().toString()).substring(1);
+ Object selected = remoteFileTable.getSelectedValue();
+ if (selected == null) {
+ return;
+ }
+ String sname = selected.toString();
+ if (sname == null) {
+ return;
+ }
+ name = sname.substring(1);
if (name.equals("[..]"))
{
action = "up";
remoteSelection = null;
drive = remoteLocation.getText().substring(0, remoteLocation.getText().length() - 1);
- // JOptionPane.showMessageDialog(null, (String)drive, "FileTransfer DEBUG", JOptionPane.INFORMATION_MESSAGE);
+ // JOptionPane.showMessageDialog(jContentPane, (String)drive, "FileTransfer DEBUG", JOptionPane.INFORMATION_MESSAGE);
int index = drive.lastIndexOf("\\");
drive = drive.substring(0, index + 1);
remoteLocation.setText(drive);
viewer.rfb.readServerDirectory(drive);
remoteList.clear();
+ remoteListInfo.clear();
remoteFileTable.setListData(remoteList);
}
else if (!name.substring(0, 2).equals(" [") && !name.substring((name.length() - 1), name.length()).equals("]"))
@@ -1149,6 +1668,7 @@
remoteSelection = remoteLocation.getText() + name.substring(0, name.length());
drive = remoteLocation.getText();
// ??
+ viewRemote(); // runge/x11vnc
}
else
{
@@ -1159,10 +1679,12 @@
remoteLocation.setText(drive);
viewer.rfb.readServerDirectory(drive);
remoteList.clear();
+ remoteListInfo.clear();
remoteFileTable.setListData(remoteList);
}
//remoteLocation.setText(drive);
}
+
/**
* Updates the Local File Table based on selection. Called from MouseClicked handler
*/
@@ -1188,6 +1710,7 @@
else if (currentSelection.isFile())
{
localSelection = currentSelection.getAbsoluteFile();
+ viewLocal(); // runge/x11vnc
}
else if (currentSelection.isDirectory())
{
@@ -1201,13 +1724,22 @@
*
*/
private String getTrimmedSelection(){
- String currentSelection = (localFileTable.getSelectedValue().toString()).substring(1);
- if(currentSelection.substring(0,1).equals("[") &&
- currentSelection.substring(currentSelection.length()-1,currentSelection.length()).equals("]")){
- return currentSelection.substring(1,currentSelection.length()-1);
- } else {
- return currentSelection;
- }
+ String currentSelection = "";
+ Object selected = localFileTable.getSelectedValue();
+ if (selected == null) {
+ return currentSelection;
+ }
+ String selstr = selected.toString();
+ if (selstr == null) {
+ return currentSelection;
+ }
+ currentSelection = selstr.substring(1);
+ if(currentSelection.substring(0,1).equals("[") &&
+ currentSelection.substring(currentSelection.length()-1,currentSelection.length()).equals("]")){
+ return currentSelection.substring(1,currentSelection.length()-1);
+ } else {
+ return currentSelection;
+ }
}
/*
@@ -1241,36 +1773,148 @@
return null;
}
+ String timeStr(long t) {
+ Date date = new Date(t);
+ return date.toString();
+ }
+ String dotPast(double f, int n) {
+ String fs = "" + f;
+ int i = fs.lastIndexOf(".") + n;
+ if (i >= 0) {
+ int len = fs.length();
+ if (i >= len) {
+ i = len-1;
+ }
+ fs = fs.substring(0, i);
+ }
+ return fs;
+ }
+ String sizeStr(int s) {
+ if (s < 0) {
+ return s + "? B";
+ } else if (s < 1024) {
+ return s + " B";
+ } else if (s < 1024 * 1024) {
+ double k = s / 1024.0;
+ String ks = dotPast(k, 3);
+
+ return s + " (" + ks + " KB)";
+ } else {
+ double m = s / (1024.0*1024.0);
+ String ms = dotPast(m, 3);
+ return s + " (" + ms + " MB)";
+ }
+ }
+
+ int max_char(String text) {
+ int maxc = 0;
+ char chars[] = text.toCharArray();
+ for (int n = 0; n < chars.length; n++) {
+ if ((int) chars[n] > maxc) {
+ maxc = (int) chars[n];
+ }
+ }
+ return maxc;
+ }
/*
* Navigates the local file structure up or down one directory
*/
public void changeLocalDirectory(File dir)
{
- currentLocalDirectory = dir; // Updates Global
+ dir = saveLocalHack(dir); // runge/x11vnc
+
+ if (dir == null) {
+ connectionStatus.setText("Error changing local directory.");
+ historyComboBox.insertItemAt(new String("> Error changing local directory."), 0);
+ historyComboBox.setSelectedIndex(0);
+ return;
+ }
+
File allFiles[] = dir.listFiles(); // Reads files
String[] contents = dir.list();
+ if (contents == null || allFiles == null) {
+ connectionStatus.setText("Error changing local directory.");
+ historyComboBox.insertItemAt(new String("> Error changing local directory."), 0);
+ historyComboBox.setSelectedIndex(0);
+ return;
+ }
+
+ currentLocalDirectory = dir; // Updates Global
+// begin runge/x11vnc
+System.out.println("changeLocalDirectory: " + dir.toString());
+ if (contents != null) {
+ java.util.Arrays.sort(contents, String.CASE_INSENSITIVE_ORDER);
+ for (int i = 0; i < contents.length; i++) {
+ allFiles[i] = new File(dir, contents[i]);
+ }
+ } else {
+ return;
+ }
+// end runge/x11vnc
+
localList.clear();
+ localListInfo.clear();
localList.addElement(" [..]");
+ localListInfo.addElement(" [..]");
+
+ ArrayList DirInfo = new ArrayList();
+ ArrayList FilInfo = new ArrayList();
+
+ Charset charset = Charset.forName("ISO-8859-1");
+ CharsetDecoder decoder = charset.newDecoder();
+ CharsetEncoder encoder = charset.newEncoder();
// Populate the Lists
for (int i = 0; i < contents.length; i++)
{
- if (allFiles[i].isDirectory())
+ String f1 = contents[i];
+
+if (false) {
+
+System.out.println("max_char: " + max_char(f1) + " " + f1);
+ if (max_char(f1) > 255) {
+ try {
+System.out.println("bbuf1");
+ ByteBuffer bbuf = encoder.encode(CharBuffer.wrap(f1.toCharArray()));
+System.out.println("bbuf2");
+ CharBuffer cbuf = decoder.decode(bbuf);
+System.out.println("bbuf3");
+ f1 = cbuf.toString();
+System.out.println("did bbuf: " + f1);
+ } catch (Exception e) {
+ ;
+ }
+ }
+}
+
+ String f2 = f1;
+ if (f2.length() < 24) {
+ for (int ik = f2.length(); ik < 24; ik++) {
+ f2 = f2 + " ";
+ }
+ }
+ String s = f2 + " \tLastmod: " + timeStr(allFiles[i].lastModified()) + " \t\tSize: " + sizeStr((int) allFiles[i].length());
+ if (allFiles[i].isDirectory()) {
// localList.addElement("[" + contents[i] + "]");
- DirsList.add(" [" + contents[i] + "]"); // sf@2004
- else
- {
+ DirsList.add(" [" + f1 + "]"); // sf@2004
+ DirInfo.add(s);
+ } else {
// localList.addElement(contents[i]);
- FilesList.add(" " + contents[i]); // sf@2004
+ FilesList.add(" " + f1); // sf@2004
+ FilInfo.add(s);
}
}
// sf@2004
- for (int i = 0; i < DirsList.size(); i++)
+ for (int i = 0; i < DirsList.size(); i++) {
localList.addElement(DirsList.get(i));
- for (int i = 0; i < FilesList.size(); i++)
+ localListInfo.addElement(DirInfo.get(i));
+ }
+ for (int i = 0; i < FilesList.size(); i++) {
localList.addElement(FilesList.get(i));
+ localListInfo.addElement(FilInfo.get(i));
+ }
FilesList.clear();
DirsList.clear();
@@ -1296,3 +1940,147 @@
}
} // @jve:visual-info decl-index=0 visual-constraint="10,10"
+
+// begin runge/x11vnc
+class TextViewer extends JFrame implements ActionListener {
+
+ JTextArea textArea = new JTextArea(35, 80);
+ File file = null;
+ JButton refreshButton;
+ JButton dismissButton;
+ Timer tim = null;
+ int rcnt = 0;
+ int tms = 250;
+ boolean delete_it = false;
+ TextViewer me;
+
+ public TextViewer(String s, File f, boolean d) {
+
+ delete_it = d;
+ file = f;
+ me = this;
+
+ JScrollPane scrollPane = new JScrollPane(textArea,
+ JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+ JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
+
+ textArea.setEditable(false);
+ textArea.setFont(new Font("Monospaced", Font.PLAIN, 12));
+
+ KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, InputEvent.SHIFT_MASK);
+ AbstractAction escapeAction = new AbstractAction() {
+ public void actionPerformed(ActionEvent actionEvent) {
+ cleanse();
+ me.dispose();
+ }
+ };
+ textArea.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(stroke, "escapeAction");
+ textArea.getInputMap().put(stroke, "escapeAction");
+ textArea.getActionMap().put("escapeAction", escapeAction);
+
+ refreshButton = new JButton();
+ refreshButton.setText("Reload");
+ refreshButton.setName("refreshButton");
+ refreshButton.addActionListener(this);
+
+ dismissButton = new JButton();
+ dismissButton.setText("Dismiss");
+ dismissButton.setName("dismissButton");
+ dismissButton.addActionListener(this);
+
+ JPanel buttons = new JPanel();
+ buttons.setLayout(new BorderLayout());
+ buttons.add(refreshButton, BorderLayout.WEST);
+ buttons.add(dismissButton, BorderLayout.EAST);
+
+ JPanel content = new JPanel();
+ content.setLayout(new BorderLayout());
+ content.add(scrollPane, BorderLayout.CENTER);
+ content.add(buttons, BorderLayout.SOUTH);
+
+ ActionListener tsk = new ActionListener() {
+ public void actionPerformed(ActionEvent evt) {
+ // System.out.println("tsk");
+ refresh();
+ }
+ };
+ tim = new Timer(tms, tsk);
+ tim.start();
+
+ this.setContentPane(content);
+ this.setTitle("TextViewer - " + s);
+ this.pack();
+ this.setVisible(true);
+ }
+
+ private void refresh() {
+
+ rcnt++;
+ if (rcnt * tms > 3000 && tim != null) {
+ tim.stop();
+ tim = null;
+ }
+ BufferedReader input = null;
+ StringBuffer contents = new StringBuffer();
+ try {
+ if (input == null) {
+ input = new BufferedReader(new FileReader(file));
+ }
+ String line = null;
+ int i = 0;
+ while (( line = input.readLine()) != null) {
+ if (i == 0) {
+ // System.out.println("read");
+ }
+ i++;
+ contents.append(line);
+ contents.append(System.getProperty("line.separator"));
+ }
+ } catch (Exception e) {
+ ;
+ } finally {
+ try {
+ if (input != null) {
+ input.close();
+ input = null;
+ }
+ } catch (Exception e) {
+ ;
+ }
+ }
+
+ textArea.setText(contents.toString());
+ textArea.setCaretPosition(0);
+ }
+
+ public void actionPerformed(ActionEvent evt) {
+
+ if (evt.getSource() == refreshButton) {
+ refresh();
+ }
+ if (evt.getSource() == dismissButton) {
+ cleanse();
+ this.dispose();
+ }
+ }
+
+ private void cleanse() {
+ if (delete_it && file != null) {
+ try {
+ file.delete();
+ file = null;
+ } catch (Exception e) {
+ ;
+ }
+ }
+ }
+
+ protected void finalize() throws Throwable {
+ try {
+ cleanse();
+ } finally {
+ super.finalize();
+ }
+ }
+}
+// end runge/x11vnc
diff -Naur JavaViewer.orig/OptionsFrame.java JavaViewer/OptionsFrame.java
--- JavaViewer.orig/OptionsFrame.java 2005-11-21 18:50:16.000000000 -0500
+++ JavaViewer/OptionsFrame.java 2007-05-13 22:18:30.000000000 -0400
@@ -144,7 +144,10 @@
choices[jpegQualityIndex].select("6");
choices[cursorUpdatesIndex].select("Enable");
choices[useCopyRectIndex].select("Yes");
- choices[eightBitColorsIndex].select("64");
+// begin runge/x11vnc
+// choices[eightBitColorsIndex].select("64");
+ choices[eightBitColorsIndex].select("Full");
+// end runge/x11vnc
choices[mouseButtonIndex].select("Normal");
choices[viewOnlyIndex].select("No");
choices[shareDesktopIndex].select("Yes");
diff -Naur JavaViewer.orig/RfbProto.java JavaViewer/RfbProto.java
--- JavaViewer.orig/RfbProto.java 2006-05-24 15:14:40.000000000 -0400
+++ JavaViewer/RfbProto.java 2008-10-06 13:32:30.000000000 -0400
@@ -31,6 +31,7 @@
import java.net.Socket;
import java.util.*;
import java.util.zip.*;
+import java.text.DateFormat;
class RfbProto {
@@ -86,8 +87,11 @@
// sf@2004 - FileTransfer part
ArrayList remoteDirsList;
+ ArrayList remoteDirsListInfo;
ArrayList remoteFilesList;
+ ArrayList remoteFilesListInfo;
ArrayList a;
+ ArrayList b;
boolean fFTInit = true; // sf@2004
boolean fFTAllowed = true;
boolean fAbort = false;
@@ -199,6 +203,10 @@
// playback.
int numUpdatesInSession;
+// begin runge/x11vnc
+ int readServerDriveListCnt = -1;
+ long readServerDriveListTime = 0;
+// end runge/x11vnc
//
// Constructor. Make TCP connection to RFB server.
//
@@ -207,7 +215,27 @@
viewer = v;
host = h;
port = p;
- sock = new Socket(host, port);
+// begin runge/x11vnc
+// sock = new Socket(host, port);
+ if (! viewer.disableSSL) {
+ System.out.println("new SSLSocketToMe");
+ SSLSocketToMe ssl;
+ try {
+ ssl = new SSLSocketToMe(host, port, v);
+ } catch (Exception e) {
+ throw new IOException(e.getMessage());
+ }
+
+ try {
+ sock = ssl.connectSock();
+ } catch (Exception es) {
+ throw new IOException(es.getMessage());
+ }
+ } else {
+ sock = new Socket(host, port);
+ }
+// end runge/x11vnc
+
is =
new DataInputStream(
new BufferedInputStream(sock.getInputStream(), 16384));
@@ -215,9 +243,12 @@
osw = new OutputStreamWriter(sock.getOutputStream());
inDirectory2 = false;
a = new ArrayList();
+ b = new ArrayList();
// sf@2004
remoteDirsList = new ArrayList();
+ remoteDirsListInfo = new ArrayList();
remoteFilesList = new ArrayList();
+ remoteFilesListInfo = new ArrayList();
sendFileSource = "";
}
@@ -420,7 +451,13 @@
//
int readServerMessageType() throws IOException {
- int msgType = is.readUnsignedByte();
+ int msgType;
+ try {
+ msgType = is.readUnsignedByte();
+ } catch (Exception e) {
+ viewer.disconnect();
+ return -1;
+ }
// If the session is being recorded:
if (rec != null) {
@@ -600,6 +637,7 @@
contentParamT = is.readUnsignedByte();
contentParamT = contentParamT << 8;
contentParam = contentParam | contentParamT;
+//System.out.println("FTM: contentType " + contentType + " contentParam " + contentParam);
if (contentType == rfbRDrivesList || contentType == rfbDirPacket)
{
readDriveOrDirectory(contentParam);
@@ -610,7 +648,7 @@
}
else if (contentType == rfbFilePacket)
{
- receiveFileChunk();
+ receiveFileChunk();
}
else if (contentType == rfbEndOfFile)
{
@@ -618,6 +656,10 @@
}
else if (contentType == rfbAbortFileTransfer)
{
+ System.out.println("rfbAbortFileTransfer: fFileReceptionRunning="
+ + fFileReceptionRunning + " fAbort="
+ + fAbort + " fFileReceptionError="
+ + fFileReceptionError);
if (fFileReceptionRunning)
{
endOfReceiveFile(false); // Error
@@ -626,6 +668,11 @@
{
// sf@2004 - Todo: Add TestPermission
// System.out.println("File Transfer Aborted!");
+
+ // runge: seems like we must at least read the remaining
+ // 8 bytes of the header, right?
+ int size = is.readInt();
+ int length = is.readInt();
}
}
@@ -645,6 +692,7 @@
{
System.out.println("ContentType: " + contentType);
}
+//System.out.println("FTM: done");
}
//Refactored from readRfbFileTransferMsg()
@@ -662,6 +710,7 @@
//Refactored from readRfbFileTransferMsg()
public void readDriveOrDirectory(int contentParam) throws IOException {
+//System.out.println("RDOD: " + contentParam + " " + inDirectory2);
if (contentParam == rfbADrivesList)
{
readFTPMsgDriveList();
@@ -688,13 +737,21 @@
// Internally used. Write an Rfb message to the server
void writeRfbFileTransferMsg(
- int contentType,
- int contentParam,
- long size, // 0 : compression not supported - 1 : compression supported
- long length,
- String text) throws IOException
+ int contentType,
+ int contentParam,
+ long size, // 0 : compression not supported - 1 : compression supported
+ long length,
+ String text) throws IOException
{
byte b[] = new byte[12];
+ byte byteArray[];
+
+ if (viewer.dsmActive) {
+ // need to send the rfbFileTransfer msg type twice for the plugin...
+ byte b2[] = new byte[1];
+ b2[0] = (byte) rfbFileTransfer;
+ os.write(b2);
+ }
b[0] = (byte) rfbFileTransfer;
b[1] = (byte) contentType;
@@ -702,7 +759,7 @@
byte by = 0;
long c = 0;
- length++;
+
c = size & 0xFF000000;
by = (byte) (c >>> 24);
b[4] = by;
@@ -716,6 +773,32 @@
by = (byte) c;
b[7] = by;
+ if (text != null) {
+ byte byteArray0[] = text.getBytes();
+ int maxc = max_char(text);
+ if (maxc > 255) {
+ System.out.println("writeRfbFileTransferMsg: using getBytes(\"UTF-8\")");
+ byteArray0 = text.getBytes("UTF-8");
+ } else if (maxc > 127) {
+ System.out.println("writeRfbFileTransferMsg: using getBytes(\"ISO-8859-1\")");
+ byteArray0 = text.getBytes("ISO-8859-1");
+ }
+ byteArray = new byte[byteArray0.length + 1];
+ for (int i = 0; i < byteArray0.length; i++) {
+ byteArray[i] = byteArray0[i];
+ }
+ byteArray[byteArray.length - 1] = 0;
+System.out.println("writeRfbFileTransferMsg: length: " + length + " -> byteArray.length: " + byteArray.length);
+
+ // will equal length for ascii, ISO-8859-1, more for UTF-8
+ length = byteArray.length;
+
+ //length++; // used to not include null byte at end.
+ } else {
+ String moo = "moo";
+ byteArray = moo.getBytes();
+ }
+
c = length & 0xFF000000;
by = (byte) (c >>> 24);
b[8] = by;
@@ -729,29 +812,91 @@
by = (byte) c;
b[11] = by;
os.write(b);
+
+//System.out.println("size: " + size + " length: " + length + " text: " + text);
if (text != null)
{
- byte byteArray[] = text.getBytes();
- byte byteArray2[] = new byte[byteArray.length + 1];
- for (int i = 0; i < byteArray.length; i++) {
- byteArray2[i] = byteArray[i];
+ os.write(byteArray);
+ }
+ }
+
+ int max_char(String text) {
+ int maxc = 0;
+ char chars[] = text.toCharArray();
+ for (int n = 0; n < chars.length; n++) {
+ if ((int) chars[n] > maxc) {
+ maxc = (int) chars[n];
}
- byteArray2[byteArray2.length - 1] = 0;
- os.write(byteArray2);
}
-
+ return maxc;
+ }
+
+ String guess_encoding(char[] chars) {
+ boolean saw_high_char = false;
+
+ for (int i = 0; i < chars.length; i++) {
+ if (chars[i] == '\0') {
+ break;
+ }
+ if (chars[i] >= 128) {
+ saw_high_char = true;
+ break;
+ }
+ }
+ if (!saw_high_char) {
+ return "ASCII";
+ }
+ char prev = 1;
+ boolean valid_utf8 = true;
+ int n = 0;
+ for (int i = 0; i < chars.length; i++) {
+ if (chars[i] == '\0') {
+ break;
+ }
+ char c = chars[i];
+ if (prev < 128 && c >= 128) {
+ if (c >> 5 == 0x6) {
+ n = 1;
+ } else if (c >> 4 == 0xe) {
+ n = 2;
+ } else if (c >> 3 == 0x1e) {
+ n = 3;
+ } else if (c >> 2 == 0x3e) {
+ n = 4;
+ } else {
+ valid_utf8 = false;
+ break;
+ }
+ } else {
+ if (n > 0) {
+ if (c < 128) {
+ valid_utf8 = false;
+ break;
+ }
+ n--;
+ }
+ }
+
+ prev = c;
+ }
+ if (valid_utf8) {
+ return "UTF-8";
+ } else {
+ return "ISO-8859-1";
+ }
}
+
//Internally used. Write an rfb message to the server for sending files ONLY
int writeRfbFileTransferMsgForSendFile(
- int contentType,
- int contentParam,
- long size,
- long length,
- String source
- ) throws IOException
+ int contentType,
+ int contentParam,
+ long size,
+ long length,
+ String source
+ ) throws IOException
{
File f = new File(source);
fis = new FileInputStream(f);
@@ -768,50 +913,47 @@
while (bytesRead!=-1)
{
- counter += bytesRead;
- myDeflater.setInput(byteBuffer, 0, bytesRead);
- myDeflater.finish();
- compressedSize = myDeflater.deflate(CompressionBuffer);
- myDeflater.reset();
- // If the compressed data is larger than the original one, we're dealing with
- // already compressed data
- if (compressedSize > bytesRead)
- fCompress = false;
- this.writeRfbFileTransferMsg(
- contentType,
- contentParam,
- (fCompress ? 1 : 0),
- (fCompress ? compressedSize-1 : bytesRead-1),
- null
- );
- // Todo: Test write error !
- os.write(
- fCompress ? CompressionBuffer : byteBuffer,
- 0,
- fCompress ? compressedSize : bytesRead
- );
-
- // Todo: test read error !
- bytesRead = fis.read(byteBuffer);
-
- // viewer.ftp.connectionStatus.setText("Sent: "+ counter + " bytes of "+ f.length() + " bytes");
- viewer.ftp.jProgressBar.setValue((int)((counter * 100) / f.length()));
- viewer.ftp.connectionStatus.setText(">>> Sending File: " + source + " - Size: " + f.length() + " bytes - Progress: " + ((counter * 100) / f.length()) + "%");
-
- if (fAbort == true)
- {
- fAbort = false;
- fError = true;
- break;
- }
- try
- {
- Thread.sleep(5);
- }
- catch(InterruptedException e)
- {
- System.err.println("Interrupted");
- }
+ counter += bytesRead;
+ myDeflater.setInput(byteBuffer, 0, bytesRead);
+ myDeflater.finish();
+ compressedSize = myDeflater.deflate(CompressionBuffer);
+ myDeflater.reset();
+ // If the compressed data is larger than the original one, we're dealing with
+ // already compressed data
+ if (compressedSize > bytesRead)
+ fCompress = false;
+ this.writeRfbFileTransferMsg(
+ contentType,
+ contentParam,
+ (fCompress ? 1 : 0),
+// RUNGE (fCompress ? compressedSize-1 : bytesRead-1),
+ (fCompress ? compressedSize : bytesRead),
+ null
+ );
+ // Todo: Test write error !
+ os.write(fCompress ? CompressionBuffer : byteBuffer, 0, fCompress ? compressedSize : bytesRead);
+
+ // Todo: test read error !
+ bytesRead = fis.read(byteBuffer);
+
+ // viewer.ftp.connectionStatus.setText("Sent: "+ counter + " bytes of "+ f.length() + " bytes");
+ viewer.ftp.jProgressBar.setValue((int)((counter * 100) / f.length()));
+ viewer.ftp.connectionStatus.setText(">>> Sending File: " + source + " - Size: " + f.length() + " bytes - Progress: " + ((counter * 100) / f.length()) + "%");
+
+ if (fAbort == true)
+ {
+ fAbort = false;
+ fError = true;
+ break;
+ }
+ try
+ {
+ Thread.sleep(5);
+ }
+ catch(InterruptedException e)
+ {
+ System.err.println("Interrupted");
+ }
}
writeRfbFileTransferMsg(fError ? rfbAbortFileTransfer : rfbEndOfFile, 0, 0, 0, null);
@@ -831,24 +973,30 @@
{
System.out.print((char) is.readUnsignedByte());
}
+ System.out.println("");
+
+ if (size == rfbRErrorCmd || size == -1) {
+ viewer.ftp.enableButtons();
+ viewer.ftp.connectionStatus.setText("Remote file not available for writing.");
+ viewer.ftp.historyComboBox.insertItemAt(new String(" > Error - Remote file not available for writing."), 0);
+ viewer.ftp.historyComboBox.setSelectedIndex(0);
+ return;
+ }
- int ret = writeRfbFileTransferMsgForSendFile(
- rfbFilePacket,
- 0,
- 0,
- 0,
- sendFileSource);
+ int ret = writeRfbFileTransferMsgForSendFile(rfbFilePacket, 0, 0, 0, sendFileSource);
viewer.ftp.refreshRemoteLocation();
if (ret != 1)
{
viewer.ftp.connectionStatus.setText(" > Error - File NOT sent");
- viewer.ftp.historyComboBox.insertItemAt(new String(" > Error - File: <" + sendFileSource) + "> was not correctly sent (aborted by user or error)",0);
+ viewer.ftp.historyComboBox.insertItemAt(new String(" > Error - File: <" + sendFileSource)
+ + "> was not correctly sent (aborted or error). Data may still be buffered/in transit. Wait for remote listing...",0);
}
else
{
viewer.ftp.connectionStatus.setText(" > File sent");
- viewer.ftp.historyComboBox.insertItemAt(new String(" > File: <" + sendFileSource) + "> was sent to Remote Machine",0);
+ viewer.ftp.historyComboBox.insertItemAt(new String(" > File: <" + sendFileSource)
+ + "> was sent to Remote Machine. Note: data may still be buffered/in transit. Wait for remote listing...",0);
}
viewer.ftp.historyComboBox.setSelectedIndex(0);
viewer.ftp.enableButtons();
@@ -907,7 +1055,7 @@
//Handles acknowledgement that the file has been deleted on the server
void deleteRemoteFileFeedback() throws IOException
{
- is.readInt();
+ int ret = is.readInt();
int length = is.readInt();
String f = "";
for (int i = 0; i < length; i++)
@@ -916,7 +1064,11 @@
}
viewer.ftp.refreshRemoteLocation();
- viewer.ftp.historyComboBox.insertItemAt(new String(" > Deleted File On Remote Machine: " + f.substring(0, f.length()-1)),0);
+ if (ret == -1) {
+ viewer.ftp.historyComboBox.insertItemAt(new String(" > ERROR Could not Delete File On Remote Machine: "),0);
+ } else {
+ viewer.ftp.historyComboBox.insertItemAt(new String(" > Deleted File On Remote Machine: " + f.substring(0, f.length()-1)),0);
+ }
viewer.ftp.historyComboBox.setSelectedIndex(0);
}
@@ -926,12 +1078,7 @@
try
{
String temp = text;
- writeRfbFileTransferMsg(
- rfbCommand,
- rfbCFileDelete,
- 0,
- temp.length(),
- temp);
+ writeRfbFileTransferMsg(rfbCommand, rfbCFileDelete, 0, temp.length(), temp);
}
catch (IOException e)
{
@@ -943,7 +1090,7 @@
// Handles acknowledgement that the directory has been created on the server
void createRemoteDirectoryFeedback() throws IOException
{
- is.readInt();
+ int ret = is.readInt();
int length = is.readInt();
String f="";
for (int i = 0; i < length; i++)
@@ -951,7 +1098,11 @@
f += (char)is.readUnsignedByte();
}
viewer.ftp.refreshRemoteLocation();
- viewer.ftp.historyComboBox.insertItemAt(new String(" > Created Directory on Remote Machine: " + f.substring(0, f.length()-1)),0);
+ if (ret == -1) {
+ viewer.ftp.historyComboBox.insertItemAt(new String(" > ERROR Could not Create Directory on Remote Machine."),0);
+ } else {
+ viewer.ftp.historyComboBox.insertItemAt(new String(" > Created Directory on Remote Machine: " + f.substring(0, f.length()-1)),0);
+ }
viewer.ftp.historyComboBox.setSelectedIndex(0);
}
@@ -961,12 +1112,7 @@
try
{
String temp = text;
- writeRfbFileTransferMsg(
- rfbCommand,
- rfbCDirCreate,
- 0,
- temp.length(),
- temp);
+ writeRfbFileTransferMsg(rfbCommand, rfbCDirCreate, 0, temp.length(), temp);
}
catch (IOException e)
{
@@ -979,15 +1125,13 @@
{
try
{
+//System.out.println("requestRemoteFile text: " + text);
+//System.out.println("requestRemoteFile leng: " + text.length());
String temp = text;
receivePath = localPath;
- writeRfbFileTransferMsg(
- rfbFileTransferRequest,
- 0,
- 1, // 0 : compression not supported - 1 : compression supported
- temp.length(),
- temp);
+ // 0 : compression not supported - 1 : compression supported
+ writeRfbFileTransferMsg(rfbFileTransferRequest, 0, 1, temp.length(), temp);
}
catch (IOException e)
{
@@ -1004,6 +1148,9 @@
viewer.ftp.disableButtons();
int size = is.readInt();
int length = is.readInt();
+
+//System.out.println("receiveFileHeader size: " + size);
+//System.out.println("receiveFileHeader leng: " + length);
String tempName = "";
for (int i = 0; i < length; i++)
@@ -1011,6 +1158,15 @@
tempName += (char) is.readUnsignedByte();
}
+ if (size == rfbRErrorCmd || size == -1) {
+ fFileReceptionRunning = false;
+ viewer.ftp.enableButtons();
+ viewer.ftp.connectionStatus.setText("Remote file not available for reading.");
+ viewer.ftp.historyComboBox.insertItemAt(new String(" > Error - Remote file not available for reading."), 0);
+ viewer.ftp.historyComboBox.setSelectedIndex(0);
+ return;
+ }
+
// sf@2004 - Read the high part of file size (not yet in rfbFileTransferMsg for
// backward compatibility reasons...)
int sizeH = is.readInt();
@@ -1021,7 +1177,16 @@
fileSize=0;
fileChunkCounter = 0;
String fileName = receivePath;
- fos = new FileOutputStream(fileName);
+ try {
+ fos = new FileOutputStream(fileName);
+ } catch (Exception e) {
+ fFileReceptionRunning = false;
+ writeRfbFileTransferMsg(rfbAbortFileTransfer, 0, 0, 0, null);
+ viewer.ftp.historyComboBox.insertItemAt(new String(" > ERROR opening Local File: <" + fileName ),0);
+ viewer.ftp.historyComboBox.setSelectedIndex(0);
+ viewer.ftp.enableButtons();
+ return;
+ }
writeRfbFileTransferMsg(rfbFileHeader, 0, 0, 0, null);
}
@@ -1085,7 +1250,13 @@
fAbort = false;
fFileReceptionError = true;
writeRfbFileTransferMsg(rfbAbortFileTransfer, 0, 0, 0, null);
-
+
+ //runge for use with x11vnc/libvncserver, no rfbAbortFileTransfer reply sent.
+ try {Thread.sleep(500);} catch (InterruptedException e) {}
+ viewer.ftp.enableButtons();
+ viewer.ftp.refreshLocalLocation();
+ viewer.ftp.connectionStatus.setText(" > Error - File NOT received");
+ viewer.ftp.historyComboBox.insertItemAt(new String(" > Error - File: <" + receivePath + "> not correctly received from Remote Machine (aborted by user or error)") ,0);
}
// sf@2004 - For old FT protocole only
/*
@@ -1104,7 +1275,7 @@
int length = is.readInt();
fileSize=0;
fos.close();
-
+
viewer.ftp.refreshLocalLocation();
if (fReceptionOk && !fFileReceptionError)
{
@@ -1132,12 +1303,7 @@
try
{
String temp = text;
- writeRfbFileTransferMsg(
- rfbDirContentRequest,
- rfbRDirContent,
- 0,
- temp.length(),
- temp);
+ writeRfbFileTransferMsg(rfbDirContentRequest, rfbRDirContent, 0, temp.length(), temp);
}
catch (IOException e)
{
@@ -1197,11 +1363,80 @@
str += temp;
}
}
+ // runge
+ viewer.ftp.receivedRemoteDirectoryName(str);
// viewer.ftp.changeRemoteDirectory(str);
}
}
+ int zogswap(int n) {
+ long l = n;
+ if (l < 0) {
+ l += 0x100000000L;
+ }
+ l = l & 0xFFFFFFFF;
+ l = (l >> 24) | ((l & 0x00ff0000) >> 8) | ((l & 0x0000ff00) << 8) | (l << 24);
+ return (int) l;
+ }
+
+ int windozeToUnix(int L, int H) {
+ long L2 = zogswap(L);
+ long H2 = zogswap(H);
+ long unix = (H2 << 32) + L2;
+ unix -= 11644473600L * 10000000L;
+ unix /= 10000000L;
+ //System.out.println("unix time: " + unix + " H2: " + H2 + " L2: " + L2);
+ return (int) unix;
+ }
+
+ String timeStr(int t, int h) {
+ if (h == 0) {
+ // x11vnc/libvncserver unix
+ t = zogswap(t);
+ } else {
+ // ultra (except if h==0 by chance)
+ t = windozeToUnix(t, h);
+ }
+ long tl = (long) t;
+ Date date = new Date(tl * 1000);
+ if (true) {
+ return date.toString();
+ } else {
+ return DateFormat.getDateTimeInstance().format(date);
+ }
+ }
+
+ String dotPast(double f, int n) {
+ String fs = "" + f;
+ int i = fs.lastIndexOf(".") + n;
+ if (i >= 0) {
+ int len = fs.length();
+ if (i >= len) {
+ i = len-1;
+ }
+ fs = fs.substring(0, i);
+ }
+ return fs;
+ }
+ String sizeStr(int s) {
+ s = zogswap(s);
+ if (s < 0) {
+ return s + "? B";
+ } else if (s < 1024) {
+ return s + " B";
+ } else if (s < 1024 * 1024) {
+ double k = s / 1024.0;
+ String ks = dotPast(k, 3);
+
+ return s + " (" + ks + " KB)";
+ } else {
+ double m = s / (1024.0*1024.0);
+ String ms = dotPast(m, 3);
+ return s + " (" + ms + " MB)";
+ }
+ }
+
//Internally used to receive directory content from server
//Here, the server sends one file/directory with it's attributes
void readFTPMsgDirectoryListContent() throws IOException
@@ -1217,17 +1452,32 @@
dwReserved0,
dwReserved1;
long ftCreationTime, ftLastAccessTime, ftLastWriteTime;
+ int ftCreationTimeL, ftLastAccessTimeL, ftLastWriteTimeL;
+ int ftCreationTimeH, ftLastAccessTimeH, ftLastWriteTimeH;
char cFileName, cAlternateFileName;
int length = 0;
is.readInt();
length = is.readInt();
+
+ char[] chars = new char[4*length];
+ int char_cnt = 0;
+ for (int i = 0; i < chars.length; i++) {
+ chars[i] = '\0';
+ }
+
dwFileAttributes = is.readInt();
length -= 4;
- ftCreationTime = is.readLong();
+ //ftCreationTime = is.readLong();
+ ftCreationTimeL = is.readInt();
+ ftCreationTimeH = is.readInt();
length -= 8;
- ftLastAccessTime = is.readLong();
+ //ftLastAccessTime = is.readLong();
+ ftLastAccessTimeL = is.readInt();
+ ftLastAccessTimeH = is.readInt();
length -= 8;
- ftLastWriteTime = is.readLong();
+ //ftLastWriteTime = is.readLong();
+ ftLastWriteTimeL = is.readInt();
+ ftLastWriteTimeH = is.readInt();
length -= 8;
nFileSizeHigh = is.readInt();
length -= 4;
@@ -1239,10 +1489,12 @@
length -= 4;
cFileName = (char) is.readUnsignedByte();
length--;
+ chars[char_cnt++] = cFileName;
while (cFileName != '\0')
{
fileName += cFileName;
cFileName = (char) is.readUnsignedByte();
+ chars[char_cnt++] = cFileName;
length--;
}
cAlternateFileName = (char) is.readByte();
@@ -1253,7 +1505,28 @@
cAlternateFileName = (char) is.readUnsignedByte();
length--;
}
- if (dwFileAttributes == 268435456
+ String guessed = guess_encoding(chars);
+ if (!guessed.equals("ASCII")) {
+ System.out.println("guess: " + guessed + "\t" + fileName);
+ }
+ if (guessed.equals("UTF-8")) {
+ try {
+ byte[] bytes = new byte[char_cnt-1];
+ for (int i=0; i < char_cnt-1; i++) {
+ bytes[i] = (byte) chars[i];
+ }
+ String newstr = new String(bytes, "UTF-8");
+ fileName = newstr;
+ } catch (Exception e) {
+ System.out.println("failed to convert bytes to UTF-8 based string");
+ }
+ }
+ for (int i = 0; i < char_cnt; i++) {
+ //System.out.println("char[" + i + "]\t" + (int) chars[i]);
+ }
+ if (fileName.length() <= 0) {
+ ;
+ } else if (dwFileAttributes == 268435456
|| dwFileAttributes == 369098752
|| dwFileAttributes == 285212672
|| dwFileAttributes == 271056896
@@ -1263,11 +1536,74 @@
|| dwFileAttributes == 369623040)
{
fileName = " [" + fileName + "]";
- remoteDirsList.add(fileName); // sf@2004
- }
- else
- {
- remoteFilesList.add(" " + fileName); // sf@2004
+// begin runge/x11vnc
+// remoteDirsList.add(fileName); // sf@2004
+ int i = -1;
+ String t1 = fileName.toLowerCase();
+ for (int j = 0; j < remoteDirsList.size(); j++) {
+ String t = (String) remoteDirsList.get(j);
+ String t2 = t.toLowerCase();
+ if (t1.compareTo(t2) < 0) {
+ i = j;
+ break;
+ }
+ }
+ //String s = "Lastmod: " + timeStr(ftLastWriteTimeL, ftLastWriteTimeH) + " " + fileName;
+ String f2 = fileName;
+ if (f2.length() < 24) {
+ for (int ik = f2.length(); ik < 24; ik++) {
+ f2 = f2 + " ";
+ }
+ }
+ String s = f2 + " \tLastmod: " + timeStr(ftLastWriteTimeL, ftLastWriteTimeH) + " \t\tSize: " + sizeStr(nFileSizeLow);
+ //s = fileName + " Lastmod: " + zogswap(ftLastWriteTimeL);
+ if (i >= 0) {
+ remoteDirsList.add(i, fileName);
+ remoteDirsListInfo.add(i, s);
+ } else {
+ remoteDirsList.add(fileName);
+ remoteDirsListInfo.add(s);
+ }
+// end runge/x11vnc
+ } else {
+// begin runge/x11vnc
+// remoteFilesList.add(" " + fileName); // sf@2004
+
+ fileName = " " + fileName;
+ int i = -1;
+ String t1 = fileName.toLowerCase();
+ for (int j = 0; j < remoteFilesList.size(); j++) {
+ String t = (String) remoteFilesList.get(j);
+ String t2 = t.toLowerCase();
+ if (t1.compareTo(t2) < 0) {
+ i = j;
+ break;
+ }
+ }
+ String f2 = fileName;
+ if (f2.length() < 24) {
+ for (int ik = f2.length(); ik < 24; ik++) {
+ f2 = f2 + " ";
+ }
+ }
+
+if (false) {
+System.out.println("fileName: " + f2);
+System.out.println("ftLastWriteTimeL: " + ftLastWriteTimeL);
+System.out.println("ftLastWriteTimeH: " + ftLastWriteTimeH);
+System.out.println("nFileSizeLow: " + nFileSizeLow);
+}
+
+ String s = f2 + " \tLastmod: " + timeStr(ftLastWriteTimeL, ftLastWriteTimeH) + " \t\tSize: " + sizeStr(nFileSizeLow);
+ //s = fileName + " Lastmod: " + ftLastWriteTimeL + "/" + zogswap(ftLastWriteTimeL) + " Size: " + nFileSizeLow + "/" + zogswap(nFileSizeLow);
+ if (i >= 0) {
+ remoteFilesList.add(i, fileName);
+ remoteFilesListInfo.add(i, s);
+ } else {
+ remoteFilesList.add(fileName);
+ remoteFilesListInfo.add(s);
+ }
+// end runge/x11vnc
}
// a.add(fileName);
@@ -1282,14 +1618,32 @@
// sf@2004
a.clear();
- for (int i = 0; i < remoteDirsList.size(); i++)
+ b.clear();
+ for (int i = 0; i < remoteDirsList.size(); i++) {
a.add(remoteDirsList.get(i));
- for (int i = 0; i < remoteFilesList.size(); i++)
+ b.add(remoteDirsListInfo.get(i));
+ }
+ for (int i = 0; i < remoteFilesList.size(); i++) {
a.add(remoteFilesList.get(i));
+
+ b.add(remoteFilesListInfo.get(i));
+ }
remoteDirsList.clear();
+ remoteDirsListInfo.clear();
remoteFilesList.clear();
+ remoteFilesListInfo.clear();
- viewer.ftp.printDirectory(a);
+// begin runge/x11vnc
+ // Hack for double listing at startup... probably libvncserver bug..
+ readServerDriveListCnt++;
+ if (readServerDriveListCnt == 2) {
+ if (System.currentTimeMillis() - readServerDriveListTime < 2000) {
+//System.out.println("readServerDriveListCnt skip " + readServerDriveListCnt);
+ return;
+ }
+ }
+// end runge/x11vnc
+ viewer.ftp.printDirectory(a, b);
}
//Internally used to signify the drive requested is not ready
@@ -1299,6 +1653,8 @@
System.out.println("Remote Drive unavailable");
viewer.ftp.connectionStatus.setText(" > WARNING - Remote Drive unavailable (possibly restricted access or media not present)");
viewer.ftp.remoteStatus.setText("WARNING: Remote Drive unavailable");
+ viewer.ftp.historyComboBox.insertItemAt(new String(" > WARNING: Remote Drive unavailable."), 0);
+ viewer.ftp.historyComboBox.setSelectedIndex(0);
}
//Call this method to request the list of drives on the server.
@@ -1306,12 +1662,11 @@
{
try
{
- viewer.rfb.writeRfbFileTransferMsg(
- RfbProto.rfbDirContentRequest,
- RfbProto.rfbRDrivesList,
- 0,
- 0,
- null);
+ viewer.rfb.writeRfbFileTransferMsg(RfbProto.rfbDirContentRequest, RfbProto.rfbRDrivesList, 0, 0, null);
+// begin runge/x11vnc
+ readServerDriveListCnt = 0;
+ readServerDriveListTime = System.currentTimeMillis();
+// end runge/x11vnc
}
catch (IOException e)
{
@@ -1355,21 +1710,21 @@
int h,
boolean incremental)
throws IOException {
- if (!viewer.ftp.isVisible()) {
- byte[] b = new byte[10];
+ if (!viewer.ftp.isVisible()) {
+ byte[] b = new byte[10];
- b[0] = (byte) FramebufferUpdateRequest;
- b[1] = (byte) (incremental ? 1 : 0);
- b[2] = (byte) ((x >> 8) & 0xff);
- b[3] = (byte) (x & 0xff);
- b[4] = (byte) ((y >> 8) & 0xff);
- b[5] = (byte) (y & 0xff);
- b[6] = (byte) ((w >> 8) & 0xff);
- b[7] = (byte) (w & 0xff);
- b[8] = (byte) ((h >> 8) & 0xff);
- b[9] = (byte) (h & 0xff);
+ b[0] = (byte) FramebufferUpdateRequest;
+ b[1] = (byte) (incremental ? 1 : 0);
+ b[2] = (byte) ((x >> 8) & 0xff);
+ b[3] = (byte) (x & 0xff);
+ b[4] = (byte) ((y >> 8) & 0xff);
+ b[5] = (byte) (y & 0xff);
+ b[6] = (byte) ((w >> 8) & 0xff);
+ b[7] = (byte) (w & 0xff);
+ b[8] = (byte) ((h >> 8) & 0xff);
+ b[9] = (byte) (h & 0xff);
- os.write(b);
+ os.write(b);
}
}
@@ -1482,7 +1837,13 @@
b[6] = (byte) ((text.length() >> 8) & 0xff);
b[7] = (byte) (text.length() & 0xff);
- System.arraycopy(text.getBytes(), 0, b, 8, text.length());
+ if (false && max_char(text) > 255) {
+ System.arraycopy(text.getBytes("UTF-8"), 0, b, 8, text.length());
+ } else if (max_char(text) > 127) {
+ System.arraycopy(text.getBytes("ISO-8859-1"), 0, b, 8, text.length());
+ } else {
+ System.arraycopy(text.getBytes(), 0, b, 8, text.length());
+ }
os.write(b);
// }
diff -Naur JavaViewer.orig/SSLSocketToMe.java JavaViewer/SSLSocketToMe.java
--- JavaViewer.orig/SSLSocketToMe.java 1969-12-31 19:00:00.000000000 -0500
+++ JavaViewer/SSLSocketToMe.java 2010-02-22 20:03:11.000000000 -0500
@@ -0,0 +1,1712 @@
+/*
+ * SSLSocketToMe.java: add SSL encryption to Java VNC Viewer.
+ *
+ * Copyright (c) 2006 Karl J. Runge <runge@karlrunge.com>
+ * All rights reserved.
+ *
+ * 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; 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.
+ *
+ */
+
+import java.net.*;
+import java.io.*;
+import javax.net.ssl.*;
+import java.util.*;
+
+import java.security.*;
+import java.security.cert.*;
+import java.security.spec.*;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateFactory;
+
+import java.awt.*;
+import java.awt.event.*;
+
+public class SSLSocketToMe {
+
+ /* basic member data: */
+ String host;
+ int port;
+ VncViewer viewer;
+ boolean debug = true;
+
+ /* sockets */
+ SSLSocket socket = null;
+ SSLSocketFactory factory;
+
+ /* fallback for Proxy connection */
+ boolean proxy_in_use = false;
+ boolean proxy_is_https = false;
+ boolean proxy_failure = false;
+ public DataInputStream is = null;
+ public OutputStream os = null;
+
+ String proxy_auth_string = null;
+ String proxy_dialog_host = null;
+ int proxy_dialog_port = 0;
+
+ Socket proxySock;
+ DataInputStream proxy_is;
+ OutputStream proxy_os;
+
+ /* trust contexts */
+ SSLContext trustloc_ctx;
+ SSLContext trustall_ctx;
+ SSLContext trusturl_ctx;
+ SSLContext trustone_ctx;
+
+ TrustManager[] trustAllCerts;
+ TrustManager[] trustUrlCert;
+ TrustManager[] trustOneCert;
+
+ boolean use_url_cert_for_auth = true;
+ boolean user_wants_to_see_cert = true;
+ boolean debug_certs = false;
+
+ /* cert(s) we retrieve from VNC server */
+ java.security.cert.Certificate[] trustallCerts = null;
+ java.security.cert.Certificate[] trusturlCerts = null;
+
+ byte[] hex2bytes(String s) {
+ byte[] bytes = new byte[s.length()/2];
+ for (int i=0; i<s.length()/2; i++) {
+ int j = 2*i;
+ try {
+ int val = Integer.parseInt(s.substring(j, j+2), 16);
+ if (val > 127) {
+ val -= 256;
+ }
+ Integer I = new Integer(val);
+ bytes[i] = Byte.decode(I.toString()).byteValue();
+
+ } catch (Exception e) {
+ ;
+ }
+ }
+ return bytes;
+ }
+
+ SSLSocketToMe(String h, int p, VncViewer v) throws Exception {
+ host = h;
+ port = p;
+ viewer = v;
+
+ debug_certs = v.debugCerts;
+
+ /* we will first try default factory for certification: */
+
+ factory = (SSLSocketFactory) SSLSocketFactory.getDefault();
+
+ dbg("SSL startup: " + host + " " + port);
+
+ /* create trust managers used if initial handshake fails: */
+
+ trustAllCerts = new TrustManager[] {
+ /*
+ * this one accepts everything.
+ */
+ new X509TrustManager() {
+ public java.security.cert.X509Certificate[]
+ getAcceptedIssuers() {
+ return null;
+ }
+ public void checkClientTrusted(
+ java.security.cert.X509Certificate[] certs,
+ String authType) {
+ /* empty */
+ }
+ public void checkServerTrusted(
+ java.security.cert.X509Certificate[] certs,
+ String authType) {
+ /* empty */
+ dbg("ALL: an untrusted connect to grab cert.");
+ }
+ }
+ };
+
+ trustUrlCert = new TrustManager[] {
+ /*
+ * this one accepts only the retrieved server cert
+ * by SSLSocket by this applet.
+ */
+ new X509TrustManager() {
+ public java.security.cert.X509Certificate[]
+ getAcceptedIssuers() {
+ return null;
+ }
+ public void checkClientTrusted(
+ java.security.cert.X509Certificate[] certs,
+ String authType) throws CertificateException {
+ throw new CertificateException("No Clients");
+ }
+ public void checkServerTrusted(
+ java.security.cert.X509Certificate[] certs,
+ String authType) throws CertificateException {
+ if (trusturlCerts == null) {
+ throw new CertificateException(
+ "No Trust url Certs array.");
+ }
+ if (trusturlCerts.length < 1) {
+ throw new CertificateException(
+ "No Trust url Certs.");
+ }
+ if (certs == null) {
+ throw new CertificateException(
+ "No this-certs array.");
+ }
+ if (certs.length < 1) {
+ throw new CertificateException(
+ "No this-certs Certs.");
+ }
+ if (certs.length != trusturlCerts.length) {
+ throw new CertificateException(
+ "certs.length != trusturlCerts.length " + certs.length + " " + trusturlCerts.length);
+ }
+ boolean ok = true;
+ for (int i = 0; i < certs.length; i++) {
+ if (! trusturlCerts[i].equals(certs[i])) {
+ ok = false;
+ dbg("URL: cert mismatch at i=" + i);
+ dbg("URL: cert mismatch cert" + certs[i]);
+ dbg("URL: cert mismatch url" + trusturlCerts[i]);
+ }
+ if (debug_certs) {
+ dbg("\n***********************************************");
+ dbg("URL: cert info at i=" + i);
+ dbg("URL: cert info cert" + certs[i]);
+ dbg("===============================================");
+ dbg("URL: cert info url" + trusturlCerts[i]);
+ dbg("***********************************************");
+ }
+ }
+ if (!ok) {
+ throw new CertificateException(
+ "Server Cert Chain != URL Cert Chain.");
+ }
+ dbg("URL: trusturlCerts[i] matches certs[i] i=0:" + (certs.length-1));
+ }
+ }
+ };
+ trustOneCert = new TrustManager[] {
+ /*
+ * this one accepts only the retrieved server cert
+ * by SSLSocket by this applet.
+ */
+ new X509TrustManager() {
+ public java.security.cert.X509Certificate[]
+ getAcceptedIssuers() {
+ return null;
+ }
+ public void checkClientTrusted(
+ java.security.cert.X509Certificate[] certs,
+ String authType) throws CertificateException {
+ throw new CertificateException("No Clients");
+ }
+ public void checkServerTrusted(
+ java.security.cert.X509Certificate[] certs,
+ String authType) throws CertificateException {
+ if (trustallCerts == null) {
+ throw new CertificateException(
+ "No Trust All Server Certs array.");
+ }
+ if (trustallCerts.length < 1) {
+ throw new CertificateException(
+ "No Trust All Server Certs.");
+ }
+ if (certs == null) {
+ throw new CertificateException(
+ "No this-certs array.");
+ }
+ if (certs.length < 1) {
+ throw new CertificateException(
+ "No this-certs Certs.");
+ }
+ if (certs.length != trustallCerts.length) {
+ throw new CertificateException(
+ "certs.length != trustallCerts.length " + certs.length + " " + trustallCerts.length);
+ }
+ boolean ok = true;
+ for (int i = 0; i < certs.length; i++) {
+ if (! trustallCerts[i].equals(certs[i])) {
+ ok = false;
+ dbg("ONE: cert mismatch at i=" + i);
+ dbg("ONE: cert mismatch cert" + certs[i]);
+ dbg("ONE: cert mismatch all" + trustallCerts[i]);
+ }
+ if (debug_certs) {
+ dbg("\n***********************************************");
+ dbg("ONE: cert info at i=" + i);
+ dbg("ONE: cert info cert" + certs[i]);
+ dbg("===============================================");
+ dbg("ONE: cert info all" + trustallCerts[i]);
+ dbg("***********************************************");
+ }
+ }
+ if (!ok) {
+ throw new CertificateException(
+ "Server Cert Chain != TRUSTALL Cert Chain.");
+ }
+ dbg("ONE: trustallCerts[i] matches certs[i] i=0:" + (certs.length-1));
+ }
+ }
+ };
+
+ /*
+ * They are used:
+ *
+ * 1) to retrieve the server cert in case of failure to
+ * display it to the user.
+ * 2) to subsequently connect to the server if user agrees.
+ */
+
+ KeyManager[] mykey = null;
+
+ if (viewer.oneTimeKey != null && viewer.oneTimeKey.equals("PROMPT")) {
+ ClientCertDialog d = new ClientCertDialog();
+ viewer.oneTimeKey = d.queryUser();
+ }
+
+ if (viewer.oneTimeKey != null && viewer.oneTimeKey.indexOf(",") > 0) {
+ int idx = viewer.oneTimeKey.indexOf(",");
+
+ String onetimekey = viewer.oneTimeKey.substring(0, idx);
+ byte[] key = hex2bytes(onetimekey);
+ String onetimecert = viewer.oneTimeKey.substring(idx+1);
+ byte[] cert = hex2bytes(onetimecert);
+
+ KeyFactory kf = KeyFactory.getInstance("RSA");
+ PKCS8EncodedKeySpec keysp = new PKCS8EncodedKeySpec ( key );
+ PrivateKey ff = kf.generatePrivate (keysp);
+ //dbg("ff " + ff);
+ String cert_str = new String(cert);
+
+ CertificateFactory cf = CertificateFactory.getInstance("X.509");
+ Collection c = cf.generateCertificates(new ByteArrayInputStream(cert));
+ Certificate[] certs = new Certificate[c.toArray().length];
+ if (c.size() == 1) {
+ Certificate tmpcert = cf.generateCertificate(new ByteArrayInputStream(cert));
+ //dbg("tmpcert" + tmpcert);
+ certs[0] = tmpcert;
+ } else {
+ certs = (Certificate[]) c.toArray();
+ }
+
+ KeyStore ks = KeyStore.getInstance("JKS");
+ ks.load(null, null);
+ ks.setKeyEntry("onetimekey", ff, "".toCharArray(), certs);
+ String da = KeyManagerFactory.getDefaultAlgorithm();
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance(da);
+ kmf.init(ks, "".toCharArray());
+
+ mykey = kmf.getKeyManagers();
+ }
+
+
+ /* trust loc certs: */
+ try {
+ trustloc_ctx = SSLContext.getInstance("SSL");
+ trustloc_ctx.init(mykey, null, new
+ java.security.SecureRandom());
+
+ } catch (Exception e) {
+ String msg = "SSL trustloc_ctx FAILED.";
+ dbg(msg);
+ throw new Exception(msg);
+ }
+
+ /* trust all certs: */
+ try {
+ trustall_ctx = SSLContext.getInstance("SSL");
+ trustall_ctx.init(mykey, trustAllCerts, new
+ java.security.SecureRandom());
+
+ } catch (Exception e) {
+ String msg = "SSL trustall_ctx FAILED.";
+ dbg(msg);
+ throw new Exception(msg);
+ }
+
+ /* trust url certs: */
+ try {
+ trusturl_ctx = SSLContext.getInstance("SSL");
+ trusturl_ctx.init(mykey, trustUrlCert, new
+ java.security.SecureRandom());
+
+ } catch (Exception e) {
+ String msg = "SSL trusturl_ctx FAILED.";
+ dbg(msg);
+ throw new Exception(msg);
+ }
+
+ /* trust the one cert from server: */
+ try {
+ trustone_ctx = SSLContext.getInstance("SSL");
+ trustone_ctx.init(mykey, trustOneCert, new
+ java.security.SecureRandom());
+
+ } catch (Exception e) {
+ String msg = "SSL trustone_ctx FAILED.";
+ dbg(msg);
+ throw new Exception(msg);
+ }
+ }
+
+ boolean browser_cert_match() {
+ String msg = "Browser URL accept previously accepted cert";
+
+ if (user_wants_to_see_cert) {
+ return false;
+ }
+
+ if (trustallCerts != null && trusturlCerts != null) {
+ if (trustallCerts.length == 1 && trusturlCerts.length == 1) {
+ if (trustallCerts[0].equals(trusturlCerts[0])) {
+ System.out.println(msg);
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public void check_for_proxy() {
+
+ boolean result = false;
+
+ trusturlCerts = null;
+ proxy_in_use = false;
+ if (viewer.ignoreProxy) {
+ return;
+ }
+
+ String ustr = "https://" + host + ":";
+ if (viewer.httpsPort != null) {
+ ustr += viewer.httpsPort;
+ } else {
+ ustr += port; // hmmm
+ }
+ ustr += viewer.urlPrefix + "/check.https.proxy.connection";
+ dbg("ustr is: " + ustr);
+
+
+ try {
+ URL url = new URL(ustr);
+ HttpsURLConnection https = (HttpsURLConnection)
+ url.openConnection();
+
+ https.setUseCaches(false);
+ https.setRequestMethod("GET");
+ https.setRequestProperty("Pragma", "No-Cache");
+ https.setRequestProperty("Proxy-Connection",
+ "Keep-Alive");
+ https.setDoInput(true);
+
+ https.connect();
+
+ trusturlCerts = https.getServerCertificates();
+ if (trusturlCerts == null) {
+ dbg("set trusturlCerts to null...");
+ } else {
+ dbg("set trusturlCerts to non-null");
+ }
+
+ if (https.usingProxy()) {
+ proxy_in_use = true;
+ proxy_is_https = true;
+ dbg("HTTPS proxy in use. There may be connection problems.");
+ }
+ Object output = https.getContent();
+ https.disconnect();
+ result = true;
+
+ } catch(Exception e) {
+ dbg("HttpsURLConnection: " + e.getMessage());
+ }
+
+ if (proxy_in_use) {
+ return;
+ }
+
+ ustr = "http://" + host + ":" + port;
+ ustr += viewer.urlPrefix + "/index.vnc";
+
+ try {
+ URL url = new URL(ustr);
+ HttpURLConnection http = (HttpURLConnection)
+ url.openConnection();
+
+ http.setUseCaches(false);
+ http.setRequestMethod("GET");
+ http.setRequestProperty("Pragma", "No-Cache");
+ http.setRequestProperty("Proxy-Connection",
+ "Keep-Alive");
+ http.setDoInput(true);
+
+ http.connect();
+
+ if (http.usingProxy()) {
+ proxy_in_use = true;
+ proxy_is_https = false;
+ dbg("HTTP proxy in use. There may be connection problems.");
+ }
+ Object output = http.getContent();
+ http.disconnect();
+
+ } catch(Exception e) {
+ dbg("HttpURLConnection: " + e.getMessage());
+ }
+ }
+
+ public Socket connectSock() throws IOException {
+
+ /*
+ * first try a https connection to detect a proxy, and
+ * also grab the VNC server cert.
+ */
+ check_for_proxy();
+
+ if (viewer.trustAllVncCerts) {
+ dbg("viewer.trustAllVncCerts-0 using trustall_ctx");
+ factory = trustall_ctx.getSocketFactory();
+ } else if (use_url_cert_for_auth && trusturlCerts != null) {
+ dbg("using trusturl_ctx");
+ factory = trusturl_ctx.getSocketFactory();
+ } else {
+ dbg("using trustloc_ctx");
+ factory = trustloc_ctx.getSocketFactory();
+ }
+
+ socket = null;
+ try {
+ if (proxy_in_use && viewer.forceProxy) {
+ throw new Exception("forcing proxy (forceProxy)");
+ } else if (viewer.CONNECT != null) {
+ throw new Exception("forcing CONNECT");
+ }
+
+ int timeout = 6;
+ if (timeout > 0) {
+ socket = (SSLSocket) factory.createSocket();
+ InetSocketAddress inetaddr = new InetSocketAddress(host, port);
+ dbg("Using timeout of " + timeout + " secs to: " + host + ":" + port);
+ socket.connect(inetaddr, timeout * 1000);
+ } else {
+ socket = (SSLSocket) factory.createSocket(host, port);
+ }
+
+ } catch (Exception esock) {
+ dbg("esock: " + esock.getMessage());
+ if (proxy_in_use || viewer.CONNECT != null) {
+ proxy_failure = true;
+ if (proxy_in_use) {
+ dbg("HTTPS proxy in use. Trying to go with it.");
+ } else {
+ dbg("viewer.CONNECT reverse proxy in use. Trying to go with it.");
+ }
+ try {
+ socket = proxy_socket(factory);
+ } catch (Exception e) {
+ dbg("err proxy_socket: " + e.getMessage());
+ }
+ }
+ }
+
+ try {
+ socket.startHandshake();
+ dbg("Server Connection Verified on 1st try.");
+
+ java.security.cert.Certificate[] currentTrustedCerts;
+ BrowserCertsDialog bcd;
+
+ SSLSession sess = socket.getSession();
+ currentTrustedCerts = sess.getPeerCertificates();
+
+ if (viewer.trustAllVncCerts) {
+ dbg("viewer.trustAllVncCerts-1");
+ } else if (currentTrustedCerts == null || currentTrustedCerts.length < 1) {
+ socket.close();
+ socket = null;
+ throw new SSLHandshakeException("no current certs");
+ }
+
+ String serv = "";
+ try {
+ CertInfo ci = new CertInfo(currentTrustedCerts[0]);
+ serv = ci.get_certinfo("CN");
+ } catch (Exception e) {
+ ;
+ }
+
+ if (viewer.trustAllVncCerts) {
+ dbg("viewer.trustAllVncCerts-2");
+ user_wants_to_see_cert = false;
+ } else if (viewer.trustUrlVncCert) {
+ dbg("viewer.trustUrlVncCert-1");
+ user_wants_to_see_cert = false;
+ } else {
+ bcd = new BrowserCertsDialog(serv, host + ":" + port);
+ dbg("browser certs dialog START");
+ bcd.queryUser();
+ dbg("browser certs dialog DONE");
+ if (bcd.showCertDialog) {
+ String msg = "user wants to see cert";
+ dbg(msg);
+ user_wants_to_see_cert = true;
+ throw new SSLHandshakeException(msg);
+ } else {
+ user_wants_to_see_cert = false;
+ dbg("browser certs dialog: user said yes, accept it");
+ }
+ }
+
+ } catch (SSLHandshakeException eh) {
+ dbg("Could not automatically verify Server.");
+ dbg("msg: " + eh.getMessage());
+ String getoutstr = "GET /index.vnc HTTP/1.0\r\nConnection: close\r\n\r\n";
+
+ OutputStream os = socket.getOutputStream();
+ os.write(getoutstr.getBytes());
+ socket.close();
+ socket = null;
+
+ /*
+ * Reconnect, trusting any cert, so we can grab
+ * the cert to show it to the user. The connection
+ * is not used for anything else.
+ */
+ factory = trustall_ctx.getSocketFactory();
+ if (proxy_failure) {
+ socket = proxy_socket(factory);
+ } else {
+ socket = (SSLSocket) factory.createSocket(host, port);
+ }
+
+ try {
+ socket.startHandshake();
+ dbg("TrustAll Server Connection Verified.");
+
+ /* grab the cert: */
+ try {
+ SSLSession sess = socket.getSession();
+ trustallCerts = sess.getPeerCertificates();
+ } catch (Exception e) {
+ throw new Exception("Could not get " +
+ "Peer Certificate");
+ }
+
+ if (viewer.trustAllVncCerts) {
+ dbg("viewer.trustAllVncCerts-3");
+ } else if (! browser_cert_match()) {
+ /*
+ * close socket now, we will reopen after
+ * dialog if user agrees to use the cert.
+ */
+ os = socket.getOutputStream();
+ os.write(getoutstr.getBytes());
+ socket.close();
+ socket = null;
+
+ /* dialog with user to accept cert or not: */
+
+ TrustDialog td= new TrustDialog(host, port,
+ trustallCerts);
+
+ if (! td.queryUser()) {
+ String msg = "User decided against it.";
+ dbg(msg);
+ throw new IOException(msg);
+ }
+ }
+
+ } catch (Exception ehand2) {
+ dbg("** Could not TrustAll Verify Server.");
+
+ throw new IOException(ehand2.getMessage());
+ }
+
+ if (socket != null) {
+ try {
+ socket.close();
+ } catch (Exception e) {
+ ;
+ }
+ socket = null;
+ }
+
+ /*
+ * Now connect a 3rd time, using the cert
+ * retrieved during connection 2 (that the user
+ * likely blindly agreed to).
+ */
+
+ factory = trustone_ctx.getSocketFactory();
+ if (proxy_failure) {
+ socket = proxy_socket(factory);
+ } else {
+ socket = (SSLSocket) factory.createSocket(host, port);
+ }
+
+ try {
+ socket.startHandshake();
+ dbg("TrustAll Server Connection Verified #3.");
+
+ } catch (Exception ehand3) {
+ dbg("** Could not TrustAll Verify Server #3.");
+
+ throw new IOException(ehand3.getMessage());
+ }
+ }
+
+ if (socket != null && viewer.GET) {
+ String str = "GET ";
+ str += viewer.urlPrefix;
+ str += "/request.https.vnc.connection";
+ str += " HTTP/1.0\r\n";
+ str += "Pragma: No-Cache\r\n";
+ str += "\r\n";
+ System.out.println("sending GET: " + str);
+ OutputStream os = socket.getOutputStream();
+ String type = "os";
+ if (type == "os") {
+ os.write(str.getBytes());
+ os.flush();
+ System.out.println("used OutputStream");
+ } else if (type == "bs") {
+ BufferedOutputStream bs = new BufferedOutputStream(os);
+ bs.write(str.getBytes());
+ bs.flush();
+ System.out.println("used BufferedOutputStream");
+ } else if (type == "ds") {
+ DataOutputStream ds = new DataOutputStream(os);
+ ds.write(str.getBytes());
+ ds.flush();
+ System.out.println("used DataOutputStream");
+ }
+ if (false) {
+ String rep = "";
+ DataInputStream is = new DataInputStream(
+ new BufferedInputStream(socket.getInputStream(), 16384));
+ while (true) {
+ rep += readline(is);
+ if (rep.indexOf("\r\n\r\n") >= 0) {
+ break;
+ }
+ }
+ System.out.println("rep: " + rep);
+ }
+ }
+
+ dbg("SSL returning socket to caller.");
+ return (Socket) socket;
+ }
+
+ private void dbg(String s) {
+ if (debug) {
+ System.out.println(s);
+ }
+ }
+
+ private int gint(String s) {
+ int n = -1;
+ try {
+ Integer I = new Integer(s);
+ n = I.intValue();
+ } catch (Exception ex) {
+ return -1;
+ }
+ return n;
+ }
+
+ private void proxy_helper(String proxyHost, int proxyPort) {
+
+ boolean proxy_auth = false;
+ String proxy_auth_basic_realm = "";
+ String hp = host + ":" + port;
+ dbg("proxy_helper: " + proxyHost + ":" + proxyPort + " hp: " + hp);
+
+ for (int k=0; k < 2; k++) {
+ dbg("proxy_in_use psocket:");
+
+ if (proxySock != null) {
+ try {
+ proxySock.close();
+ } catch (Exception e) {
+ ;
+ }
+ }
+
+ proxySock = psocket(proxyHost, proxyPort);
+ if (proxySock == null) {
+ dbg("1-a sadly, returning a null socket");
+ return;
+ }
+
+ String req1 = "CONNECT " + hp + " HTTP/1.1\r\n"
+ + "Host: " + hp + "\r\n";
+
+ dbg("requesting: " + req1);
+
+ if (proxy_auth) {
+ if (proxy_auth_string == null) {
+ ProxyPasswdDialog pp = new ProxyPasswdDialog(proxyHost, proxyPort, proxy_auth_basic_realm);
+ pp.queryUser();
+ proxy_auth_string = pp.getAuth();
+ }
+ //dbg("auth1: " + proxy_auth_string);
+ String auth2 = Base64Coder.encodeString(proxy_auth_string);
+ //dbg("auth2: " + auth2);
+ req1 += "Proxy-Authorization: Basic " + auth2 + "\r\n";
+ //dbg("req1: " + req1);
+ dbg("added Proxy-Authorization: Basic ... to request");
+ }
+ req1 += "\r\n";
+
+ try {
+ proxy_os.write(req1.getBytes());
+ String reply = readline(proxy_is);
+
+ dbg("proxy replied: " + reply.trim());
+
+ if (reply.indexOf("HTTP/1.") == 0 && reply.indexOf(" 407 ") > 0) {
+ proxy_auth = true;
+ proxySock.close();
+ } else if (reply.indexOf("HTTP/1.") < 0 && reply.indexOf(" 200") < 0) {
+ proxySock.close();
+ proxySock = psocket(proxyHost, proxyPort);
+ if (proxySock == null) {
+ dbg("2-a sadly, returning a null socket");
+ return;
+ }
+ }
+ } catch(Exception e) {
+ dbg("sock prob: " + e.getMessage());
+ }
+
+ while (true) {
+ String line = readline(proxy_is);
+ dbg("proxy line: " + line.trim());
+ if (proxy_auth) {
+ String uc = line.toLowerCase();
+ if (uc.indexOf("proxy-authenticate:") == 0) {
+ if (uc.indexOf(" basic ") >= 0) {
+ int idx = uc.indexOf(" realm");
+ if (idx >= 0) {
+ proxy_auth_basic_realm = uc.substring(idx+1);
+ }
+ }
+ }
+ }
+ if (line.equals("\r\n") || line.equals("\n")) {
+ break;
+ }
+ }
+ if (!proxy_auth || proxy_auth_basic_realm.equals("")) {
+ break;
+ }
+ }
+ }
+
+ public SSLSocket proxy_socket(SSLSocketFactory factory) {
+ Properties props = null;
+ String proxyHost = null;
+ int proxyPort = 0;
+ String proxyHost_nossl = null;
+ int proxyPort_nossl = 0;
+ String str;
+
+ /* see if we can guess the proxy info from Properties: */
+ try {
+ props = System.getProperties();
+ } catch (Exception e) {
+ dbg("props failed: " + e.getMessage());
+ }
+ if (viewer.proxyHost != null) {
+ dbg("Using supplied proxy " + viewer.proxyHost + " " + viewer.proxyPort + " applet parameters.");
+ proxyHost = viewer.proxyHost;
+ if (viewer.proxyPort != null) {
+ proxyPort = gint(viewer.proxyPort);
+ } else {
+ proxyPort = 8080;
+ }
+
+ } else if (props != null) {
+ dbg("\n---------------\nAll props:");
+ props.list(System.out);
+ dbg("\n---------------\n\n");
+
+ for (Enumeration e = props.propertyNames(); e.hasMoreElements(); ) {
+ String s = (String) e.nextElement();
+ String v = System.getProperty(s);
+ String s2 = s.toLowerCase();
+ String v2 = v.toLowerCase();
+
+ if (s2.indexOf("proxy") < 0 && v2.indexOf("proxy") < 0) {
+ continue;
+ }
+ if (v2.indexOf("http") < 0) {
+ continue;
+ }
+
+ if (s2.indexOf("proxy.https.host") >= 0) {
+ proxyHost = v2;
+ continue;
+ }
+ if (s2.indexOf("proxy.https.port") >= 0) {
+ proxyPort = gint(v2);
+ continue;
+ }
+ if (s2.indexOf("proxy.http.host") >= 0) {
+ proxyHost_nossl = v2;
+ continue;
+ }
+ if (s2.indexOf("proxy.http.port") >= 0) {
+ proxyPort_nossl = gint(v2);
+ continue;
+ }
+
+ String[] pieces = v.split("[,;]");
+ for (int i = 0; i < pieces.length; i++) {
+ String p = pieces[i];
+ int j = p.indexOf("https");
+ if (j < 0) {
+ j = p.indexOf("http");
+ if (j < 0) {
+ continue;
+ }
+ }
+ j = p.indexOf("=", j);
+ if (j < 0) {
+ continue;
+ }
+ p = p.substring(j+1);
+ String [] hp = p.split(":");
+ if (hp.length != 2) {
+ continue;
+ }
+ if (hp[0].length() > 1 && hp[1].length() > 1) {
+
+ proxyPort = gint(hp[1]);
+ if (proxyPort < 0) {
+ continue;
+ }
+ proxyHost = new String(hp[0]);
+ break;
+ }
+ }
+ }
+ }
+ if (proxyHost != null) {
+ if (proxyHost_nossl != null && proxyPort_nossl > 0) {
+ dbg("Using http proxy info instead of https.");
+ proxyHost = proxyHost_nossl;
+ proxyPort = proxyPort_nossl;
+ }
+ }
+
+ if (proxy_in_use) {
+ if (proxy_dialog_host != null && proxy_dialog_port > 0) {
+ proxyHost = proxy_dialog_host;
+ proxyPort = proxy_dialog_port;
+ }
+ if (proxyHost != null) {
+ dbg("Lucky us! we figured out the Proxy parameters: " + proxyHost + " " + proxyPort);
+ } else {
+ /* ask user to help us: */
+ ProxyDialog pd = new ProxyDialog(proxyHost, proxyPort);
+ pd.queryUser();
+ proxyHost = pd.getHost();
+ proxyPort = pd.getPort();
+ proxy_dialog_host = new String(proxyHost);
+ proxy_dialog_port = proxyPort;
+ dbg("User said host: " + pd.getHost() + " port: " + pd.getPort());
+ }
+
+ proxy_helper(proxyHost, proxyPort);
+ if (proxySock == null) {
+ return null;
+ }
+ } else if (viewer.CONNECT != null) {
+ dbg("viewer.CONNECT psocket:");
+ proxySock = psocket(host, port);
+ if (proxySock == null) {
+ dbg("1-b sadly, returning a null socket");
+ return null;
+ }
+ }
+
+ if (viewer.CONNECT != null) {
+ String hp = viewer.CONNECT;
+ String req2 = "CONNECT " + hp + " HTTP/1.1\r\n"
+ + "Host: " + hp + "\r\n\r\n";
+
+ dbg("requesting2: " + req2);
+
+ try {
+ proxy_os.write(req2.getBytes());
+ String reply = readline(proxy_is);
+
+ dbg("proxy replied2: " + reply.trim());
+
+ if (reply.indexOf("HTTP/1.") < 0 && reply.indexOf(" 200") < 0) {
+ proxySock.close();
+ proxySock = psocket(proxyHost, proxyPort);
+ if (proxySock == null) {
+ dbg("2-b sadly, returning a null socket");
+ return null;
+ }
+ }
+ } catch(Exception e) {
+ dbg("sock prob2: " + e.getMessage());
+ }
+
+ while (true) {
+ String line = readline(proxy_is);
+ dbg("proxy line2: " + line.trim());
+ if (line.equals("\r\n") || line.equals("\n")) {
+ break;
+ }
+ }
+ }
+
+ Socket sslsock = null;
+ try {
+ sslsock = factory.createSocket(proxySock, host, port, true);
+ } catch(Exception e) {
+ dbg("sslsock prob: " + e.getMessage());
+ dbg("3 sadly, returning a null socket");
+ }
+
+ return (SSLSocket) sslsock;
+ }
+
+ Socket psocket(String h, int p) {
+ Socket psock = null;
+ try {
+ psock = new Socket(h, p);
+ proxy_is = new DataInputStream(new BufferedInputStream(
+ psock.getInputStream(), 16384));
+ proxy_os = psock.getOutputStream();
+ } catch(Exception e) {
+ dbg("psocket prob: " + e.getMessage());
+ return null;
+ }
+
+ return psock;
+ }
+
+ String readline(DataInputStream i) {
+ byte[] ba = new byte[1];
+ String s = new String("");
+ ba[0] = 0;
+ try {
+ while (ba[0] != 0xa) {
+ ba[0] = (byte) i.readUnsignedByte();
+ s += new String(ba);
+ }
+ } catch (Exception e) {
+ ;
+ }
+ return s;
+ }
+}
+
+class TrustDialog implements ActionListener {
+ String msg, host, text;
+ int port;
+ java.security.cert.Certificate[] trustallCerts = null;
+ boolean viewing_cert = false;
+ boolean trust_this_session = false;
+
+ /*
+ * this is the gui to show the user the cert and info and ask
+ * them if they want to continue using this cert.
+ */
+
+ Button ok, cancel, viewcert;
+ TextArea textarea;
+ Checkbox accept, deny;
+ Dialog dialog;
+
+ String s1 = "Accept this certificate temporarily for this session";
+ String s2 = "Do not accept this certificate and do not connect to"
+ + " this VNC server";
+ String ln = "\n---------------------------------------------------\n\n";
+
+ TrustDialog (String h, int p, java.security.cert.Certificate[] s) {
+ host = h;
+ port = p;
+ trustallCerts = s;
+
+ msg = "VNC Server " + host + ":" + port + " Not Verified";
+ }
+
+ public boolean queryUser() {
+
+ /* create and display the dialog for unverified cert. */
+
+ Frame frame = new Frame(msg);
+
+ dialog = new Dialog(frame, true);
+
+ String infostr = "";
+ if (trustallCerts.length == 1) {
+ CertInfo ci = new CertInfo(trustallCerts[0]);
+ infostr = ci.get_certinfo("all");
+ }
+
+ text = "\n"
++ "Unable to verify the identity of\n"
++ "\n"
++ " " + host + ":" + port + "\n"
++ "\n"
++ infostr
++ "\n"
++ "as a trusted VNC server.\n"
++ "\n"
++ "This may be due to:\n"
++ "\n"
++ " - Your requesting to View the Certificate before accepting.\n"
++ "\n"
++ " - The VNC server using a Self-Signed Certificate.\n"
++ "\n"
++ " - The VNC server using a Certificate Authority not recognized by your\n"
++ " Browser or Java Plugin runtime.\n"
++ "\n"
++ " - The use of an Apache SSL portal employing CONNECT proxying and the\n"
++ " Apache web server has a certificate different from the VNC server's. \n"
++ "\n"
++ " - A Man-In-The-Middle attack impersonating as the VNC server you wish\n"
++ " to connect to. (Wouldn't that be exciting!!)\n"
++ "\n"
++ "By safely copying the VNC server's Certificate (or using a common\n"
++ "Certificate Authority certificate) you can configure your Web Browser or\n"
++ "Java Plugin to automatically authenticate this Server.\n"
++ "\n"
++ "If you do so, then you will only have to click \"Yes\" when this VNC\n"
++ "Viewer applet asks you whether to trust your Browser/Java Plugin's\n"
++ "acceptance of the certificate. (except for the Apache portal case above.)\n"
+;
+
+ /* the accept / do-not-accept radio buttons: */
+ CheckboxGroup checkbox = new CheckboxGroup();
+ accept = new Checkbox(s1, true, checkbox);
+ deny = new Checkbox(s2, false, checkbox);
+
+ /* put the checkboxes in a panel: */
+ Panel check = new Panel();
+ check.setLayout(new GridLayout(2, 1));
+
+ check.add(accept);
+ check.add(deny);
+
+ /* make the 3 buttons: */
+ ok = new Button("OK");
+ cancel = new Button("Cancel");
+ viewcert = new Button("View Certificate");
+
+ ok.addActionListener(this);
+ cancel.addActionListener(this);
+ viewcert.addActionListener(this);
+
+ /* put the buttons in their own panel: */
+ Panel buttonrow = new Panel();
+ buttonrow.setLayout(new FlowLayout(FlowLayout.LEFT));
+ buttonrow.add(viewcert);
+ buttonrow.add(ok);
+ buttonrow.add(cancel);
+
+ /* label at the top: */
+ Label label = new Label(msg, Label.CENTER);
+ label.setFont(new Font("Helvetica", Font.BOLD, 16));
+
+ /* textarea in the middle */
+ textarea = new TextArea(text, 36, 64,
+ TextArea.SCROLLBARS_VERTICAL_ONLY);
+ textarea.setEditable(false);
+
+ /* put the two panels in their own panel at bottom: */
+ Panel bot = new Panel();
+ bot.setLayout(new GridLayout(2, 1));
+ bot.add(check);
+ bot.add(buttonrow);
+
+ /* now arrange things inside the dialog: */
+ dialog.setLayout(new BorderLayout());
+
+ dialog.add("North", label);
+ dialog.add("South", bot);
+ dialog.add("Center", textarea);
+
+ dialog.pack();
+ dialog.resize(dialog.preferredSize());
+
+ dialog.show(); /* block here til OK or Cancel pressed. */
+
+ return trust_this_session;
+ }
+
+ public synchronized void actionPerformed(ActionEvent evt) {
+
+ if (evt.getSource() == viewcert) {
+ /* View Certificate button clicked */
+ if (viewing_cert) {
+ /* show the original info text: */
+ textarea.setText(text);
+ viewcert.setLabel("View Certificate");
+ viewing_cert = false;
+ } else {
+ int i;
+ /* show all (likely just one) certs: */
+ textarea.setText("");
+ for (i=0; i < trustallCerts.length; i++) {
+ int j = i + 1;
+ textarea.append("Certificate[" +
+ j + "]\n\n");
+ textarea.append(
+ trustallCerts[i].toString());
+ textarea.append(ln);
+ }
+ viewcert.setLabel("View Info");
+ viewing_cert = true;
+
+ textarea.setCaretPosition(0);
+ }
+
+ } else if (evt.getSource() == ok) {
+ /* OK button clicked */
+ if (accept.getState()) {
+ trust_this_session = true;
+ } else {
+ trust_this_session = false;
+ }
+ //dialog.dispose();
+ dialog.hide();
+
+ } else if (evt.getSource() == cancel) {
+ /* Cancel button clicked */
+ trust_this_session = false;
+
+ //dialog.dispose();
+ dialog.hide();
+ }
+ }
+
+ String get_certinfo() {
+ String all = "";
+ String fields[] = {"CN", "OU", "O", "L", "C"};
+ int i;
+ if (trustallCerts.length < 1) {
+ all = "";
+ return all;
+ }
+ String cert = trustallCerts[0].toString();
+
+ /*
+ * For now we simply scrape the cert string, there must
+ * be an API for this... perhaps optionValue?
+ */
+
+ for (i=0; i < fields.length; i++) {
+ int f, t, t1, t2;
+ String sub, mat = fields[i] + "=";
+
+ f = cert.indexOf(mat, 0);
+ if (f > 0) {
+ t1 = cert.indexOf(", ", f);
+ t2 = cert.indexOf("\n", f);
+ if (t1 < 0 && t2 < 0) {
+ continue;
+ } else if (t1 < 0) {
+ t = t2;
+ } else if (t2 < 0) {
+ t = t1;
+ } else if (t1 < t2) {
+ t = t1;
+ } else {
+ t = t2;
+ }
+ if (t > f) {
+ sub = cert.substring(f, t);
+ all = all + " " + sub + "\n";
+ }
+ }
+ }
+ return all;
+ }
+}
+
+class ProxyDialog implements ActionListener {
+ String guessedHost = null;
+ String guessedPort = null;
+ /*
+ * this is the gui to show the user the cert and info and ask
+ * them if they want to continue using this cert.
+ */
+
+ Button ok;
+ Dialog dialog;
+ TextField entry;
+ String reply = "";
+
+ ProxyDialog (String h, int p) {
+ guessedHost = h;
+ try {
+ guessedPort = Integer.toString(p);
+ } catch (Exception e) {
+ guessedPort = "8080";
+ }
+ }
+
+ public void queryUser() {
+
+ /* create and display the dialog for unverified cert. */
+
+ Frame frame = new Frame("Need Proxy host:port");
+
+ dialog = new Dialog(frame, true);
+
+
+ Label label = new Label("Please Enter your https Proxy info as host:port", Label.CENTER);
+ //label.setFont(new Font("Helvetica", Font.BOLD, 16));
+ entry = new TextField(30);
+ ok = new Button("OK");
+ ok.addActionListener(this);
+
+ String guess = "";
+ if (guessedHost != null) {
+ guess = guessedHost + ":" + guessedPort;
+ }
+ entry.setText(guess);
+
+ dialog.setLayout(new BorderLayout());
+ dialog.add("North", label);
+ dialog.add("Center", entry);
+ dialog.add("South", ok);
+ dialog.pack();
+ dialog.resize(dialog.preferredSize());
+
+ dialog.show(); /* block here til OK or Cancel pressed. */
+ return;
+ }
+
+ public String getHost() {
+ int i = reply.indexOf(":");
+ if (i < 0) {
+ return "unknown";
+ }
+ String h = reply.substring(0, i);
+ return h;
+ }
+
+ public int getPort() {
+ int i = reply.indexOf(":");
+ int p = 8080;
+ if (i < 0) {
+ return p;
+ }
+ i++;
+ String ps = reply.substring(i);
+ try {
+ Integer I = new Integer(ps);
+ p = I.intValue();
+ } catch (Exception e) {
+ ;
+ }
+ return p;
+ }
+
+ public synchronized void actionPerformed(ActionEvent evt) {
+ System.out.println(evt.getActionCommand());
+ if (evt.getSource() == ok) {
+ reply = entry.getText();
+ //dialog.dispose();
+ dialog.hide();
+ }
+ }
+}
+
+class ProxyPasswdDialog implements ActionListener {
+ String guessedHost = null;
+ String guessedPort = null;
+ String guessedUser = null;
+ String guessedPasswd = null;
+ String realm = null;
+ /*
+ * this is the gui to show the user the cert and info and ask
+ * them if they want to continue using this cert.
+ */
+
+ Button ok;
+ Dialog dialog;
+ TextField entry1;
+ TextField entry2;
+ String reply1 = "";
+ String reply2 = "";
+
+ ProxyPasswdDialog (String h, int p, String realm) {
+ guessedHost = h;
+ try {
+ guessedPort = Integer.toString(p);
+ } catch (Exception e) {
+ guessedPort = "8080";
+ }
+ this.realm = realm;
+ }
+
+ public void queryUser() {
+
+ /* create and display the dialog for unverified cert. */
+
+ Frame frame = new Frame("Proxy Requires Username and Password");
+
+ dialog = new Dialog(frame, true);
+
+ //Label label = new Label("Please Enter your Web Proxy Username in the top Entry and Password in the bottom Entry", Label.CENTER);
+ TextArea label = new TextArea("Please Enter your Web Proxy\nUsername in the Top Entry and\nPassword in the Bottom Entry,\nand then press OK.", 4, 20, TextArea.SCROLLBARS_NONE);
+ entry1 = new TextField(30);
+ entry2 = new TextField(30);
+ entry2.setEchoChar('*');
+ ok = new Button("OK");
+ ok.addActionListener(this);
+
+ dialog.setLayout(new BorderLayout());
+ dialog.add("North", label);
+ dialog.add("Center", entry1);
+ dialog.add("South", entry2);
+ dialog.add("East", ok);
+ dialog.pack();
+ dialog.resize(dialog.preferredSize());
+
+ dialog.show(); /* block here til OK or Cancel pressed. */
+ return;
+ }
+
+ public String getAuth() {
+ return reply1 + ":" + reply2;
+ }
+
+ public synchronized void actionPerformed(ActionEvent evt) {
+ System.out.println(evt.getActionCommand());
+ if (evt.getSource() == ok) {
+ reply1 = entry1.getText();
+ reply2 = entry2.getText();
+ //dialog.dispose();
+ dialog.hide();
+ }
+ }
+}
+
+class ClientCertDialog implements ActionListener {
+
+ Button ok;
+ Dialog dialog;
+ TextField entry;
+ String reply = "";
+
+ ClientCertDialog() {
+ ;
+ }
+
+ public String queryUser() {
+
+ /* create and display the dialog for unverified cert. */
+
+ Frame frame = new Frame("Enter SSL Client Cert+Key String");
+
+ dialog = new Dialog(frame, true);
+
+
+ Label label = new Label("Please Enter the SSL Client Cert+Key String 308204c0...,...522d2d0a", Label.CENTER);
+ entry = new TextField(30);
+ ok = new Button("OK");
+ ok.addActionListener(this);
+
+ dialog.setLayout(new BorderLayout());
+ dialog.add("North", label);
+ dialog.add("Center", entry);
+ dialog.add("South", ok);
+ dialog.pack();
+ dialog.resize(dialog.preferredSize());
+
+ dialog.show(); /* block here til OK or Cancel pressed. */
+ return reply;
+ }
+
+ public synchronized void actionPerformed(ActionEvent evt) {
+ System.out.println(evt.getActionCommand());
+ if (evt.getSource() == ok) {
+ reply = entry.getText();
+ //dialog.dispose();
+ dialog.hide();
+ }
+ }
+}
+
+class BrowserCertsDialog implements ActionListener {
+ Button yes, no;
+ Dialog dialog;
+ String vncServer;
+ String hostport;
+ public boolean showCertDialog = true;
+
+ BrowserCertsDialog(String serv, String hp) {
+ vncServer = serv;
+ hostport = hp;
+ }
+
+ public void queryUser() {
+
+ /* create and display the dialog for unverified cert. */
+
+ Frame frame = new Frame("Use Browser/JVM Certs?");
+
+ dialog = new Dialog(frame, true);
+
+ String m = "";
+m += "\n";
+m += "This VNC Viewer applet does not have its own keystore to track\n";
+m += "SSL certificates, and so cannot authenticate the certificate\n";
+m += "of the VNC Server:\n";
+m += "\n";
+m += " " + hostport + "\n\n " + vncServer + "\n";
+m += "\n";
+m += "on its own.\n";
+m += "\n";
+m += "However, it has noticed that your Web Browser or Java VM Plugin\n";
+m += "has previously accepted the same certificate. You may have set\n";
+m += "this up permanently or just for this session, or the server\n";
+m += "certificate was signed by a CA cert that your Web Browser or\n";
+m += "Java VM Plugin has.\n";
+m += "\n";
+m += "Should this VNC Viewer applet now connect to the above VNC server?\n";
+m += "\n";
+
+// String m = "\nShould this VNC Viewer applet use your Browser/JVM certs to\n";
+// m += "authenticate the VNC Server:\n";
+// m += "\n " + hostport + "\n\n " + vncServer + "\n\n";
+// m += "(NOTE: this *includes* any certs you have Just Now accepted in a\n";
+// m += "dialog box with your Web Browser or Java Applet Plugin)\n\n";
+
+ TextArea textarea = new TextArea(m, 20, 64,
+ TextArea.SCROLLBARS_VERTICAL_ONLY);
+ textarea.setEditable(false);
+ yes = new Button("Yes");
+ yes.addActionListener(this);
+ no = new Button("No, Let Me See the Certificate.");
+ no.addActionListener(this);
+
+ dialog.setLayout(new BorderLayout());
+ dialog.add("North", textarea);
+ dialog.add("Center", yes);
+ dialog.add("South", no);
+ dialog.pack();
+ dialog.resize(dialog.preferredSize());
+
+ dialog.show(); /* block here til Yes or No pressed. */
+ System.out.println("done show()");
+ return;
+ }
+
+ public synchronized void actionPerformed(ActionEvent evt) {
+ System.out.println(evt.getActionCommand());
+ if (evt.getSource() == yes) {
+ showCertDialog = false;
+ //dialog.dispose();
+ dialog.hide();
+ } else if (evt.getSource() == no) {
+ showCertDialog = true;
+ //dialog.dispose();
+ dialog.hide();
+ }
+ System.out.println("done actionPerformed()");
+ }
+}
+
+class CertInfo {
+ String fields[] = {"CN", "OU", "O", "L", "C"};
+ java.security.cert.Certificate cert;
+ String certString = "";
+
+ CertInfo(java.security.cert.Certificate c) {
+ cert = c;
+ certString = cert.toString();
+ }
+
+ String get_certinfo(String which) {
+ int i;
+ String cs = new String(certString);
+ String all = "";
+
+ /*
+ * For now we simply scrape the cert string, there must
+ * be an API for this... perhaps optionValue?
+ */
+ for (i=0; i < fields.length; i++) {
+ int f, t, t1, t2;
+ String sub, mat = fields[i] + "=";
+
+ f = cs.indexOf(mat, 0);
+ if (f > 0) {
+ t1 = cs.indexOf(", ", f);
+ t2 = cs.indexOf("\n", f);
+ if (t1 < 0 && t2 < 0) {
+ continue;
+ } else if (t1 < 0) {
+ t = t2;
+ } else if (t2 < 0) {
+ t = t1;
+ } else if (t1 < t2) {
+ t = t1;
+ } else {
+ t = t2;
+ }
+ if (t > f) {
+ sub = cs.substring(f, t);
+ all = all + " " + sub + "\n";
+ if (which.equals(fields[i])) {
+ return sub;
+ }
+ }
+ }
+ }
+ if (which.equals("all")) {
+ return all;
+ } else {
+ return "";
+ }
+ }
+}
+
+class Base64Coder {
+
+ // Mapping table from 6-bit nibbles to Base64 characters.
+ private static char[] map1 = new char[64];
+ static {
+ int i=0;
+ for (char c='A'; c<='Z'; c++) map1[i++] = c;
+ for (char c='a'; c<='z'; c++) map1[i++] = c;
+ for (char c='0'; c<='9'; c++) map1[i++] = c;
+ map1[i++] = '+'; map1[i++] = '/'; }
+
+ // Mapping table from Base64 characters to 6-bit nibbles.
+ private static byte[] map2 = new byte[128];
+ static {
+ for (int i=0; i<map2.length; i++) map2[i] = -1;
+ for (int i=0; i<64; i++) map2[map1[i]] = (byte)i; }
+
+ /**
+ * Encodes a string into Base64 format.
+ * No blanks or line breaks are inserted.
+ * @param s a String to be encoded.
+ * @return A String with the Base64 encoded data.
+ */
+ public static String encodeString (String s) {
+ return new String(encode(s.getBytes())); }
+
+ /**
+ * Encodes a byte array into Base64 format.
+ * No blanks or line breaks are inserted.
+ * @param in an array containing the data bytes to be encoded.
+ * @return A character array with the Base64 encoded data.
+ */
+ public static char[] encode (byte[] in) {
+ return encode(in,in.length); }
+
+ /**
+ * Encodes a byte array into Base64 format.
+ * No blanks or line breaks are inserted.
+ * @param in an array containing the data bytes to be encoded.
+ * @param iLen number of bytes to process in <code>in</code>.
+ * @return A character array with the Base64 encoded data.
+ */
+ public static char[] encode (byte[] in, int iLen) {
+ int oDataLen = (iLen*4+2)/3; // output length without padding
+ int oLen = ((iLen+2)/3)*4; // output length including padding
+ char[] out = new char[oLen];
+ int ip = 0;
+ int op = 0;
+ while (ip < iLen) {
+ int i0 = in[ip++] & 0xff;
+ int i1 = ip < iLen ? in[ip++] & 0xff : 0;
+ int i2 = ip < iLen ? in[ip++] & 0xff : 0;
+ int o0 = i0 >>> 2;
+ int o1 = ((i0 & 3) << 4) | (i1 >>> 4);
+ int o2 = ((i1 & 0xf) << 2) | (i2 >>> 6);
+ int o3 = i2 & 0x3F;
+ out[op++] = map1[o0];
+ out[op++] = map1[o1];
+ out[op] = op < oDataLen ? map1[o2] : '='; op++;
+ out[op] = op < oDataLen ? map1[o3] : '='; op++; }
+ return out; }
+
+ /**
+ * Decodes a string from Base64 format.
+ * @param s a Base64 String to be decoded.
+ * @return A String containing the decoded data.
+ * @throws IllegalArgumentException if the input is not valid Base64 encoded data.
+ */
+ public static String decodeString (String s) {
+ return new String(decode(s)); }
+
+ /**
+ * Decodes a byte array from Base64 format.
+ * @param s a Base64 String to be decoded.
+ * @return An array containing the decoded data bytes.
+ * @throws IllegalArgumentException if the input is not valid Base64 encoded data.
+ */
+ public static byte[] decode (String s) {
+ return decode(s.toCharArray()); }
+
+ /**
+ * Decodes a byte array from Base64 format.
+ * No blanks or line breaks are allowed within the Base64 encoded data.
+ * @param in a character array containing the Base64 encoded data.
+ * @return An array containing the decoded data bytes.
+ * @throws IllegalArgumentException if the input is not valid Base64 encoded data.
+ */
+ public static byte[] decode (char[] in) {
+ int iLen = in.length;
+ if (iLen%4 != 0) throw new IllegalArgumentException ("Length of Base64 encoded input string is not a multiple of 4.");
+ while (iLen > 0 && in[iLen-1] == '=') iLen--;
+ int oLen = (iLen*3) / 4;
+ byte[] out = new byte[oLen];
+ int ip = 0;
+ int op = 0;
+ while (ip < iLen) {
+ int i0 = in[ip++];
+ int i1 = in[ip++];
+ int i2 = ip < iLen ? in[ip++] : 'A';
+ int i3 = ip < iLen ? in[ip++] : 'A';
+ if (i0 > 127 || i1 > 127 || i2 > 127 || i3 > 127)
+ throw new IllegalArgumentException ("Illegal character in Base64 encoded data.");
+ int b0 = map2[i0];
+ int b1 = map2[i1];
+ int b2 = map2[i2];
+ int b3 = map2[i3];
+ if (b0 < 0 || b1 < 0 || b2 < 0 || b3 < 0)
+ throw new IllegalArgumentException ("Illegal character in Base64 encoded data.");
+ int o0 = ( b0 <<2) | (b1>>>4);
+ int o1 = ((b1 & 0xf)<<4) | (b2>>>2);
+ int o2 = ((b2 & 3)<<6) | b3;
+ out[op++] = (byte)o0;
+ if (op<oLen) out[op++] = (byte)o1;
+ if (op<oLen) out[op++] = (byte)o2; }
+ return out; }
+
+ // Dummy constructor.
+ private Base64Coder() {}
+
+}
diff -Naur JavaViewer.orig/VncCanvas.java JavaViewer/VncCanvas.java
--- JavaViewer.orig/VncCanvas.java 2005-11-21 18:50:18.000000000 -0500
+++ JavaViewer/VncCanvas.java 2007-05-31 15:33:20.000000000 -0400
@@ -27,6 +27,9 @@
import java.lang.*;
import java.util.zip.*;
+// begin runge/x11vnc
+import java.util.Collections;
+// end runge/x11vnc
//
// VncCanvas is a subclass of Canvas which draws a VNC desktop on it.
@@ -85,6 +88,22 @@
cm24 = new DirectColorModel(24, 0xFF0000, 0x00FF00, 0x0000FF);
+// begin runge/x11vnc
+// kludge to not show any Java cursor in the canvas since we are
+// showing the soft cursor (should be a user setting...)
+Cursor dot = Toolkit.getDefaultToolkit().createCustomCursor(
+ Toolkit.getDefaultToolkit().createImage(new byte[4]), new Point(0,0),
+ "dot");
+this.setCursor(dot);
+
+// while we are at it... get rid of the keyboard traversals that
+// make it so we can't type a Tab character:
+this.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
+ Collections.EMPTY_SET);
+this.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
+ Collections.EMPTY_SET);
+// end runge/x11vnc
+
colors = new Color[256];
// sf@2005 - Now Default
for (int i = 0; i < 256; i++)
@@ -202,6 +221,9 @@
public void setPixelFormat() throws IOException {
// sf@2005 - Adding more color modes
+ if (viewer.graftFtp) {
+ return;
+ }
if (viewer.options.eightBitColors > 0)
{
viewer.options.oldEightBitColors = viewer.options.eightBitColors;
@@ -237,6 +259,9 @@
}
else
{
+// begin runge/x11vnc
+ viewer.options.oldEightBitColors = viewer.options.eightBitColors;
+// end runge/x11vnc
rfb.writeSetPixelFormat(
32,
24,
@@ -376,12 +401,14 @@
// Start/stop session recording if necessary.
viewer.checkRecordingStatus();
- rfb.writeFramebufferUpdateRequest(
- 0,
- 0,
- rfb.framebufferWidth,
- rfb.framebufferHeight,
- false);
+ if (!viewer.graftFtp) {
+ rfb.writeFramebufferUpdateRequest(
+ 0,
+ 0,
+ rfb.framebufferWidth,
+ rfb.framebufferHeight,
+ false);
+ }
//
// main dispatch loop
@@ -390,6 +417,9 @@
while (true) {
// Read message type from the server.
int msgType = rfb.readServerMessageType();
+ if (viewer.ftpOnly && msgType != RfbProto.rfbFileTransfer) {
+ System.out.println("msgType:" + msgType);
+ }
// Process the message depending on its type.
switch (msgType) {
@@ -1532,9 +1562,14 @@
else
{
result =
- 0xFF000000 | (pixBuf[i * 4 + 1] & 0xFF)
- << 16 | (pixBuf[i * 4 + 2] & 0xFF)
- << 8 | (pixBuf[i * 4 + 3] & 0xFF);
+// begin runge/x11vnc
+// 0xFF000000 | (pixBuf[i * 4 + 1] & 0xFF)
+// << 16 | (pixBuf[i * 4 + 2] & 0xFF)
+// << 8 | (pixBuf[i * 4 + 3] & 0xFF);
+ 0xFF000000 | (pixBuf[i * 4 + 2] & 0xFF)
+ << 16 | (pixBuf[i * 4 + 1] & 0xFF)
+ << 8 | (pixBuf[i * 4 + 0] & 0xFF);
+// end runge/x11vnc
}
} else {
result = 0; // Transparent pixel
@@ -1565,9 +1600,14 @@
else
{
result =
- 0xFF000000 | (pixBuf[i * 4 + 1] & 0xFF)
- << 16 | (pixBuf[i * 4 + 2] & 0xFF)
- << 8 | (pixBuf[i * 4 + 3] & 0xFF);
+// begin runge/x11vnc
+// 0xFF000000 | (pixBuf[i * 4 + 1] & 0xFF)
+// << 16 | (pixBuf[i * 4 + 2] & 0xFF)
+// << 8 | (pixBuf[i * 4 + 3] & 0xFF);
+ 0xFF000000 | (pixBuf[i * 4 + 2] & 0xFF)
+ << 16 | (pixBuf[i * 4 + 1] & 0xFF)
+ << 8 | (pixBuf[i * 4 + 0] & 0xFF);
+// end runge/x11vnc
}
} else {
result = 0; // Transparent pixel
diff -Naur JavaViewer.orig/VncViewer.java JavaViewer/VncViewer.java
--- JavaViewer.orig/VncViewer.java 2006-05-24 15:14:40.000000000 -0400
+++ JavaViewer/VncViewer.java 2010-02-22 21:58:51.000000000 -0500
@@ -80,11 +80,11 @@
GridBagLayout gridbag;
ButtonPanel buttonPanel;
AuthPanel authenticator;
- VncCanvas vc;
+ VncCanvas vc = null;
OptionsFrame options;
ClipboardFrame clipboard;
RecordingFrame rec;
- FTPFrame ftp; // KMC: FTP Frame declaration
+ FTPFrame ftp = null; // KMC: FTP Frame declaration
// Control session recording.
Object recordingSync;
@@ -96,7 +96,7 @@
// Variables read from parameter values.
String host;
- int port;
+ int port, vncserverport;
String passwordParam;
String encPasswordParam;
boolean showControls;
@@ -115,28 +115,71 @@
int i;
// mslogon support 2 end
+// begin runge/x11vnc
+boolean disableSSL;
+boolean GET;
+String CONNECT;
+String urlPrefix;
+String httpsPort;
+String oneTimeKey;
+String ftpDropDown;
+String proxyHost;
+String proxyPort;
+boolean forceProxy;
+boolean ignoreProxy;
+boolean trustAllVncCerts;
+boolean trustUrlVncCert;
+boolean debugCerts;
+
+boolean ignoreMSLogonCheck;
+boolean delayAuthPanel;
+boolean ftpOnly;
+boolean graftFtp;
+boolean dsmActive;
+
+boolean gotAuth;
+int authGot;
+// end runge/x11vnc
+
+
//
// init()
//
+public void ftp_init() {
+ boolean show = false;
+ if (ftp != null) {
+ show = true;
+ }
+ ftp = null;
+
+ ftp = new FTPFrame(this); // KMC: FTPFrame creation
+
+ if (show) {
+ ftp.doOpen();
+ rfb.readServerDriveList();
+ }
+}
+
public void init() {
readParameters();
if (inSeparateFrame) {
- vncFrame = new Frame("Ultr@VNC");
- if (!inAnApplet) {
- vncFrame.add("Center", this);
- }
- vncContainer = vncFrame;
+ vncFrame = new Frame("Ultr@VNC");
+ if (!inAnApplet) {
+ vncFrame.add("Center", this);
+ }
+ vncContainer = vncFrame;
} else {
- vncContainer = this;
+ vncContainer = this;
}
recordingSync = new Object();
options = new OptionsFrame(this);
clipboard = new ClipboardFrame(this);
+
// authenticator = new AuthPanel(false); // mslogon support : go to connectAndAuthenticate()
if (RecordingFrame.checkSecurity())
rec = new RecordingFrame(this);
@@ -147,10 +190,11 @@
cursorUpdatesDef = null;
eightBitColorsDef = null;
- if (inSeparateFrame)
+ if (inSeparateFrame && vncFrame != null)
vncFrame.addWindowListener(this);
- ftp = new FTPFrame(this); // KMC: FTPFrame creation
+ ftp_init();
+
rfbThread = new Thread(this);
rfbThread.start();
}
@@ -186,6 +230,30 @@
gbc.weightx = 1.0;
gbc.weighty = 1.0;
+ if (ftpOnly) {
+ if (showControls) {
+ buttonPanel.enableButtons();
+ }
+ ActionListener taskPerformer = new ActionListener() {
+ public void actionPerformed(ActionEvent evt) {
+ vncFrame.setVisible(false);
+ ftp.setSavedLocations();
+ if (ftp.isVisible()) {
+ ftp.doClose();
+ } else {
+ ftp.doOpen();
+ }
+ rfb.readServerDriveList();
+ }
+ };
+ Timer t = new Timer(300, taskPerformer);
+ t.setRepeats(false);
+ t.start();
+
+ vc.processNormalProtocol();
+ return;
+ }
+
// Add ScrollPanel to applet mode
// Create a panel which itself is resizeable and can hold
@@ -286,6 +354,24 @@
void connectAndAuthenticate() throws Exception {
+ if (graftFtp) {
+ rfb = new RfbProto(host, port, this);
+ rfb.desktopName = "ftponly";
+ rfb.framebufferWidth = 12;
+ rfb.framebufferHeight = 12;
+ rfb.bitsPerPixel = 32;
+ rfb.depth = 24;
+ rfb.trueColour = true;
+ rfb.redMax = 255;
+ rfb.greenMax = 255;
+ rfb.blueMax = 255;
+ rfb.redShift = 16;
+ rfb.greenShift = 8;
+ rfb.blueShift = 0;
+ rfb.inNormalProtocol = true;
+ return;
+ }
+
// If "ENCPASSWORD" parameter is set, decrypt the password into
// the passwordParam string.
@@ -336,7 +422,22 @@
//
- prologueDetectAuthProtocol() ;
+// begin runge/x11vnc
+ gotAuth = false;
+ if (delayAuthPanel) {
+ if (tryAuthenticate(null, null)) {
+ if (inSeparateFrame) {
+ vncFrame.pack();
+ vncFrame.show();
+ }
+ return;
+ }
+ }
+// prologueDetectAuthProtocol() ;
+ if (ignoreMSLogonCheck == false) {
+ prologueDetectAuthProtocol() ;
+ }
+// end runge/x11vnc
authenticator = new AuthPanel(mslogon);
@@ -390,6 +491,10 @@
break;
//mslogon support end
+// begin runge/x11vnc
+ gotAuth = false;
+// end runge/x11vnc
+
// Retry on authentication failure.
authenticator.retry();
}
@@ -405,9 +510,11 @@
void prologueDetectAuthProtocol() throws Exception {
- rfb = new RfbProto(host, port, this);
+ if (!gotAuth) {
+ rfb = new RfbProto(host, port, this);
- rfb.readVersionMsg();
+ rfb.readVersionMsg();
+ }
System.out.println("RFB server supports protocol version " +
rfb.serverMajor + "." + rfb.serverMinor);
@@ -431,16 +538,36 @@
boolean tryAuthenticate(String us, String pw) throws Exception {
- rfb = new RfbProto(host, port, this);
+ int authScheme;
- rfb.readVersionMsg();
+ if (!gotAuth) {
+ rfb = new RfbProto(host, port, this);
- System.out.println("RFB server supports protocol version " +
- rfb.serverMajor + "." + rfb.serverMinor);
+ rfb.readVersionMsg();
- rfb.writeVersionMsg();
+ System.out.println("RFB server supports protocol version: " +
+ rfb.serverMajor + "." + rfb.serverMinor);
+
+ rfb.writeVersionMsg();
- int authScheme = rfb.readAuthScheme();
+ authScheme = rfb.readAuthScheme();
+
+ gotAuth = true;
+ authGot = authScheme;
+ } else {
+ authScheme = authGot;
+ }
+// begin runge/x11vnc
+ if (delayAuthPanel && pw == null) {
+ if (authScheme == RfbProto.NoAuth) {
+ System.out.println("No authentication needed");
+ return true;
+ } else {
+ return false;
+ }
+ }
+System.out.println("as: " + authScheme);
+// end runge/x11vnc
switch (authScheme) {
@@ -629,6 +756,10 @@
void doProtocolInitialisation() throws IOException {
+ if (graftFtp) {
+ return;
+ }
+
rfb.writeClientInit();
rfb.readServerInit();
@@ -775,8 +906,25 @@
}
}
- String str = readParameter("PORT", true);
- port = Integer.parseInt(str);
+ port = 0;
+ String str = readParameter("PORT", false);
+ if (str != null) {
+ port = Integer.parseInt(str);
+ }
+ // When there is a proxy VNCSERVERPORT may be inaccessible (inside firewall).
+ vncserverport = 0;
+ str = readParameter("VNCSERVERPORT", false);
+ if (str != null) {
+ vncserverport = Integer.parseInt(str);
+ }
+ if (port == 0 && vncserverport == 0) {
+ fatalError("Neither PORT nor VNCSERVERPORT parameters specified");
+ }
+ if (port == 0) {
+ // Nevertheless, fall back to vncserverport if we have to.
+ System.out.println("using vncserverport: '" + vncserverport + "' for PORT.");
+ port = vncserverport;
+ }
if (inAnApplet) {
str = readParameter("Open New Window", false);
@@ -804,6 +952,138 @@
deferScreenUpdates = readIntParameter("Defer screen updates", 20);
deferCursorUpdates = readIntParameter("Defer cursor updates", 10);
deferUpdateRequests = readIntParameter("Defer update requests", 50);
+
+// begin runge/x11vnc
+ // SSL
+ disableSSL = false;
+ str = readParameter("DisableSSL", false);
+ if (str != null && str.equalsIgnoreCase("Yes"))
+ disableSSL = true;
+
+ httpsPort = readParameter("httpsPort", false);
+
+ // Extra GET, CONNECT string:
+ CONNECT = readParameter("CONNECT", false);
+ if (CONNECT != null) {
+ CONNECT = CONNECT.replaceAll(" ", ":");
+ }
+
+ GET = false;
+ str = readParameter("GET", false);
+ if (str != null && str.equalsIgnoreCase("Yes")) {
+ GET = true;
+ }
+ if (str != null && str.equalsIgnoreCase("1")) {
+ GET = true;
+ }
+
+ urlPrefix = readParameter("urlPrefix", false);
+ if (urlPrefix != null) {
+ urlPrefix = urlPrefix.replaceAll("%2F", "/");
+ urlPrefix = urlPrefix.replaceAll("%2f", "/");
+ urlPrefix = urlPrefix.replaceAll("_2F_", "/");
+ if (urlPrefix.indexOf("/") != 0) {
+ urlPrefix = "/" + urlPrefix;
+ }
+ } else {
+ urlPrefix = "";
+ }
+ System.out.println("urlPrefix: '" + urlPrefix + "'");
+
+ ftpDropDown = readParameter("ftpDropDown", false);
+ if (ftpDropDown != null) {
+ ftpDropDown = ftpDropDown.replaceAll("%2F", "/");
+ ftpDropDown = ftpDropDown.replaceAll("%2f", "/");
+ ftpDropDown = ftpDropDown.replaceAll("_2F_", "/");
+ ftpDropDown = ftpDropDown.replaceAll("%20", " ");
+ System.out.println("ftpDropDown: '" + ftpDropDown + "'");
+ }
+
+
+ oneTimeKey = readParameter("oneTimeKey", false);
+ if (oneTimeKey != null) {
+ System.out.println("oneTimeKey: is set");
+ }
+
+ forceProxy = false;
+ proxyHost = null;
+ proxyPort = null;
+ str = readParameter("forceProxy", false);
+ if (str != null) {
+ if (str.equalsIgnoreCase("Yes")) {
+ forceProxy = true;
+ } else if (str.equalsIgnoreCase("No")) {
+ forceProxy = false;
+ } else {
+ forceProxy = true;
+ String[] pieces = str.split(" ");
+ proxyHost = new String(pieces[0]);
+ if (pieces.length >= 2) {
+ proxyPort = new String(pieces[1]);
+ } else {
+ proxyPort = new String("8080");
+ }
+ }
+ }
+ str = readParameter("proxyHost", false);
+ if (str != null) {
+ proxyHost = new String(str);
+ }
+ str = readParameter("proxyPort", false);
+ if (str != null) {
+ proxyPort = new String(str);
+ }
+ if (proxyHost != null && proxyPort == null) {
+ proxyPort = new String("8080");
+ }
+
+ ignoreProxy = false;
+ str = readParameter("ignoreProxy", false);
+ if (str != null && str.equalsIgnoreCase("Yes")) {
+ ignoreProxy = true;
+ }
+
+ trustAllVncCerts = false;
+ str = readParameter("trustAllVncCerts", false);
+ if (str != null && str.equalsIgnoreCase("Yes")) {
+ trustAllVncCerts = true;
+ }
+ trustUrlVncCert = false;
+ str = readParameter("trustUrlVncCert", false);
+ if (str != null && str.equalsIgnoreCase("Yes")) {
+ trustUrlVncCert = true;
+ }
+ debugCerts = false;
+ str = readParameter("debugCerts", false);
+ if (str != null && str.equalsIgnoreCase("Yes")) {
+ debugCerts = true;
+ }
+ ignoreMSLogonCheck = false;
+ str = readParameter("ignoreMSLogonCheck", false);
+ if (str != null && str.equalsIgnoreCase("Yes")) {
+ ignoreMSLogonCheck = true;
+ }
+ ftpOnly = false;
+ str = readParameter("ftpOnly", false);
+ if (str != null && str.equalsIgnoreCase("Yes")) {
+ ftpOnly = true;
+ }
+ graftFtp = false;
+ str = readParameter("graftFtp", false);
+ if (str != null && str.equalsIgnoreCase("Yes")) {
+ graftFtp = true;
+ }
+ dsmActive = false;
+ str = readParameter("dsmActive", false);
+ if (str != null && str.equalsIgnoreCase("Yes")) {
+ dsmActive = true;
+ }
+ delayAuthPanel = false;
+ str = readParameter("delayAuthPanel", false);
+ if (str != null && str.equalsIgnoreCase("Yes")) {
+ delayAuthPanel = true;
+ }
+// end runge/x11vnc
}
public String readParameter(String name, boolean required) {