diff --git a/src/plugins/otr/plugin.xml b/src/plugins/otr/plugin.xml index d7182bb3..5d638f28 100644 --- a/src/plugins/otr/plugin.xml +++ b/src/plugins/otr/plugin.xml @@ -7,6 +7,7 @@ holger@bergunde.de Adds OTR support to Spark 2.6.0 + 1.6.0_1 org.jivesoftware.spark.otrplug.OTRPlugin Windows,Linux,Mac diff --git a/src/plugins/otr/src/java/org/jivesoftware/spark/otrplug/OTRManager.java b/src/plugins/otr/src/java/org/jivesoftware/spark/otrplug/OTRManager.java index 7384fc6e..4b75f279 100644 --- a/src/plugins/otr/src/java/org/jivesoftware/spark/otrplug/OTRManager.java +++ b/src/plugins/otr/src/java/org/jivesoftware/spark/otrplug/OTRManager.java @@ -33,7 +33,8 @@ public class OTRManager extends ChatRoomListenerAdapter { private MessageListenerHandler _msgListener; private Map _activeSessions = new HashMap(); final ChatManager chatManager = SparkManager.getChatManager(); - private static OtrKeyManager _keyManager; + private static MyOtrKeyManager _keyManager; + private OTRManager() { @@ -81,7 +82,7 @@ public class OTRManager extends ChatRoomListenerAdapter { } } - public OtrKeyManager getKeyManager() + public MyOtrKeyManager getKeyManager() { return _keyManager; } diff --git a/src/plugins/otr/src/java/org/jivesoftware/spark/otrplug/OTRProperties.java b/src/plugins/otr/src/java/org/jivesoftware/spark/otrplug/OTRProperties.java new file mode 100644 index 00000000..f826a7ff --- /dev/null +++ b/src/plugins/otr/src/java/org/jivesoftware/spark/otrplug/OTRProperties.java @@ -0,0 +1,139 @@ + +package org.jivesoftware.spark.otrplug; + +import java.awt.Color; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Properties; +import org.jivesoftware.spark.SparkManager; + +/** + * RoarProperties file stuff + * + * @author wolf.posdorfer + * + */ +public class OTRProperties { + private Properties props; + private File configFile; + + private static final Object LOCK = new Object(); + private static OTRProperties instance = null; + + /** + * returns the Instance of this Properties file + * @return + */ + public static OTRProperties getInstance() { + synchronized (LOCK) { + if (instance == null) { + instance = new OTRProperties(); + } + return instance; + } + } + + private OTRProperties() { + this.props = new Properties(); + + try { + props.load(new FileInputStream(getConfigFile())); + } catch (IOException e) { + // Can't load ConfigFile + } + + } + + private File getConfigFile() { + if (configFile == null) + configFile = new File(SparkManager.getUserDirectory(), "otr.properties"); + + return configFile; + } + + public void save() { + try { + props.store(new FileOutputStream(getConfigFile()), + "Storing OTRPlugin properties"); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public boolean getIsOTREnabled() + { + return getBoolean("isOTREnabled", true); + } + + public void setIsOTREnabled(boolean enabled) + { + setBoolean("isOTREnabeld", enabled); + } + + + // =============================================================================== + // =============================================================================== + // =============================================================================== + private boolean getBoolean(String property, boolean defaultValue) { + return Boolean.parseBoolean(props.getProperty(property, + Boolean.toString(defaultValue))); + } + + private void setBoolean(String property, boolean value) { + props.setProperty(property, Boolean.toString(value)); + } + + private int getInt(String property) { + return Integer.parseInt(props.getProperty(property, "0")); + } + + private void setInt(String property, int integer) { + props.setProperty(property, "" + integer); + } + + private void setColor(String property, Color color) { + props.setProperty(property, convertColor(color)); + } + + private Color getColor(String property, Color defaultcolor) { + try { + return convertString(props.getProperty(property)); + } catch (Exception e) { + return defaultcolor; + } + + } + + public String getProperty(String property) { + return props.getProperty(property); + } + + /** + * Converts a {@link String} matching xxx,xxx,xxx to a {@link Color}
+ * where xxx is a number from 0 to 255 + * + * @param s + * @return + */ + public static Color convertString(String s) throws Exception { + String[] arr = s.split(","); + return new Color(Integer.parseInt(arr[0]), Integer.parseInt(arr[1]), + Integer.parseInt(arr[2])); + + } + + /** + * Converts a {@link Color} to a {@link String} in this format:
+ * xxx,xxx,xxx
+ * where xxx is a number from 0 to 255 + * + * @param color + * @return + */ + public static String convertColor(Color color) { + return color.getRed() + "," + color.getGreen() + "," + color.getBlue(); + } + + } diff --git a/src/plugins/otr/src/java/org/jivesoftware/spark/otrplug/OTRResources.java b/src/plugins/otr/src/java/org/jivesoftware/spark/otrplug/OTRResources.java new file mode 100644 index 00000000..e9ae2d85 --- /dev/null +++ b/src/plugins/otr/src/java/org/jivesoftware/spark/otrplug/OTRResources.java @@ -0,0 +1,27 @@ +package org.jivesoftware.spark.otrplug; + +import java.util.PropertyResourceBundle; +import java.util.ResourceBundle; + +import org.jivesoftware.spark.util.log.Log; + +public class OTRResources { + + private static PropertyResourceBundle prb; + + static ClassLoader cl = OTRResources.class.getClassLoader(); + + static { + prb = (PropertyResourceBundle) ResourceBundle.getBundle("i18n/otrplugin_i18n"); + } + + public static final String getString(String propertyName) { + try { + return prb.getString(propertyName); + } catch (Exception e) { + Log.error(e); + return propertyName; + } + } + +} diff --git a/src/plugins/otr/src/java/org/jivesoftware/spark/ui/MyOtrKeyManager.java b/src/plugins/otr/src/java/org/jivesoftware/spark/ui/MyOtrKeyManager.java index bfa8c4cd..6209a6c1 100644 --- a/src/plugins/otr/src/java/org/jivesoftware/spark/ui/MyOtrKeyManager.java +++ b/src/plugins/otr/src/java/org/jivesoftware/spark/ui/MyOtrKeyManager.java @@ -32,276 +32,264 @@ import net.java.otr4j.session.SessionID; public class MyOtrKeyManager implements OtrKeyManager { - private OtrKeyManagerStore store; + private OtrKeyManagerStore store; - public MyOtrKeyManager(OtrKeyManagerStore store) { - this.store = store; + public MyOtrKeyManager(OtrKeyManagerStore store) { + this.store = store; + } + + class DefaultPropertiesStore implements OtrKeyManagerStore { + private final Properties properties = new Properties(); + private String filepath; + + public DefaultPropertiesStore(String filepath) throws IOException { + if (filepath == null || filepath.length() < 1) + throw new IllegalArgumentException(); + this.filepath = filepath; + properties.clear(); + + InputStream in = new BufferedInputStream(new FileInputStream(getConfigurationFile())); + try { + properties.load(in); + } finally { + in.close(); + } } - class DefaultPropertiesStore implements OtrKeyManagerStore { - private final Properties properties = new Properties(); - private String filepath; - - public DefaultPropertiesStore(String filepath) throws IOException { - if (filepath == null || filepath.length() < 1) - throw new IllegalArgumentException(); - this.filepath = filepath; - properties.clear(); - - InputStream in = new BufferedInputStream(new FileInputStream( - getConfigurationFile())); - try { - properties.load(in); - } finally { - in.close(); - } - } - - private File getConfigurationFile() throws IOException { - File configFile = new File(filepath); - if (!configFile.exists()) - configFile.createNewFile(); - return configFile; - } - - public void setProperty(String id, boolean value) { - properties.setProperty(id, "true"); - try { - this.store(); - } catch (Exception e) { - e.printStackTrace(); - } - } - - private void store() throws FileNotFoundException, IOException { - OutputStream out = new FileOutputStream(getConfigurationFile()); - properties.store(out, null); - out.close(); - } - - public void setProperty(String id, byte[] value) { - properties.setProperty(id, new String(Base64.encode(value))); - try { - this.store(); - } catch (Exception e) { - e.printStackTrace(); - } - } - - public void removeProperty(String id) { - properties.remove(id); - - } - - public byte[] getPropertyBytes(String id) { - String value = properties.getProperty(id); - if (value == null) - return null; - return Base64.decode(value); - } - - public boolean getPropertyBoolean(String id, boolean defaultValue) { - try { - return Boolean.valueOf(properties.get(id).toString()); - } catch (Exception e) { - return defaultValue; - } - } + private File getConfigurationFile() throws IOException { + File configFile = new File(filepath); + if (!configFile.exists()) + configFile.createNewFile(); + return configFile; } - public MyOtrKeyManager(String filepath) throws IOException { - this.store = new DefaultPropertiesStore(filepath); + public void setProperty(String id, boolean value) { + properties.setProperty(id, "true"); + try { + this.store(); + } catch (Exception e) { + e.printStackTrace(); + } } - private List listeners = new Vector(); - - public void addListener(OtrKeyManagerListener l) { - synchronized (listeners) { - if (!listeners.contains(l)) - listeners.add(l); - } + private void store() throws FileNotFoundException, IOException { + OutputStream out = new FileOutputStream(getConfigurationFile()); + properties.store(out, null); + out.close(); } - public void removeListener(OtrKeyManagerListener l) { - synchronized (listeners) { - listeners.remove(l); - } + public void setProperty(String id, byte[] value) { + properties.setProperty(id, new String(Base64.encode(value))); + try { + this.store(); + } catch (Exception e) { + e.printStackTrace(); + } } - public void generateLocalKeyPair(SessionID sessionID) { - if (sessionID == null) - return; - - String accountID = sessionID.getAccountID(); - KeyPair keyPair; - try { - keyPair = KeyPairGenerator.getInstance("DSA").genKeyPair(); - } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); - return; - } - - // Store Public Key. - PublicKey pubKey = keyPair.getPublic(); - X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(pubKey - .getEncoded()); - - this.store.setProperty(accountID + ".publicKey", x509EncodedKeySpec - .getEncoded()); - - // Store Private Key. - PrivateKey privKey = keyPair.getPrivate(); - PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec( - privKey.getEncoded()); - - this.store.setProperty(accountID + ".privateKey", pkcs8EncodedKeySpec - .getEncoded()); - } - - public String getLocalFingerprint(SessionID sessionID) { - KeyPair keyPair = loadLocalKeyPair(sessionID); - - if (keyPair == null) - return null; - - PublicKey pubKey = keyPair.getPublic(); - - try { - return new OtrCryptoEngineImpl().getFingerprint(pubKey); - } catch (OtrCryptoException e) { - e.printStackTrace(); - return null; - } - } - - public String getRemoteFingerprint(SessionID sessionID) { - PublicKey remotePublicKey = loadRemotePublicKey(sessionID); - if (remotePublicKey == null) - return null; - try { - return new OtrCryptoEngineImpl().getFingerprint(remotePublicKey); - } catch (OtrCryptoException e) { - e.printStackTrace(); - return null; - } - } - - public boolean isVerified(SessionID sessionID) { - if (sessionID == null) - return false; - - return this.store.getPropertyBoolean(sessionID.getUserID() - + ".publicKey.verified", false); - } - - public KeyPair loadLocalKeyPair(SessionID sessionID) { - if (sessionID == null) - return null; - - String accountID = sessionID.getAccountID(); - // Load Private Key. - byte[] b64PrivKey = this.store.getPropertyBytes(accountID - + ".privateKey"); - if (b64PrivKey == null) - return null; - - PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(b64PrivKey); - - // Load Public Key. - byte[] b64PubKey = this.store - .getPropertyBytes(accountID + ".publicKey"); - if (b64PubKey == null) - return null; - - X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(b64PubKey); - - PublicKey publicKey; - PrivateKey privateKey; - - // Generate KeyPair. - KeyFactory keyFactory; - try { - keyFactory = KeyFactory.getInstance("DSA"); - publicKey = keyFactory.generatePublic(publicKeySpec); - privateKey = keyFactory.generatePrivate(privateKeySpec); - } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); - return null; - } catch (InvalidKeySpecException e) { - e.printStackTrace(); - return null; - } - - return new KeyPair(publicKey, privateKey); - } - - public PublicKey loadRemotePublicKey(SessionID sessionID) { - if (sessionID == null) - return null; - - String userID = sessionID.getUserID(); - - byte[] b64PubKey = this.store.getPropertyBytes(userID + ".publicKey"); - if (b64PubKey == null) - return null; - - X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(b64PubKey); - - // Generate KeyPair. - KeyFactory keyFactory; - try { - keyFactory = KeyFactory.getInstance("DSA"); - return keyFactory.generatePublic(publicKeySpec); - } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); - return null; - } catch (InvalidKeySpecException e) { - e.printStackTrace(); - return null; - } - } - - public void savePublicKey(SessionID sessionID, PublicKey pubKey) { - if (sessionID == null) - return; - - X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(pubKey - .getEncoded()); - - String userID = sessionID.getUserID(); - this.store.setProperty(userID + ".publicKey", x509EncodedKeySpec - .getEncoded()); - - this.store.removeProperty(userID + ".publicKey.verified"); - } - - public void unverify(SessionID sessionID) { - if (sessionID == null) - return; - - if (!isVerified(sessionID)) - return; - - this.store - .removeProperty(sessionID.getUserID() + ".publicKey.verified"); - - for (OtrKeyManagerListener l : listeners) - l.verificationStatusChanged(sessionID); + public void removeProperty(String id) { + properties.remove(id); } - public void verify(SessionID sessionID) { - if (sessionID == null) - return; - - if (this.isVerified(sessionID)) - return; - - this.store.setProperty(sessionID.getUserID() + ".publicKey.verified", - true); - - for (OtrKeyManagerListener l : listeners) - l.verificationStatusChanged(sessionID); + public byte[] getPropertyBytes(String id) { + String value = properties.getProperty(id); + if (value == null) + return null; + return Base64.decode(value); } + public boolean getPropertyBoolean(String id, boolean defaultValue) { + try { + return Boolean.valueOf(properties.get(id).toString()); + } catch (Exception e) { + return defaultValue; + } + } + } + + public MyOtrKeyManager(String filepath) throws IOException { + this.store = new DefaultPropertiesStore(filepath); + } + + private List listeners = new Vector(); + + public void addListener(OtrKeyManagerListener l) { + synchronized (listeners) { + if (!listeners.contains(l)) + listeners.add(l); + } + } + + public void removeListener(OtrKeyManagerListener l) { + synchronized (listeners) { + listeners.remove(l); + } + } + + public void generateLocalKeyPair(SessionID sessionID) { + if (sessionID == null) + return; + + String accountID = sessionID.getAccountID(); + KeyPair keyPair; + try { + keyPair = KeyPairGenerator.getInstance("DSA").genKeyPair(); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + return; + } + + // Store Public Key. + PublicKey pubKey = keyPair.getPublic(); + X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(pubKey.getEncoded()); + + this.store.setProperty(accountID + ".publicKey", x509EncodedKeySpec.getEncoded()); + + // Store Private Key. + PrivateKey privKey = keyPair.getPrivate(); + PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privKey.getEncoded()); + + this.store.setProperty(accountID + ".privateKey", pkcs8EncodedKeySpec.getEncoded()); + } + + public String getLocalFingerprint(SessionID sessionID) { + KeyPair keyPair = loadLocalKeyPair(sessionID); + + if (keyPair == null) + return null; + + PublicKey pubKey = keyPair.getPublic(); + + try { + return new OtrCryptoEngineImpl().getFingerprint(pubKey); + } catch (OtrCryptoException e) { + e.printStackTrace(); + return null; + } + } + + public String getRemoteFingerprint(SessionID sessionID) { + PublicKey remotePublicKey = loadRemotePublicKey(sessionID); + if (remotePublicKey == null) + return null; + try { + return new OtrCryptoEngineImpl().getFingerprint(remotePublicKey); + } catch (OtrCryptoException e) { + e.printStackTrace(); + return null; + } + } + + public boolean isVerified(SessionID sessionID) { + if (sessionID == null) + return false; + + return this.store.getPropertyBoolean(sessionID.getUserID() + ".publicKey.verified", false); + } + + public KeyPair loadLocalKeyPair(SessionID sessionID) { + if (sessionID == null) + return null; + + String accountID = sessionID.getAccountID(); + // Load Private Key. + byte[] b64PrivKey = this.store.getPropertyBytes(accountID + ".privateKey"); + if (b64PrivKey == null) + return null; + + PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(b64PrivKey); + + // Load Public Key. + byte[] b64PubKey = this.store.getPropertyBytes(accountID + ".publicKey"); + if (b64PubKey == null) + return null; + + X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(b64PubKey); + + PublicKey publicKey; + PrivateKey privateKey; + + // Generate KeyPair. + KeyFactory keyFactory; + try { + keyFactory = KeyFactory.getInstance("DSA"); + publicKey = keyFactory.generatePublic(publicKeySpec); + privateKey = keyFactory.generatePrivate(privateKeySpec); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + return null; + } catch (InvalidKeySpecException e) { + e.printStackTrace(); + return null; + } + + return new KeyPair(publicKey, privateKey); + } + + public PublicKey loadRemotePublicKey(SessionID sessionID) { + if (sessionID == null) + return null; + + String userID = sessionID.getUserID(); + + byte[] b64PubKey = this.store.getPropertyBytes(userID + ".publicKey"); + if (b64PubKey == null) + return null; + + X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(b64PubKey); + + // Generate KeyPair. + KeyFactory keyFactory; + try { + keyFactory = KeyFactory.getInstance("DSA"); + return keyFactory.generatePublic(publicKeySpec); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + return null; + } catch (InvalidKeySpecException e) { + e.printStackTrace(); + return null; + } + } + + public void savePublicKey(SessionID sessionID, PublicKey pubKey) { + if (sessionID == null) + return; + + X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(pubKey.getEncoded()); + + String userID = sessionID.getUserID(); + this.store.setProperty(userID + ".publicKey", x509EncodedKeySpec.getEncoded()); + + this.store.removeProperty(userID + ".publicKey.verified"); + } + + public void unverify(SessionID sessionID) { + if (sessionID == null) + return; + + if (!isVerified(sessionID)) + return; + + this.store.removeProperty(sessionID.getUserID() + ".publicKey.verified"); + + for (OtrKeyManagerListener l : listeners) + l.verificationStatusChanged(sessionID); + + } + + public void verify(SessionID sessionID) { + if (sessionID == null) + return; + + if (this.isVerified(sessionID)) + return; + + this.store.setProperty(sessionID.getUserID() + ".publicKey.verified", true); + + for (OtrKeyManagerListener l : listeners) + l.verificationStatusChanged(sessionID); + } + } diff --git a/src/plugins/otr/src/java/org/jivesoftware/spark/ui/OTRKeyTable.java b/src/plugins/otr/src/java/org/jivesoftware/spark/ui/OTRKeyTable.java new file mode 100644 index 00000000..2c957fb7 --- /dev/null +++ b/src/plugins/otr/src/java/org/jivesoftware/spark/ui/OTRKeyTable.java @@ -0,0 +1,85 @@ +package org.jivesoftware.spark.ui; + +import java.awt.BorderLayout; + +import java.util.Vector; + +import javax.swing.JComponent; + +import javax.swing.JScrollPane; +import javax.swing.JTable; + +import javax.swing.event.TableModelListener; +import javax.swing.table.DefaultTableModel; + +import org.jivesoftware.spark.otrplug.OTRResources; + +public class OTRKeyTable extends JComponent { + + /** + * + */ + private static final long serialVersionUID = -2922785387942547350L; + private JTable _table; + private DefaultTableModel _tableModel; + + public OTRKeyTable() { + + final String[] header = { OTRResources.getString("otr.table.jid"), OTRResources.getString("otr.table.public.key"), OTRResources.getString("otr.key.verified") }; + + _tableModel = new MyTableModel(header); + _table = new JTable(_tableModel); + + this.setLayout(new BorderLayout()); + this.add(new JScrollPane(_table), BorderLayout.CENTER); + + } + + class MyTableModel extends DefaultTableModel { + /** + * + */ + private static final long serialVersionUID = -2930577433474767242L; + + public MyTableModel(String[] headers) { + super(headers, 0); + } + + @Override + public boolean isCellEditable(int row, int column) { + if (column == 2) + return true; + else + return false; + + } + + @Override + public Class getColumnClass(int columnIndex) { + if (columnIndex == 2) { + return Boolean.class; + } else + return String.class; + + } + } + + public void addTableChangeListener(TableModelListener listener) { + _tableModel.addTableModelListener(listener); + } + + public void addEntry(String jid, String hash, boolean verified) { + Vector data = new Vector(3); + + data.add(jid); + data.add(hash); + data.add(verified); + + _tableModel.addRow(data); + } + + public Object getValueAt(int row, int col) { + return _tableModel.getValueAt(row, col); + } + +} \ No newline at end of file diff --git a/src/plugins/otr/src/java/org/jivesoftware/spark/ui/OTRPrefPanel.java b/src/plugins/otr/src/java/org/jivesoftware/spark/ui/OTRPrefPanel.java index 312f86aa..92267b07 100644 --- a/src/plugins/otr/src/java/org/jivesoftware/spark/ui/OTRPrefPanel.java +++ b/src/plugins/otr/src/java/org/jivesoftware/spark/ui/OTRPrefPanel.java @@ -3,46 +3,157 @@ package org.jivesoftware.spark.ui; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; -import java.security.KeyPair; -import java.security.KeyPairGenerator; -import java.security.NoSuchAlgorithmException; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JPanel; + import javax.swing.JTextField; +import javax.swing.event.TableModelEvent; +import javax.swing.event.TableModelListener; import net.java.otr4j.session.SessionID; +import org.jivesoftware.smack.RosterEntry; import org.jivesoftware.spark.SparkManager; +import org.jivesoftware.spark.component.VerticalFlowLayout; import org.jivesoftware.spark.otrplug.OTRManager; +import org.jivesoftware.spark.otrplug.OTRProperties; +import org.jivesoftware.spark.otrplug.OTRResources; -public class OTRPrefPanel extends JPanel{ - +public class OTRPrefPanel extends JPanel { + + /** + * + */ + private static final long serialVersionUID = -7125162190413040003L; private OTRManager _manager; - private SessionID _mySession = new SessionID(SparkManager.getConnection().getUser(), SparkManager.getConnection().getUser(), "Scytale"); - public OTRPrefPanel() - { - + private JCheckBox _enableOTR; + private JCheckBox _closeSessionOff; + private JCheckBox _closeSessionOnWindowClose; + private JLabel _currentKeyLabel; + private JButton _renewPrivateKey; + private OTRKeyTable _keytable; + private JTextField _privateKey; + private JPanel _gridPanel; + private MyOtrKeyManager _keyManager; + private OTRProperties _properties; + + public OTRPrefPanel() { + _manager = OTRManager.getInstance(); - setLayout(new GridBagLayout()); - + _keyManager = _manager.getKeyManager(); + _properties = OTRProperties.getInstance(); + setLayout(new VerticalFlowLayout()); + init(); buildGUI(); - } - - - private void buildGUI() - { - //_manager.getKeyManager().generateLocalKeyPair(_mySession); - KeyPair key = _manager.getKeyManager().loadLocalKeyPair(_mySession); - - String privkey = _manager.getKeyManager().getLocalFingerprint(_mySession); - - System.out.println( privkey); - this.add(new JLabel("key: "), new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); - this.add(new JTextField(privkey), new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); - - + OtrEnableSwitch(); + this.add(_gridPanel); } + private void OtrEnableSwitch() { + _enableOTR.setSelected(_properties.getIsOTREnabled()); + + } + + public boolean isOTREnabled() + { + return _enableOTR.isSelected(); + } + + private void init() { + _gridPanel = new JPanel(new GridBagLayout()); + + _enableOTR = new JCheckBox(); + _enableOTR.setText(OTRResources.getString("otr.enable")); + + _closeSessionOff = new JCheckBox(); + _closeSessionOff.setText(OTRResources.getString("otr.close.session.on.contact.off")); + + _closeSessionOnWindowClose = new JCheckBox(); + _closeSessionOnWindowClose.setText(OTRResources.getString("otr.close.session.on.window.close")); + + _currentKeyLabel = new JLabel(); + _currentKeyLabel.setText(OTRResources.getString("current.priv.key")); + + _renewPrivateKey = new JButton(); + _renewPrivateKey.setText(OTRResources.getString("renew.current.key")); + _renewPrivateKey.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + SessionID mySession = new SessionID(SparkManager.getConnection().getUser(), "no one", "Scytale"); + _manager.getKeyManager().generateLocalKeyPair(mySession); + _privateKey.setText(getCurrentLocalKey()); + } + }); + + _privateKey = new JTextField(); + _privateKey.setEditable(false); + _privateKey.setSize(300, 20); + _privateKey.setText(getCurrentLocalKey()); + + _keytable = new OTRKeyTable(); + + loadRemoteKeys(); + + _keytable.addTableChangeListener(new TableModelListener() { + + @Override + public void tableChanged(TableModelEvent e) { + int col = e.getColumn(); + int row = e.getFirstRow(); + + if (col == 2) { + boolean selection = (Boolean) _keytable.getValueAt(row, col); + String JID = (String)_keytable.getValueAt(row, 0); + SessionID curSelectedSession = new SessionID(SparkManager.getConnection().getUser(), JID, "Scytale"); + if (selection) { + _keyManager.verify(curSelectedSession); + } else + + { + _keyManager.unverify(curSelectedSession); + } + } + } + }); + + } + + private String getCurrentLocalKey() { + SessionID mySession = new SessionID(SparkManager.getConnection().getUser(), "no one", "Scytale"); + String myKey = _keyManager.getLocalFingerprint(mySession); + return myKey; + } + + private void loadRemoteKeys() { + + for (RosterEntry entry : SparkManager.getConnection().getRoster().getEntries()) { + SessionID curSession = new SessionID(SparkManager.getConnection().getUser(), entry.getUser(), "Scytale"); + String remoteKey = _keyManager.getRemoteFingerprint(curSession); + if (remoteKey != null) { + boolean isVerified = _keyManager.isVerified(curSession); + _keytable.addEntry(entry.getUser(), remoteKey, isVerified); + } + } + } + + private void buildGUI() { + _gridPanel.setBorder(BorderFactory.createTitledBorder(OTRResources.getString("otr.settings"))); + + _gridPanel.add(_enableOTR, new GridBagConstraints(0, 0, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); + _gridPanel.add(_closeSessionOff, new GridBagConstraints(0, 1, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); + _gridPanel.add(_closeSessionOnWindowClose, new GridBagConstraints(0, 2, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); + _gridPanel.add(_currentKeyLabel, new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(10, 0, 0, 0), 0, 0)); + _gridPanel.add(_privateKey, new GridBagConstraints(1, 3, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(10, 0, 0, 0), 0, 0)); + _gridPanel.add(_renewPrivateKey, new GridBagConstraints(1, 4, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHEAST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0)); + _gridPanel.add(_keytable, new GridBagConstraints(0, 5, 2, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(20, 0, 0, 0), 0, 0)); + } + } diff --git a/src/plugins/otr/src/java/org/jivesoftware/spark/ui/OTRPreferences.java b/src/plugins/otr/src/java/org/jivesoftware/spark/ui/OTRPreferences.java index 4a64ba28..37712fad 100644 --- a/src/plugins/otr/src/java/org/jivesoftware/spark/ui/OTRPreferences.java +++ b/src/plugins/otr/src/java/org/jivesoftware/spark/ui/OTRPreferences.java @@ -4,13 +4,17 @@ import javax.swing.Icon; import javax.swing.JComponent; import org.jivesoftware.spark.otrplug.OTRManager; +import org.jivesoftware.spark.otrplug.OTRProperties; +import org.jivesoftware.spark.otrplug.OTRResources; import org.jivesoftware.spark.preference.Preference; public class OTRPreferences implements Preference { + private OTRPrefPanel pref = new OTRPrefPanel(); + @Override public String getTitle() { - return "Off-The-Record Plugin"; + return OTRResources.getString("otr.title"); } @Override @@ -27,7 +31,7 @@ public class OTRPreferences implements Preference { @Override public String getListName() { - return "OTR"; + return OTRResources.getString("otr.list.entry"); } @Override @@ -38,7 +42,7 @@ public class OTRPreferences implements Preference { @Override public JComponent getGUI() { - return new OTRPrefPanel(); + return pref; } @Override @@ -49,7 +53,8 @@ public class OTRPreferences implements Preference { @Override public void commit() { - // TODO Auto-generated method stub + OTRProperties.getInstance().setIsOTREnabled(pref.isOTREnabled()); + OTRProperties.getInstance().save(); } diff --git a/src/plugins/otr/src/java/org/jivesoftware/spark/ui/OTRSession.java b/src/plugins/otr/src/java/org/jivesoftware/spark/ui/OTRSession.java index d8ea3f69..0576f11e 100644 --- a/src/plugins/otr/src/java/org/jivesoftware/spark/ui/OTRSession.java +++ b/src/plugins/otr/src/java/org/jivesoftware/spark/ui/OTRSession.java @@ -162,8 +162,20 @@ public class OTRSession { { PublicKey rempubkey = _engine.getRemotePublicKey(_mySession); OTRManager.getInstance().getKeyManager().savePublicKey(_mySession, rempubkey); - remkey = OTRManager.getInstance().getKeyManager().getRemoteFingerprint(_mySession); + remkey = OTRManager.getInstance().getKeyManager().getRemoteFingerprint(_mySession); } + + System.out.println(remkey); + + if (OTRManager.getInstance().getKeyManager().isVerified(_mySession)) + { + System.out.println("verified"); + + } + + System.out.println(_mySession.getUserID()); + System.out.println( OTRManager.getInstance().getKeyManager().getLocalFingerprint(_mySession));; + //String remkey = OTRManager.getInstance().getKeyManager().getRemoteFingerprint(_mySession); _chatRoom.getTranscriptWindow().insertNotificationMessage("From now on, your conversation is encrypted Remotekey: "+remkey, Color.gray); _otrButton.setIcon(new ImageIcon(cl.getResource("otr_on.png"))); diff --git a/src/plugins/otr/src/resources/i18n/otrplugin_i18n.properties b/src/plugins/otr/src/resources/i18n/otrplugin_i18n.properties new file mode 100644 index 00000000..bc0c267f --- /dev/null +++ b/src/plugins/otr/src/resources/i18n/otrplugin_i18n.properties @@ -0,0 +1,19 @@ + +# OTR language file + +otr.title = Off-the-Record Messaging +otr.list.entry = OTR Messaging +otr.settings = OTR Settings +otr.enable = OTR Enabled +current.priv.key = Current private key: +renew.current.key = Generate a new key +otr.close.session.on.window.close = Close OTR session when chat window is closed +otr.close.session.on.contact.off = Close OTR session when contact went offline + + +#Table Columns +otr.table.jid = User's JID +otr.table.public.key = Public key +otr.key.verified = Verified + + diff --git a/src/plugins/otr/src/resources/i18n/otrplugin_i18n_de.properties b/src/plugins/otr/src/resources/i18n/otrplugin_i18n_de.properties new file mode 100644 index 00000000..fa4b6ae0 --- /dev/null +++ b/src/plugins/otr/src/resources/i18n/otrplugin_i18n_de.properties @@ -0,0 +1,3 @@ + +# OTR language file + diff --git a/src/plugins/otr/src/resources/otr_pref.png b/src/plugins/otr/src/resources/otr_pref.png index b06ba749..a8d18a59 100644 Binary files a/src/plugins/otr/src/resources/otr_pref.png and b/src/plugins/otr/src/resources/otr_pref.png differ