SPARK-884 added javadoc to OTR Plugin

git-svn-id: http://svn.igniterealtime.org/svn/repos/spark/trunk@12481 b35dd754-fafc-0310-a699-88a17e54d16e
This commit is contained in:
Holger Bergunde
2011-06-14 12:30:06 +00:00
committed by holger.bergunde
parent bcfe29b519
commit dc20f37795
11 changed files with 332 additions and 180 deletions

View File

@ -1,7 +1,5 @@
package org.jivesoftware.spark.otrplug; package org.jivesoftware.spark.otrplug;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
@ -25,25 +23,27 @@ import org.jivesoftware.spark.ui.ContactItem;
import org.jivesoftware.spark.ui.ContactItemHandler; import org.jivesoftware.spark.ui.ContactItemHandler;
import org.jivesoftware.spark.ui.rooms.ChatRoomImpl; import org.jivesoftware.spark.ui.rooms.ChatRoomImpl;
/**
* OTRManager controls the whole OTR process. It checks if a new chat window is
* opened and creates an OTR session if there is no available.
*
* @author Bergunde Holger
*
*/
public class OTRManager extends ChatRoomListenerAdapter implements ContactItemHandler {
public class OTRManager extends ChatRoomListenerAdapter implements ContactItemHandler {
private static OTRManager singleton; private static OTRManager singleton;
private static Object LOCK = new Object(); private static Object LOCK = new Object();
private Map<String, OTRSession> _activeSessions = new HashMap<String,OTRSession>(); private Map<String, OTRSession> _activeSessions = new HashMap<String, OTRSession>();
final ChatManager chatManager = SparkManager.getChatManager(); final ChatManager chatManager = SparkManager.getChatManager();
private static MyOtrKeyManager _keyManager; private static MyOtrKeyManager _keyManager;
private OTRManager() private OTRManager() {
{
chatManager.addChatRoomListener(this); chatManager.addChatRoomListener(this);
chatManager.addContactItemHandler(this); chatManager.addContactItemHandler(this);
} }
@Override @Override
public void chatRoomOpened(ChatRoom room) { public void chatRoomOpened(ChatRoom room) {
super.chatRoomOpened(room); super.chatRoomOpened(room);
@ -51,7 +51,7 @@ public class OTRManager extends ChatRoomListenerAdapter implements ContactItemH
createOTRSession((ChatRoomImpl) room, ((ChatRoomImpl) room).getParticipantJID()); createOTRSession((ChatRoomImpl) room, ((ChatRoomImpl) room).getParticipantJID());
} }
} }
@Override @Override
public void chatRoomClosed(ChatRoom room) { public void chatRoomClosed(ChatRoom room) {
super.chatRoomClosed(room); super.chatRoomClosed(room);
@ -66,8 +66,12 @@ public class OTRManager extends ChatRoomListenerAdapter implements ContactItemH
} }
} }
} }
/**
* OTRManager is a sigleton. Use this method to get the instance.
*
* @return
*/
public static OTRManager getInstance() { public static OTRManager getInstance() {
// Synchronize on LOCK to ensure that we don't end up creating // Synchronize on LOCK to ensure that we don't end up creating
// two singletons. // two singletons.
@ -76,14 +80,14 @@ public class OTRManager extends ChatRoomListenerAdapter implements ContactItemH
OTRManager controller = new OTRManager(); OTRManager controller = new OTRManager();
singleton = controller; singleton = controller;
try { try {
_keyManager = new MyOtrKeyManager(SparkManager.getUserDirectory().getPath()+"/otrkey.priv"); _keyManager = new MyOtrKeyManager(SparkManager.getUserDirectory().getPath() + "/otrkey.priv");
//we should generate a local keyprint if there is no avaiable // we should generate a local keyprint if there is no
// avaiable
String key = _keyManager.getLocalFingerprint(new SessionID(SparkManager.getConnection().getUser(), "none", "Scytale")); String key = _keyManager.getLocalFingerprint(new SessionID(SparkManager.getConnection().getUser(), "none", "Scytale"));
if (key == null) if (key == null) {
{
_keyManager.generateLocalKeyPair(new SessionID(SparkManager.getConnection().getUser(), "none", "Scytale")); _keyManager.generateLocalKeyPair(new SessionID(SparkManager.getConnection().getUser(), "none", "Scytale"));
} }
} catch (IOException e) { } catch (IOException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
@ -94,67 +98,65 @@ public class OTRManager extends ChatRoomListenerAdapter implements ContactItemH
return singleton; return singleton;
} }
public void startOtrWithUser(String jid) /**
{ * Starts the OTR session with specified JID.
if (_activeSessions.containsKey(jid)) *
{ * @param jid
* participant
*/
public void startOtrWithUser(String jid) {
if (_activeSessions.containsKey(jid)) {
_activeSessions.get(jid).startSession(); _activeSessions.get(jid).startSession();
} }
} }
private void createOTRSession(ChatRoomImpl chatroom, String jid) private void createOTRSession(ChatRoomImpl chatroom, String jid) {
{ if (!_activeSessions.containsKey(jid)) {
if (!_activeSessions.containsKey(jid))
{
_activeSessions.put(jid, startOTRSession(chatroom, jid)); _activeSessions.put(jid, startOTRSession(chatroom, jid));
} else { } else {
_activeSessions.get(jid).updateChatRoom(chatroom); _activeSessions.get(jid).updateChatRoom(chatroom);
} }
} }
public MyOtrKeyManager getKeyManager() /**
{ * Returns the OtrKeyManager to store and load keys
*
* @return
*/
public MyOtrKeyManager getKeyManager() {
return _keyManager; return _keyManager;
} }
private OTRSession startOTRSession(ChatRoomImpl chatroom, String jid) private OTRSession startOTRSession(ChatRoomImpl chatroom, String jid) {
{
return new OTRSession(chatroom, SparkManager.getConnection().getUser(), jid); return new OTRSession(chatroom, SparkManager.getConnection().getUser(), jid);
} }
@Override @Override
public boolean handlePresence(ContactItem item, Presence presence) { public boolean handlePresence(ContactItem item, Presence presence) {
if (OTRProperties.getInstance().getOTRCloseOnDisc()) if (OTRProperties.getInstance().getOTRCloseOnDisc()) {
{ if (!presence.isAvailable() && _activeSessions.containsKey(item.getJID())) {
if (!presence.isAvailable() && _activeSessions.containsKey(item.getJID()))
{
_activeSessions.get(item.getJID()).stopSession(); _activeSessions.get(item.getJID()).stopSession();
} }
} }
return false; return false;
} }
@Override @Override
public Icon getIcon(String jid) { public Icon getIcon(String jid) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
return null; return null;
} }
@Override @Override
public Icon getTabIcon(Presence presence) { public Icon getTabIcon(Presence presence) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
return null; return null;
} }
@Override @Override
public boolean handleDoubleClick(ContactItem item) { public boolean handleDoubleClick(ContactItem item) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
return false; return false;
} }
} }

View File

@ -5,28 +5,32 @@ import org.jivesoftware.spark.otrplug.pref.OTRPreferences;
import org.jivesoftware.spark.plugin.Plugin; import org.jivesoftware.spark.plugin.Plugin;
import org.jivesoftware.spark.preference.Preference; import org.jivesoftware.spark.preference.Preference;
/**
* OTR Plugin
*
* @author Bergunde Holger
*/
public class OTRPlugin implements Plugin {
public class OTRPlugin implements Plugin{ OTRManager _manager;
OTRManager _manager;
@Override @Override
public void initialize() { public void initialize() {
//Create OTRManager singleton // Create OTRManager singleton
_manager = OTRManager.getInstance(); _manager = OTRManager.getInstance();
// The following will add an Entry into the Spark Preferences Window // The following will add an Entry into the Spark Preferences Window
Preference mypreference = new OTRPreferences(); Preference mypreference = new OTRPreferences();
SparkManager.getPreferenceManager().addPreference(mypreference); SparkManager.getPreferenceManager().addPreference(mypreference);
} }
@Override @Override
public void shutdown() { public void shutdown() {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
@Override @Override
@ -38,7 +42,7 @@ public class OTRPlugin implements Plugin{
@Override @Override
public void uninstall() { public void uninstall() {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
} }

View File

@ -30,14 +30,34 @@ import net.java.otr4j.crypto.OtrCryptoEngineImpl;
import net.java.otr4j.crypto.OtrCryptoException; import net.java.otr4j.crypto.OtrCryptoException;
import net.java.otr4j.session.SessionID; import net.java.otr4j.session.SessionID;
/**
* An implementation of the OtrKeyManager provided by otr4j. It stores the local
* key chain
*
* @author Bergunde Holger
*
*/
public class MyOtrKeyManager implements OtrKeyManager { public class MyOtrKeyManager implements OtrKeyManager {
private OtrKeyManagerStore store; private OtrKeyManagerStore store;
/**
* Use this consturctor if you want to use your own implementation for key
* storage
*
* @param store
* Imlementation of OtrKeyManagerStore
*/
public MyOtrKeyManager(OtrKeyManagerStore store) { public MyOtrKeyManager(OtrKeyManagerStore store) {
this.store = store; this.store = store;
} }
/**
* Inner class, own implemented key sotrage
*
* @author Bergunde Holger
*
*/
class DefaultPropertiesStore implements OtrKeyManagerStore { class DefaultPropertiesStore implements OtrKeyManagerStore {
private final Properties properties = new Properties(); private final Properties properties = new Properties();
private String filepath; private String filepath;
@ -112,12 +132,23 @@ public class MyOtrKeyManager implements OtrKeyManager {
} }
} }
/**
* Use this consturctor if key manager should use his own implementation of
* key storage
*
* @param filepath
* file where the keys should be stored
* @throws IOException
*/
public MyOtrKeyManager(String filepath) throws IOException { public MyOtrKeyManager(String filepath) throws IOException {
this.store = new DefaultPropertiesStore(filepath); this.store = new DefaultPropertiesStore(filepath);
} }
private List<OtrKeyManagerListener> listeners = new Vector<OtrKeyManagerListener>(); private List<OtrKeyManagerListener> listeners = new Vector<OtrKeyManagerListener>();
/**
* Adds listener to key manager
*/
public void addListener(OtrKeyManagerListener l) { public void addListener(OtrKeyManagerListener l) {
synchronized (listeners) { synchronized (listeners) {
if (!listeners.contains(l)) if (!listeners.contains(l))
@ -125,12 +156,22 @@ public class MyOtrKeyManager implements OtrKeyManager {
} }
} }
/**
* Remove listener from key manager
*/
public void removeListener(OtrKeyManagerListener l) { public void removeListener(OtrKeyManagerListener l) {
synchronized (listeners) { synchronized (listeners) {
listeners.remove(l); listeners.remove(l);
} }
} }
/**
* Generate a local key pair. Be careful. If there is already an key pair,
* it will override it
*
* @param sessionID
* the sessionID that is identified with the local machine
*/
public void generateLocalKeyPair(SessionID sessionID) { public void generateLocalKeyPair(SessionID sessionID) {
if (sessionID == null) if (sessionID == null)
return; return;
@ -157,6 +198,13 @@ public class MyOtrKeyManager implements OtrKeyManager {
this.store.setProperty(accountID + ".privateKey", pkcs8EncodedKeySpec.getEncoded()); this.store.setProperty(accountID + ".privateKey", pkcs8EncodedKeySpec.getEncoded());
} }
/**
*
* Returns the local finger print for specified session. If there is no
* finger print you might generate one.
*
* @return the local finger print for this sessionID
*/
public String getLocalFingerprint(SessionID sessionID) { public String getLocalFingerprint(SessionID sessionID) {
KeyPair keyPair = loadLocalKeyPair(sessionID); KeyPair keyPair = loadLocalKeyPair(sessionID);
@ -173,6 +221,11 @@ public class MyOtrKeyManager implements OtrKeyManager {
} }
} }
/**
* Return remote finger print for specified sessionID.
*
* @return finger print for remote contact
*/
public String getRemoteFingerprint(SessionID sessionID) { public String getRemoteFingerprint(SessionID sessionID) {
PublicKey remotePublicKey = loadRemotePublicKey(sessionID); PublicKey remotePublicKey = loadRemotePublicKey(sessionID);
if (remotePublicKey == null) if (remotePublicKey == null)
@ -185,6 +238,10 @@ public class MyOtrKeyManager implements OtrKeyManager {
} }
} }
/**
* check if the specified sessionID is verified for this machine
*
*/
public boolean isVerified(SessionID sessionID) { public boolean isVerified(SessionID sessionID) {
if (sessionID == null) if (sessionID == null)
return false; return false;
@ -192,6 +249,12 @@ public class MyOtrKeyManager implements OtrKeyManager {
return this.store.getPropertyBoolean(sessionID.getUserID() + ".publicKey.verified", false); return this.store.getPropertyBoolean(sessionID.getUserID() + ".publicKey.verified", false);
} }
/**
* Returns the key pair (private and public key) for the local machine
*
* @param sessionID
* sessionID for currect machine
*/
public KeyPair loadLocalKeyPair(SessionID sessionID) { public KeyPair loadLocalKeyPair(SessionID sessionID) {
if (sessionID == null) if (sessionID == null)
return null; return null;
@ -231,6 +294,10 @@ public class MyOtrKeyManager implements OtrKeyManager {
return new KeyPair(publicKey, privateKey); return new KeyPair(publicKey, privateKey);
} }
/**
* Loads the public key for the specified sessionID. If there is no key
* stored, you will get 'null'
*/
public PublicKey loadRemotePublicKey(SessionID sessionID) { public PublicKey loadRemotePublicKey(SessionID sessionID) {
if (sessionID == null) if (sessionID == null)
return null; return null;
@ -257,6 +324,14 @@ public class MyOtrKeyManager implements OtrKeyManager {
} }
} }
/**
* Stores the public key for a specified user from sessionID
*
* @param sessionID
* sessionID to identifiy the owner of the key
* @param pubKey
* the key which should be stored
*/
public void savePublicKey(SessionID sessionID, PublicKey pubKey) { public void savePublicKey(SessionID sessionID, PublicKey pubKey) {
if (sessionID == null) if (sessionID == null)
return; return;
@ -269,19 +344,25 @@ public class MyOtrKeyManager implements OtrKeyManager {
this.store.removeProperty(userID + ".publicKey.verified"); this.store.removeProperty(userID + ".publicKey.verified");
} }
/**
* Removes the verification for the specified sessionID
*/
public void unverify(SessionID sessionID) { public void unverify(SessionID sessionID) {
if (sessionID == null) if (sessionID == null)
return; return;
if (!isVerified(sessionID)) if (!isVerified(sessionID))
return; return;
this.store.removeProperty(sessionID.getUserID() + ".publicKey.verified"); this.store.removeProperty(sessionID.getUserID() + ".publicKey.verified");
for (OtrKeyManagerListener l : listeners) for (OtrKeyManagerListener l : listeners)
l.verificationStatusChanged(sessionID); l.verificationStatusChanged(sessionID);
} }
/**
* Verify the specified sessionID
*/
public void verify(SessionID sessionID) { public void verify(SessionID sessionID) {
if (sessionID == null) if (sessionID == null)
return; return;

View File

@ -3,7 +3,6 @@ package org.jivesoftware.spark.otrplug.impl;
import java.awt.Color; import java.awt.Color;
import java.security.KeyPair; import java.security.KeyPair;
import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smack.util.StringUtils; import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.spark.SparkManager; import org.jivesoftware.spark.SparkManager;
@ -14,16 +13,23 @@ import net.java.otr4j.OtrEngineHost;
import net.java.otr4j.OtrPolicy; import net.java.otr4j.OtrPolicy;
import net.java.otr4j.session.SessionID; import net.java.otr4j.session.SessionID;
/**
*
* Implementation of OtrEngineHost provided from otr4j. It handles the message
* injection to specified chat window and handles key pair.
*
* @author Bergunde Holger
*/
public class OTREngineHost implements OtrEngineHost { public class OTREngineHost implements OtrEngineHost {
private ChatRoomImpl _chatRoom; private ChatRoomImpl _chatRoom;
private OtrPolicy _policy; private OtrPolicy _policy;
public OTREngineHost(OtrPolicy policy, ChatRoomImpl chatroom)
{ public OTREngineHost(OtrPolicy policy, ChatRoomImpl chatroom) {
_policy = policy; _policy = policy;
_chatRoom = chatroom; _chatRoom = chatroom;
} }
@Override @Override
public KeyPair getKeyPair(SessionID arg0) { public KeyPair getKeyPair(SessionID arg0) {
return OTRManager.getInstance().getKeyManager().loadLocalKeyPair(arg0); return OTRManager.getInstance().getKeyManager().loadLocalKeyPair(arg0);
@ -35,11 +41,11 @@ public class OTREngineHost implements OtrEngineHost {
} }
@Override @Override
public void injectMessage(SessionID arg0, String arg1) { public void injectMessage(SessionID arg0, String arg1) {
Message injection = new Message(); Message injection = new Message();
injection.setType(Message.Type.chat); injection.setType(Message.Type.chat);
injection.setTo(_chatRoom.getParticipantJID()); injection.setTo(_chatRoom.getParticipantJID());
injection.setFrom(SparkManager.getSessionManager().getJID()); injection.setFrom(SparkManager.getSessionManager().getJID());
String threadID = StringUtils.randomString(6); String threadID = StringUtils.randomString(6);
injection.setThread(threadID); injection.setThread(threadID);
injection.setBody(arg1); injection.setBody(arg1);

View File

@ -26,6 +26,12 @@ import net.java.otr4j.OtrPolicyImpl;
import net.java.otr4j.session.SessionID; import net.java.otr4j.session.SessionID;
import net.java.otr4j.session.SessionStatus; import net.java.otr4j.session.SessionStatus;
/**
* OTRSession are unique for every conversation. It handles the otrEngine for
* the chat and controls if the chat is encrypted or not.
*
* @author Bergunde Holger
*/
public class OTRSession { public class OTRSession {
private ChatRoomImpl _chatRoom; private ChatRoomImpl _chatRoom;
@ -41,6 +47,16 @@ public class OTRSession {
private boolean _OtrEnabled = false; private boolean _OtrEnabled = false;
private OtrEngineListener _otrListener; private OtrEngineListener _otrListener;
/**
* OTRSession Constructor
*
* @param chatroom
* chat room related to this OTR session
* @param myJID
* my own JID
* @param remoteJID
* the JID of the participant
*/
public OTRSession(ChatRoomImpl chatroom, String myJID, String remoteJID) { public OTRSession(ChatRoomImpl chatroom, String myJID, String remoteJID) {
_chatRoom = chatroom; _chatRoom = chatroom;
_myJID = myJID; _myJID = myJID;
@ -50,33 +66,36 @@ public class OTRSession {
_engine = new OtrEngineImpl(_otrEngineHost); _engine = new OtrEngineImpl(_otrEngineHost);
setUpMessageListener(); setUpMessageListener();
createButton(); createButton();
//Only initialize the actionListener once
_otrButton.addActionListener(
new ActionListener() {
@Override // Only initialize the actionListener once
public void actionPerformed(ActionEvent e) { _otrButton.addActionListener(new ActionListener() {
if (_engine.getSessionStatus(_mySession).equals(SessionStatus.ENCRYPTED)) {
stopSession(); @Override
} else { public void actionPerformed(ActionEvent e) {
startSession(); if (_engine.getSessionStatus(_mySession).equals(SessionStatus.ENCRYPTED)) {
} stopSession();
} else {
startSession();
}
}
});
}
});
_otrButton.setToolTipText(OTRResources.getString("otr.chat.button.tooltip")); _otrButton.setToolTipText(OTRResources.getString("otr.chat.button.tooltip"));
_OtrEnabled = OTRProperties.getInstance().getIsOTREnabled(); _OtrEnabled = OTRProperties.getInstance().getIsOTREnabled();
} }
/**
* Maybe you want to update the chat room because it was reopend but the OTR
* session is still alive.
*
* @param chatroom
* the chat room related to this OTR session
*/
public void updateChatRoom(ChatRoomImpl chatroom) { public void updateChatRoom(ChatRoomImpl chatroom) {
_OtrEnabled = OTRProperties.getInstance().getIsOTREnabled(); _OtrEnabled = OTRProperties.getInstance().getIsOTREnabled();
_chatRoom = chatroom; _chatRoom = chatroom;
@ -117,14 +136,13 @@ public class OTRSession {
} }
message.setBody(old); message.setBody(old);
} }
} else if (!_OtrEnabled) } else if (!_OtrEnabled) {
{
String old = message.getBody(); String old = message.getBody();
message.setBody(null); message.setBody(null);
if (old.length() > 3 && old.substring(0, 4).equals("?OTR")) { if (old.length() > 3 && old.substring(0, 4).equals("?OTR")) {
_chatRoom.getTranscriptWindow().insertNotificationMessage(OTRResources.getString("otr.not.enabled"), Color.gray); _chatRoom.getTranscriptWindow().insertNotificationMessage(OTRResources.getString("otr.not.enabled"), Color.gray);
} else { } else {
message.setBody(old); message.setBody(old);
} }
} }
@ -141,23 +159,22 @@ public class OTRSession {
ImageIcon otricon = null; ImageIcon otricon = null;
if (_engine.getSessionStatus(_mySession).equals(SessionStatus.ENCRYPTED)) { if (_engine.getSessionStatus(_mySession).equals(SessionStatus.ENCRYPTED)) {
otricon = new ImageIcon(cl.getResource("otr_on.png")); otricon = new ImageIcon(cl.getResource("otr_on.png"));
_conPanel.sucessfullyCon(); _conPanel.successfullyCon();
} else { } else {
otricon = new ImageIcon(cl.getResource("otr_off.png")); otricon = new ImageIcon(cl.getResource("otr_off.png"));
} }
_otrButton.setIcon(otricon); _otrButton.setIcon(otricon);
_engine.removeOtrEngineListener(_otrListener); _engine.removeOtrEngineListener(_otrListener);
_chatRoom.getToolBar().addChatRoomButton(_otrButton); _chatRoom.getToolBar().addChatRoomButton(_otrButton);
_otrListener = new OtrEngineListener() { _otrListener = new OtrEngineListener() {
@Override @Override
public void sessionStatusChanged(SessionID arg0) { public void sessionStatusChanged(SessionID arg0) {
if (_engine.getSessionStatus(_mySession).equals(SessionStatus.ENCRYPTED)) { if (_engine.getSessionStatus(_mySession).equals(SessionStatus.ENCRYPTED)) {
_conPanel.sucessfullyCon(); _conPanel.successfullyCon();
String otrkey = _manager.getKeyManager().getRemoteFingerprint(_mySession); String otrkey = _manager.getKeyManager().getRemoteFingerprint(_mySession);
if (otrkey == null) { if (otrkey == null) {
PublicKey pubkey = _engine.getRemotePublicKey(_mySession); PublicKey pubkey = _engine.getRemotePublicKey(_mySession);
@ -191,14 +208,20 @@ public class OTRSession {
} }
} }
/**
* Start the OTR session manually from outside
*/
public void startSession() { public void startSession() {
_conPanel.tryToStart(); _conPanel.tryToStart();
_engine.startSession(_mySession); _engine.startSession(_mySession);
} }
/**
* Stop the OTR session manually from outside
*/
public void stopSession() { public void stopSession() {
_conPanel.connectionClosed(); _conPanel.connectionClosed();
if (_engine.getSessionStatus(_mySession).equals(SessionStatus.ENCRYPTED)) { if (_engine.getSessionStatus(_mySession).equals(SessionStatus.ENCRYPTED)) {
final ClassLoader cl = getClass().getClassLoader(); final ClassLoader cl = getClass().getClassLoader();
_otrButton.setIcon(new ImageIcon(cl.getResource("otr_off.png"))); _otrButton.setIcon(new ImageIcon(cl.getResource("otr_off.png")));
_engine.endSession(_mySession); _engine.endSession(_mySession);

View File

@ -4,8 +4,6 @@ import java.awt.BorderLayout;
import java.util.Vector; import java.util.Vector;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JScrollPane; import javax.swing.JScrollPane;
import javax.swing.JTable; import javax.swing.JTable;
@ -15,7 +13,12 @@ import javax.swing.table.DefaultTableModel;
import org.jivesoftware.spark.otrplug.util.OTRResources; import org.jivesoftware.spark.otrplug.util.OTRResources;
/**
* OTRKeyTable displays a key table. You can add keys using the addEntry()
* mathod
*
* @author Bergunde Holger
*/
public class OTRKeyTable extends JPanel { public class OTRKeyTable extends JPanel {
/** /**
@ -32,7 +35,7 @@ public class OTRKeyTable extends JPanel {
_tableModel = new MyTableModel(header); _tableModel = new MyTableModel(header);
_table = new JTable(_tableModel); _table = new JTable(_tableModel);
_table.getTableHeader().setReorderingAllowed(false); _table.getTableHeader().setReorderingAllowed(false);
this.setLayout(new BorderLayout()); this.setLayout(new BorderLayout());
this.add(new JScrollPane(_table), BorderLayout.CENTER); this.add(new JScrollPane(_table), BorderLayout.CENTER);
@ -70,6 +73,13 @@ public class OTRKeyTable extends JPanel {
_tableModel.addTableModelListener(listener); _tableModel.addTableModelListener(listener);
} }
/**
* Adds a key to the table
*
* @param jid
* @param hash
* @param verified
*/
public void addEntry(String jid, String hash, boolean verified) { public void addEntry(String jid, String hash, boolean verified) {
Vector<Object> data = new Vector<Object>(3); Vector<Object> data = new Vector<Object>(3);
@ -80,6 +90,12 @@ public class OTRKeyTable extends JPanel {
_tableModel.addRow(data); _tableModel.addRow(data);
} }
/**
* Returns a specified row
*
* @param row
* @param col
*/
public Object getValueAt(int row, int col) { public Object getValueAt(int row, int col) {
return _tableModel.getValueAt(row, col); return _tableModel.getValueAt(row, col);
} }

View File

@ -27,11 +27,15 @@ import org.jivesoftware.spark.otrplug.impl.MyOtrKeyManager;
import org.jivesoftware.spark.otrplug.util.OTRProperties; import org.jivesoftware.spark.otrplug.util.OTRProperties;
import org.jivesoftware.spark.otrplug.util.OTRResources; import org.jivesoftware.spark.otrplug.util.OTRResources;
/**
*
* OTR preference panel for Spark Preferences
*
* @author Bergund Holger
*
*/
public class OTRPrefPanel extends JPanel { public class OTRPrefPanel extends JPanel {
/**
*
*/
private static final long serialVersionUID = -7125162190413040003L; private static final long serialVersionUID = -7125162190413040003L;
private OTRManager _manager; private OTRManager _manager;
private JCheckBox _enableOTR; private JCheckBox _enableOTR;
@ -43,7 +47,7 @@ public class OTRPrefPanel extends JPanel {
private JTextField _privateKey; private JTextField _privateKey;
private MyOtrKeyManager _keyManager; private MyOtrKeyManager _keyManager;
private OTRProperties _properties; private OTRProperties _properties;
public OTRPrefPanel() { public OTRPrefPanel() {
_manager = OTRManager.getInstance(); _manager = OTRManager.getInstance();
@ -56,8 +60,7 @@ public class OTRPrefPanel extends JPanel {
} }
private void OtrEnableSwitch() { private void OtrEnableSwitch() {
if (!_enableOTR.isSelected()) if (!_enableOTR.isSelected()) {
{
_closeSessionOff.setEnabled(false); _closeSessionOff.setEnabled(false);
_closeSessionOnWindowClose.setEnabled(false); _closeSessionOnWindowClose.setEnabled(false);
_renewPrivateKey.setEnabled(false); _renewPrivateKey.setEnabled(false);
@ -75,23 +78,23 @@ public class OTRPrefPanel extends JPanel {
_enableOTR = new JCheckBox(); _enableOTR = new JCheckBox();
_enableOTR.setText(OTRResources.getString("otr.enable")); _enableOTR.setText(OTRResources.getString("otr.enable"));
_enableOTR.setSelected(_properties.getIsOTREnabled()); _enableOTR.setSelected(_properties.getIsOTREnabled());
_enableOTR.addActionListener(new ActionListener() { _enableOTR.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
OtrEnableSwitch(); OtrEnableSwitch();
} }
}); });
_closeSessionOff = new JCheckBox(); _closeSessionOff = new JCheckBox();
_closeSessionOff.setText(OTRResources.getString("otr.close.session.on.contact.off")); _closeSessionOff.setText(OTRResources.getString("otr.close.session.on.contact.off"));
_closeSessionOff.setSelected(_properties.getOTRCloseOnDisc()); _closeSessionOff.setSelected(_properties.getOTRCloseOnDisc());
_closeSessionOnWindowClose = new JCheckBox(); _closeSessionOnWindowClose = new JCheckBox();
_closeSessionOnWindowClose.setText(OTRResources.getString("otr.close.session.on.window.close")); _closeSessionOnWindowClose.setText(OTRResources.getString("otr.close.session.on.window.close"));
_closeSessionOnWindowClose.setSelected(_properties.getOTRCloseOnChatClose()); _closeSessionOnWindowClose.setSelected(_properties.getOTRCloseOnChatClose());
_currentKeyLabel = new JLabel(); _currentKeyLabel = new JLabel();
_currentKeyLabel.setText(OTRResources.getString("current.priv.key")); _currentKeyLabel.setText(OTRResources.getString("current.priv.key"));
@ -115,12 +118,8 @@ public class OTRPrefPanel extends JPanel {
loadRemoteKeys(); loadRemoteKeys();
} }
private void loadRemoteKeys() { private void loadRemoteKeys() {
for (RosterEntry entry : SparkManager.getConnection().getRoster().getEntries()) { for (RosterEntry entry : SparkManager.getConnection().getRoster().getEntries()) {
@ -141,58 +140,53 @@ public class OTRPrefPanel extends JPanel {
if (col == 2) { if (col == 2) {
boolean selection = (Boolean) _keytable.getValueAt(row, col); boolean selection = (Boolean) _keytable.getValueAt(row, col);
String JID = (String)_keytable.getValueAt(row, 0); String JID = (String) _keytable.getValueAt(row, 0);
SessionID curSelectedSession = new SessionID(SparkManager.getConnection().getUser(), JID, "Scytale"); SessionID curSelectedSession = new SessionID(SparkManager.getConnection().getUser(), JID, "Scytale");
if (!selection) { if (!selection) {
_keyManager.verify(curSelectedSession); _keyManager.verify(curSelectedSession);
} else } else {
{
_keyManager.unverify(curSelectedSession); _keyManager.unverify(curSelectedSession);
} }
} }
} }
}); });
} }
private void buildGUI() { private void buildGUI() {
this.setBorder(BorderFactory.createTitledBorder(OTRResources.getString("otr.settings"))); this.setBorder(BorderFactory.createTitledBorder(OTRResources.getString("otr.settings")));
this.add(_enableOTR, new GridBagConstraints(0, 0, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); this.add(_enableOTR, new GridBagConstraints(0, 0, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
this.add(_closeSessionOff, new GridBagConstraints(0, 1, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(10, 0, 0, 0), 0, 0)); this.add(_closeSessionOff, new GridBagConstraints(0, 1, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(10, 0, 0, 0), 0, 0));
this.add(_closeSessionOnWindowClose, new GridBagConstraints(0, 2, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); this.add(_closeSessionOnWindowClose,
new GridBagConstraints(0, 2, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
this.add(_currentKeyLabel, new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(10, 5, 0, 0), 0, 0)); this.add(_currentKeyLabel, new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(10, 5, 0, 0), 0, 0));
this.add(_privateKey, new GridBagConstraints(1, 3, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(10, 0, 0, 5), 0, 0)); this.add(_privateKey, new GridBagConstraints(1, 3, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(10, 0, 0, 5), 0, 0));
this.add(_renewPrivateKey, new GridBagConstraints(1, 4, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHEAST, GridBagConstraints.NONE, new Insets(0, 0, 0, 5), 0, 0)); this.add(_renewPrivateKey, new GridBagConstraints(1, 4, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHEAST, GridBagConstraints.NONE, new Insets(0, 0, 0, 5), 0, 0));
this.add(_keytable, new GridBagConstraints(0, 5, 2, 1, 1.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(20, 5, 10, 5), 0, 0)); this.add(_keytable, new GridBagConstraints(0, 5, 2, 1, 1.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(20, 5, 10, 5), 0, 0));
} }
private String getCurrentLocalKey() { private String getCurrentLocalKey() {
SessionID mySession = new SessionID(SparkManager.getConnection().getUser(), "no one", "Scytale"); SessionID mySession = new SessionID(SparkManager.getConnection().getUser(), "no one", "Scytale");
String myKey = _keyManager.getLocalFingerprint(mySession); String myKey = _keyManager.getLocalFingerprint(mySession);
return myKey; return myKey;
} }
public JComponent getGUI() { public JComponent getGUI() {
_keytable = new OTRKeyTable(); _keytable = new OTRKeyTable();
loadRemoteKeys(); loadRemoteKeys();
return this; return this;
} }
public boolean isOTREnabled() {
public boolean isOTREnabled()
{
return _enableOTR.isSelected(); return _enableOTR.isSelected();
} }
public boolean isCloseOnDisc() public boolean isCloseOnDisc() {
{
return _closeSessionOff.isSelected(); return _closeSessionOff.isSelected();
} }
public boolean isCloseOnChatClose()
{ public boolean isCloseOnChatClose() {
return _closeSessionOnWindowClose.isSelected(); return _closeSessionOnWindowClose.isSelected();
} }
} }

View File

@ -3,15 +3,19 @@ package org.jivesoftware.spark.otrplug.pref;
import javax.swing.Icon; import javax.swing.Icon;
import javax.swing.JComponent; import javax.swing.JComponent;
import org.jivesoftware.spark.otrplug.util.OTRProperties; import org.jivesoftware.spark.otrplug.util.OTRProperties;
import org.jivesoftware.spark.otrplug.util.OTRResources; import org.jivesoftware.spark.otrplug.util.OTRResources;
import org.jivesoftware.spark.preference.Preference; import org.jivesoftware.spark.preference.Preference;
/**
* Implementation of Preference interface provided by Spark
*
* @author Bergunde Holger
*/
public class OTRPreferences implements Preference { public class OTRPreferences implements Preference {
private OTRPrefPanel pref = new OTRPrefPanel(); private OTRPrefPanel pref = new OTRPrefPanel();
@Override @Override
public String getTitle() { public String getTitle() {
return OTRResources.getString("otr.title"); return OTRResources.getString("otr.title");
@ -24,13 +28,12 @@ public class OTRPreferences implements Preference {
@Override @Override
public String getTooltip() { public String getTooltip() {
// TODO Auto-generated method stub return OTRResources.getString("otr.title");
return null;
} }
@Override @Override
public String getListName() { public String getListName() {
return OTRResources.getString("otr.list.entry"); return OTRResources.getString("otr.list.entry");
} }

View File

@ -23,6 +23,12 @@ import org.jivesoftware.spark.otrplug.util.OTRResources;
import org.jivesoftware.spark.ui.TranscriptWindow; import org.jivesoftware.spark.ui.TranscriptWindow;
import org.jivesoftware.spark.ui.rooms.ChatRoomImpl; import org.jivesoftware.spark.ui.rooms.ChatRoomImpl;
/**
* Shows StyledDocuments in transcript window for info if the session
* established successfully or not
*
* @author Bergunde Holger
*/
public class OTRConnectionPanel { public class OTRConnectionPanel {
private ChatRoomImpl _chatRoom; private ChatRoomImpl _chatRoom;
@ -30,7 +36,7 @@ public class OTRConnectionPanel {
private ImageIcon _icon; private ImageIcon _icon;
private JPanel _conPanel; private JPanel _conPanel;
private int _i; private int _i;
private StyledDocument _doc; private StyledDocument _doc;
private TranscriptWindow _transcriptWindow; private TranscriptWindow _transcriptWindow;
private JButton _retry; private JButton _retry;
private boolean _succesfull = false; private boolean _succesfull = false;
@ -39,32 +45,36 @@ public class OTRConnectionPanel {
public OTRConnectionPanel(ChatRoomImpl chatroom) { public OTRConnectionPanel(ChatRoomImpl chatroom) {
_chatRoom = chatroom; _chatRoom = chatroom;
_transcriptWindow = _chatRoom.getTranscriptWindow(); _transcriptWindow = _chatRoom.getTranscriptWindow();
_doc = _transcriptWindow.getStyledDocument(); _doc = _transcriptWindow.getStyledDocument();
_retry = new JButton(OTRResources.getString("otr.retry")); _retry = new JButton(OTRResources.getString("otr.retry"));
_retry.addActionListener(new ActionListener() { _retry.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
OTRManager.getInstance().startOtrWithUser(_chatRoom.getParticipantJID()); OTRManager.getInstance().startOtrWithUser(_chatRoom.getParticipantJID());
} }
}); });
_retry.setVisible(false);
_retry.setVisible(false);
} }
/**
* Indicates that OTR is trying to establish an OTR session. This will
* inject a styledDocument. You have 10 seconds to approve that the
* connection was successful using method successfullyCon()
*
*/
public void tryToStart() { public void tryToStart() {
if (!_succesfull && !_waiting) { if (!_succesfull && !_waiting) {
renewPanel(); renewPanel();
_icon.setImage(SparkRes.getImageIcon(SparkRes.BUSY_IMAGE).getImage()); _icon.setImage(SparkRes.getImageIcon(SparkRes.BUSY_IMAGE).getImage());
_conPanel.setVisible(true); _conPanel.setVisible(true);
_i = 10; _i = 10;
_label.setText(OTRResources.getString("otr.try.to.connect.for.seconds",_i)); _label.setText(OTRResources.getString("otr.try.to.connect.for.seconds", _i));
Timer t = new Timer(); Timer t = new Timer();
TimerTask task = new TimerTask() { TimerTask task = new TimerTask() {
@ -74,14 +84,14 @@ public class OTRConnectionPanel {
if (_i > 0 && !_succesfull) { if (_i > 0 && !_succesfull) {
_waiting = true; _waiting = true;
_label.setText(OTRResources.getString("otr.try.to.connect.for.seconds",_i)); _label.setText(OTRResources.getString("otr.try.to.connect.for.seconds", _i));
decI(); decI();
} else if (!_succesfull) { } else if (!_succesfull) {
_waiting = true; _waiting = true;
_icon.setImage(SparkRes.getImageIcon(SparkRes.SMALL_DELETE).getImage()); _icon.setImage(SparkRes.getImageIcon(SparkRes.SMALL_DELETE).getImage());
_label.setText(OTRResources.getString("otr.failed.to.establish",_i)); _label.setText(OTRResources.getString("otr.failed.to.establish", _i));
_retry.setVisible(true); _retry.setVisible(true);
this.cancel(); this.cancel();
} else { } else {
this.cancel(); this.cancel();
@ -99,20 +109,23 @@ public class OTRConnectionPanel {
_conPanel.add(new JLabel(_icon), new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 10, 0, 0), 0, 0)); _conPanel.add(new JLabel(_icon), new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 10, 0, 0), 0, 0));
_conPanel.add(_label, new GridBagConstraints(1, 0, 1, 1, 0.7, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 15, 0, 0), 0, 0)); _conPanel.add(_label, new GridBagConstraints(1, 0, 1, 1, 0.7, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 15, 0, 0), 0, 0));
_conPanel.add(_retry,new GridBagConstraints(2, 0, 1, 1, 2.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 10, 0, 0), 0, 0)); _conPanel.add(_retry, new GridBagConstraints(2, 0, 1, 1, 2.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 10, 0, 0), 0, 0));
Style style = _doc.addStyle("OTRStyle", null); Style style = _doc.addStyle("OTRStyle", null);
StyleConstants.setComponent(style, _conPanel); StyleConstants.setComponent(style, _conPanel);
try { try {
_doc.insertString(_doc.getLength(), "ignored text", style); _doc.insertString(_doc.getLength(), "ignored text", style);
_doc.insertString(_doc.getLength(), "\n", null); _doc.insertString(_doc.getLength(), "\n", null);
} catch (BadLocationException e) { } catch (BadLocationException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
} }
} }
/**
* Indicates in the transcript window, that the OTR session has been closed
*/
public void connectionClosed() { public void connectionClosed() {
if (_succesfull) { if (_succesfull) {
renewPanel(); renewPanel();
@ -126,13 +139,12 @@ public class OTRConnectionPanel {
private void decI() { private void decI() {
--_i; --_i;
} }
public void setConnected(boolean con)
{
_succesfull = con;
}
public void sucessfullyCon() { /**
* Should be called after you called tryToStart(). It will indicate that the
* session is now encrypted
*/
public void successfullyCon() {
if (!_succesfull) { if (!_succesfull) {
if (!_waiting) if (!_waiting)
renewPanel(); renewPanel();

View File

@ -1,4 +1,3 @@
package org.jivesoftware.spark.otrplug.util; package org.jivesoftware.spark.otrplug.util;
import java.io.File; import java.io.File;
@ -17,12 +16,13 @@ import org.jivesoftware.spark.SparkManager;
public class OTRProperties { public class OTRProperties {
private Properties props; private Properties props;
private File configFile; private File configFile;
private static final Object LOCK = new Object(); private static final Object LOCK = new Object();
private static OTRProperties instance = null; private static OTRProperties instance = null;
/** /**
* returns the Instance of this Properties file * returns the Instance of this Properties file
*
* @return * @return
*/ */
public static OTRProperties getInstance() { public static OTRProperties getInstance() {
@ -54,40 +54,33 @@ public class OTRProperties {
public void save() { public void save() {
try { try {
props.store(new FileOutputStream(getConfigFile()), props.store(new FileOutputStream(getConfigFile()), "Storing OTRPlugin properties");
"Storing OTRPlugin properties");
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
public boolean getIsOTREnabled() public boolean getIsOTREnabled() {
{
return getBoolean("isOTREnabeld", true); return getBoolean("isOTREnabeld", true);
} }
public void setIsOTREnabled(boolean enabled) public void setIsOTREnabled(boolean enabled) {
{
setBoolean("isOTREnabeld", enabled); setBoolean("isOTREnabeld", enabled);
} }
public boolean getOTRCloseOnDisc() public boolean getOTRCloseOnDisc() {
{
return getBoolean("OTRCloseOnDisc", true); return getBoolean("OTRCloseOnDisc", true);
} }
public void setOTRCloseOnDisc(boolean enabled) public void setOTRCloseOnDisc(boolean enabled) {
{
setBoolean("OTRCloseOnDisc", enabled); setBoolean("OTRCloseOnDisc", enabled);
} }
public boolean getOTRCloseOnChatClose() public boolean getOTRCloseOnChatClose() {
{
return getBoolean("OTRCloseOnChatClose", false); return getBoolean("OTRCloseOnChatClose", false);
} }
public void setOTRCloseOnChatClose(boolean enabled) public void setOTRCloseOnChatClose(boolean enabled) {
{
setBoolean("OTRCloseOnChatClose", enabled); setBoolean("OTRCloseOnChatClose", enabled);
} }
@ -95,8 +88,7 @@ public class OTRProperties {
// =============================================================================== // ===============================================================================
// =============================================================================== // ===============================================================================
private boolean getBoolean(String property, boolean defaultValue) { private boolean getBoolean(String property, boolean defaultValue) {
return Boolean.parseBoolean(props.getProperty(property, return Boolean.parseBoolean(props.getProperty(property, Boolean.toString(defaultValue)));
Boolean.toString(defaultValue)));
} }
private void setBoolean(String property, boolean value) { private void setBoolean(String property, boolean value) {
@ -115,4 +107,4 @@ public class OTRProperties {
return props.getProperty(property); return props.getProperty(property);
} }
} }

View File

@ -1,5 +1,10 @@
package org.jivesoftware.spark.otrplug.util; package org.jivesoftware.spark.otrplug.util;
/**
* OTRResources needed to load icons and language files into OTR plugin
*
* @author Bergunde Holger
*/
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.PropertyResourceBundle; import java.util.PropertyResourceBundle;
import java.util.ResourceBundle; import java.util.ResourceBundle;
@ -18,6 +23,12 @@ public class OTRResources {
prb = (PropertyResourceBundle) ResourceBundle.getBundle("i18n/otrplugin_i18n"); prb = (PropertyResourceBundle) ResourceBundle.getBundle("i18n/otrplugin_i18n");
} }
/**
* Returns a string from the language file
*
* @param propertyName
* @return
*/
public static final String getString(String propertyName) { public static final String getString(String propertyName) {
try { try {
return prb.getString(propertyName); return prb.getString(propertyName);
@ -26,23 +37,31 @@ public class OTRResources {
return propertyName; return propertyName;
} }
} }
/**
public static ImageIcon getIcon(String fileName) * Returns an ImageIcon from OTR resources folder
{ *
* @param fileName
* @return
*/
public static ImageIcon getIcon(String fileName) {
final ClassLoader cl = OTRResources.class.getClassLoader(); final ClassLoader cl = OTRResources.class.getClassLoader();
ImageIcon icon = new ImageIcon(cl.getResource(fileName)); ImageIcon icon = new ImageIcon(cl.getResource(fileName));
return icon; return icon;
} }
/**
* Returns a string with wildcards
*
* @param propertyName
* @param obj
*/
public static String getString(String propertyName, Object... obj) { public static String getString(String propertyName, Object... obj) {
String str = prb.getString(propertyName); String str = prb.getString(propertyName);
if (str == null) { if (str == null) {
return propertyName; return propertyName;
} }
return MessageFormat.format(str, obj); return MessageFormat.format(str, obj);
} }