diff options
author | Marin <m.dzhigarov@gmail.com> | 2013-10-21 15:24:19 +0300 |
---|---|---|
committer | Marin <m.dzhigarov@gmail.com> | 2013-11-07 09:21:32 +0200 |
commit | 88bc48e9b121685f11e3a36b13a7ce0d79b0044d (patch) | |
tree | 5ac80d3c172833083246cddb4536a57e93f9e87e /src/net/java/sip | |
parent | a7e685476c1bd29b9feb50afbc3a791d257041a6 (diff) | |
download | jitsi-88bc48e9b121685f11e3a36b13a7ce0d79b0044d.zip jitsi-88bc48e9b121685f11e3a36b13a7ce0d79b0044d.tar.gz jitsi-88bc48e9b121685f11e3a36b13a7ce0d79b0044d.tar.bz2 |
Added support for SMP for the OTR plugin.
Diffstat (limited to 'src/net/java/sip')
10 files changed, 1278 insertions, 204 deletions
diff --git a/src/net/java/sip/communicator/plugin/otr/CustomTextArea.java b/src/net/java/sip/communicator/plugin/otr/CustomTextArea.java new file mode 100644 index 0000000..00aa7d1 --- /dev/null +++ b/src/net/java/sip/communicator/plugin/otr/CustomTextArea.java @@ -0,0 +1,26 @@ +package net.java.sip.communicator.plugin.otr; + +import java.awt.*; + +import javax.swing.*; + +/** + * A special {@link JTextArea} for use in the OTR authentication panels. + * It is meant to be used for fingerprint representation and general + * information display. + * + * @author George Politis + */ + public class CustomTextArea + extends JTextArea + { + public CustomTextArea() + { + this.setBackground(new Color(0,0,0,0)); + this.setOpaque(false); + this.setColumns(20); + this.setEditable(false); + this.setLineWrap(true); + this.setWrapStyleWord(true); + } + }
\ No newline at end of file diff --git a/src/net/java/sip/communicator/plugin/otr/FingerprintAuthenticationPanel.java b/src/net/java/sip/communicator/plugin/otr/FingerprintAuthenticationPanel.java new file mode 100644 index 0000000..70ef5d8 --- /dev/null +++ b/src/net/java/sip/communicator/plugin/otr/FingerprintAuthenticationPanel.java @@ -0,0 +1,257 @@ +/* + * Jitsi, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. + * See terms of license at gnu.org. + */ +package net.java.sip.communicator.plugin.otr; + +import java.awt.*; + +import javax.swing.*; +import javax.swing.event.*; + +import net.java.sip.communicator.plugin.desktoputil.*; +import net.java.sip.communicator.service.protocol.*; + +/** + * @author George Politis + * @author Marin Dzhigarov + */ +@SuppressWarnings("serial") +public class FingerprintAuthenticationPanel + extends TransparentPanel + implements DocumentListener +{ + + /** + * The Contact that we are authenticating. + */ + private final Contact contact; + + private SIPCommTextField txtRemoteFingerprintComparison; + + /** + * Our fingerprint. + */ + private JTextArea txtLocalFingerprint; + + /** + * The purported fingerprint of the remote party. + */ + private JTextArea txtRemoteFingerprint; + + /** + * The "I have" / "I have not" combo box. + */ + private JComboBox cbAction; + + private ActionComboBoxItem actionIHave = + new ActionComboBoxItem(ActionComboBoxItemIndex.I_HAVE); + + private ActionComboBoxItem actionIHaveNot = + new ActionComboBoxItem(ActionComboBoxItemIndex.I_HAVE_NOT); + + private JTextArea txtAction; + + /** + * Creates an instance FingerprintAuthenticationPanel + * + * @param contact The contact that this panel refers to. + */ + FingerprintAuthenticationPanel(Contact contact) + { + this.contact = contact; + initComponents(); + loadContact(); + + } + + /** + * Initializes the {@link FingerprintAuthenticationPanel} components. + */ + private void initComponents() + { + setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + setPreferredSize(new Dimension(350, 300)); + + JTextArea generalInformation = new CustomTextArea(); + generalInformation.setText(OtrActivator.resourceService + .getI18NString( + "plugin.otr.authbuddydialog.AUTHENTICATION_FINGERPRINT")); + this.add(generalInformation); + + add(Box.createVerticalStrut(10)); + + txtLocalFingerprint = new CustomTextArea(); + this.add(txtLocalFingerprint); + + add(Box.createVerticalStrut(10)); + + txtRemoteFingerprint = new CustomTextArea(); + this.add(txtRemoteFingerprint); + + add(Box.createVerticalStrut(10)); + + // Action Panel (the panel that holds the I have/I have not dropdown) + JPanel pnlAction = new JPanel(new GridBagLayout()); + pnlAction.setBorder(BorderFactory.createEtchedBorder()); + this.add(pnlAction); + + GridBagConstraints c = new GridBagConstraints(); + c.fill = GridBagConstraints.HORIZONTAL; + c.insets = new Insets(5, 5, 5, 5); + c.weightx = 0.0; + + setCbAction(new JComboBox()); + getCbAction().addItem(actionIHave); + getCbAction().addItem(actionIHaveNot); + getCbAction().setSelectedItem(OtrActivator.scOtrKeyManager + .isVerified(contact) ? actionIHave : actionIHaveNot); + + pnlAction.add(getCbAction(), c); + + txtAction = new CustomTextArea(); + c.weightx = 1.0; + pnlAction.add(txtAction, c); + + txtRemoteFingerprintComparison = new SIPCommTextField( + OtrActivator.resourceService + .getI18NString("plugin.otr.authbuddydialog.FINGERPRINT_CHECK", + new String[]{contact.getDisplayName()})); + txtRemoteFingerprintComparison.getDocument().addDocumentListener(this); + + c.gridwidth = 2; + c.gridy = 1; + pnlAction.add(txtRemoteFingerprintComparison, c); + c.gridwidth = 1; + c.gridy = 0; + } + + /** + * Sets up the {@link OtrBuddyAuthenticationDialog} components so that they + * reflect the {@link OtrBuddyAuthenticationDialog#contact} + */ + private void loadContact() + { + // Local fingerprint. + String account = + contact.getProtocolProvider().getAccountID().getDisplayName(); + String localFingerprint = + OtrActivator.scOtrKeyManager.getLocalFingerprint(contact + .getProtocolProvider().getAccountID()); + txtLocalFingerprint.setText(OtrActivator.resourceService.getI18NString( + "plugin.otr.authbuddydialog.LOCAL_FINGERPRINT", new String[] + { account, localFingerprint })); + + // Remote fingerprint. + String user = contact.getDisplayName(); + String remoteFingerprint = + OtrActivator.scOtrKeyManager.getRemoteFingerprint(contact); + txtRemoteFingerprint.setText(OtrActivator.resourceService + .getI18NString("plugin.otr.authbuddydialog.REMOTE_FINGERPRINT", + new String[] + { user, remoteFingerprint })); + + // Action + txtAction.setText(OtrActivator.resourceService.getI18NString( + "plugin.otr.authbuddydialog.VERIFY_ACTION", new String[] + { user })); + } + + public void removeUpdate(DocumentEvent e) + { + compareFingerprints(); + } + + public void insertUpdate(DocumentEvent e) + { + compareFingerprints(); + } + + public void changedUpdate(DocumentEvent e) + { + compareFingerprints(); + } + + public void compareFingerprints() + { + if(txtRemoteFingerprintComparison.getText() == null + || txtRemoteFingerprintComparison.getText().length() == 0) + { + txtRemoteFingerprintComparison.setBackground(Color.white); + return; + } + if(txtRemoteFingerprintComparison.getText().toLowerCase().contains( + OtrActivator.scOtrKeyManager + .getRemoteFingerprint(contact).toLowerCase())) + { + txtRemoteFingerprintComparison.setBackground(Color.green); + getCbAction().setSelectedItem(actionIHave); + } + else + { + txtRemoteFingerprintComparison.setBackground( + new Color(243, 72, 48)); + getCbAction().setSelectedItem(actionIHaveNot); + } + } + + public JComboBox getCbAction() + { + return cbAction; + } + + public void setCbAction(JComboBox cbAction) + { + this.cbAction = cbAction; + } + + /** + * A simple enumeration that is meant to be used with + * {@link ActionComboBoxItem} to distinguish them (like an ID). + * + * @author George Politis + */ + enum ActionComboBoxItemIndex + { + I_HAVE, I_HAVE_NOT + } + + /** + * A special {@link JComboBox} that is hosted in + * {@link OtrBuddyAuthenticationDialog#cbAction}. + * + * @author George Politis + */ + class ActionComboBoxItem + { + public ActionComboBoxItemIndex action; + + private String text; + + public ActionComboBoxItem(ActionComboBoxItemIndex actionIndex) + { + this.action = actionIndex; + switch (action) + { + case I_HAVE: + text = + OtrActivator.resourceService + .getI18NString("plugin.otr.authbuddydialog.I_HAVE"); + break; + case I_HAVE_NOT: + text = + OtrActivator.resourceService + .getI18NString("plugin.otr.authbuddydialog.I_HAVE_NOT"); + break; + } + } + + @Override + public String toString() + { + return text; + } + } +} diff --git a/src/net/java/sip/communicator/plugin/otr/OtrBuddyAuthenticationDialog.java b/src/net/java/sip/communicator/plugin/otr/OtrBuddyAuthenticationDialog.java index 5d5e06c..a78fb7a 100644 --- a/src/net/java/sip/communicator/plugin/otr/OtrBuddyAuthenticationDialog.java +++ b/src/net/java/sip/communicator/plugin/otr/OtrBuddyAuthenticationDialog.java @@ -10,18 +10,18 @@ import java.awt.*; import java.awt.event.*; import javax.swing.*; -import javax.swing.event.*; -import net.java.sip.communicator.service.protocol.*; import net.java.sip.communicator.plugin.desktoputil.*; +import net.java.sip.communicator.plugin.otr.FingerprintAuthenticationPanel.ActionComboBoxItem; +import net.java.sip.communicator.service.protocol.*; /** * @author George Politis + * @author Marin Dzhigarov */ @SuppressWarnings("serial") public class OtrBuddyAuthenticationDialog extends SIPCommDialog - implements DocumentListener { private final Contact contact; @@ -37,121 +37,6 @@ public class OtrBuddyAuthenticationDialog this.contact = contact; initComponents(); - loadContact(); - } - - private SIPCommTextField txtRemoteFingerprintComparison; - - private JTextArea txtLocalFingerprint; - - private JTextArea txtRemoteFingerprint; - - private JComboBox cbAction; - ActionComboBoxItem actionIHave = - new ActionComboBoxItem(ActionComboBoxItemIndex.I_HAVE); - ActionComboBoxItem actionIHaveNot = - new ActionComboBoxItem(ActionComboBoxItemIndex.I_HAVE_NOT); - - private JTextArea txtAction; - - /** - * Sets up the {@link OtrBuddyAuthenticationDialog} components so that they - * reflect the {@link OtrBuddyAuthenticationDialog#contact} - */ - private void loadContact() - { - // Local fingerprint. - String account = - contact.getProtocolProvider().getAccountID().getDisplayName(); - String localFingerprint = - OtrActivator.scOtrKeyManager.getLocalFingerprint(contact - .getProtocolProvider().getAccountID()); - txtLocalFingerprint.setText(OtrActivator.resourceService.getI18NString( - "plugin.otr.authbuddydialog.LOCAL_FINGERPRINT", new String[] - { account, localFingerprint })); - - // Remote fingerprint. - String user = contact.getDisplayName(); - String remoteFingerprint = - OtrActivator.scOtrKeyManager.getRemoteFingerprint(contact); - txtRemoteFingerprint.setText(OtrActivator.resourceService - .getI18NString("plugin.otr.authbuddydialog.REMOTE_FINGERPRINT", - new String[] - { user, remoteFingerprint })); - - // Action - txtAction.setText(OtrActivator.resourceService.getI18NString( - "plugin.otr.authbuddydialog.VERIFY_ACTION", new String[] - { user })); - } - - /** - * A special {@link JTextArea} for use in the - * {@link OtrBuddyAuthenticationDialog}. It is meant to be used for - * fingerprint representation and general information display. - * - * @author George Politis - */ - class CustomTextArea - extends JTextArea - { - public CustomTextArea() - { - this.setBackground(new Color(0,0,0,0)); - this.setOpaque(false); - this.setColumns(20); - this.setEditable(false); - this.setLineWrap(true); - this.setWrapStyleWord(true); - } - } - - /** - * A simple enumeration that is meant to be used with - * {@link ActionComboBoxItem} to distinguish them (like an ID). - * - * @author George Politis - */ - enum ActionComboBoxItemIndex - { - I_HAVE, I_HAVE_NOT - } - - /** - * A special {@link JComboBox} that is hosted in - * {@link OtrBuddyAuthenticationDialog#cbAction}. - * - * @author George Politis - */ - class ActionComboBoxItem - { - public ActionComboBoxItemIndex action; - - private String text; - - public ActionComboBoxItem(ActionComboBoxItemIndex actionIndex) - { - this.action = actionIndex; - switch (action) - { - case I_HAVE: - text = - OtrActivator.resourceService - .getI18NString("plugin.otr.authbuddydialog.I_HAVE"); - break; - case I_HAVE_NOT: - text = - OtrActivator.resourceService - .getI18NString("plugin.otr.authbuddydialog.I_HAVE_NOT"); - break; - } - } - - @Override - public String toString() - { - return text; - } } /** @@ -172,45 +57,60 @@ public class OtrBuddyAuthenticationDialog .getI18NString("plugin.otr.authbuddydialog.AUTHENTICATION_INFO")); mainPanel.add(generalInformation); - txtLocalFingerprint = new CustomTextArea(); - mainPanel.add(txtLocalFingerprint); - - txtRemoteFingerprint = new CustomTextArea(); - mainPanel.add(txtRemoteFingerprint); - - // Action Panel (the panel that holds the I have/I have not dropdown) - JPanel pnlAction = new JPanel(new GridBagLayout()); - pnlAction.setBorder(BorderFactory.createEtchedBorder()); - mainPanel.add(pnlAction); + mainPanel.add(Box.createVerticalStrut(10)); + + // Add authentication method label and combo box. + final String am[] = new String[]{ + OtrActivator.resourceService.getI18NString( + "plugin.otr.authbuddydialog.AUTHENTICATION_METHOD_QUESTION"), + OtrActivator.resourceService.getI18NString( + "plugin.otr.authbuddydialog.AUTHENTICATION_METHOD_SECRET"), + OtrActivator.resourceService.getI18NString( + "plugin.otr.authbuddydialog.AUTHENTICATION_METHOD_FINGERPRINT")}; + final JComboBox authenticationMethodComboBox = + new JComboBox(am); + JTextArea authMethodLabel = new CustomTextArea(); + authMethodLabel.setText( + OtrActivator.resourceService.getI18NString( + "plugin.otr.authbuddydialog.AUTHENTICATION_METHOD")); + mainPanel.add(authMethodLabel); + mainPanel.add(authenticationMethodComboBox); + mainPanel.add(Box.createVerticalStrut(10)); + + // Add authentication panels in a card layout so that the user can + // use the combo box to switch between authentication methods. + final JPanel authenticationPanel = + new TransparentPanel(new CardLayout()); + final FingerprintAuthenticationPanel fingerprintPanel = + new FingerprintAuthenticationPanel(contact); + final SecretQuestionAuthenticationPanel secretQuestionPanel = + new SecretQuestionAuthenticationPanel(); + final SharedSecretAuthenticationPanel sharedSecretPanel = + new SharedSecretAuthenticationPanel(); + authenticationPanel.add(secretQuestionPanel, am[0]); + authenticationPanel.add(sharedSecretPanel, am[1]); + authenticationPanel.add(fingerprintPanel, am[2]); + + authenticationMethodComboBox.addItemListener(new ItemListener() + { + @Override + public void itemStateChanged(ItemEvent e) + { + if (e.getStateChange() == ItemEvent.SELECTED) + { + CardLayout cl = + (CardLayout) (authenticationPanel.getLayout()); + cl.show(authenticationPanel, (String)e.getItem()); + } + } + }); + authenticationMethodComboBox.setSelectedIndex(0); + mainPanel.add(authenticationPanel); GridBagConstraints c = new GridBagConstraints(); - c.fill = GridBagConstraints.HORIZONTAL; c.insets = new Insets(5, 5, 5, 5); - c.weightx = 0.0; - - cbAction = new JComboBox(); - cbAction.addItem(actionIHave); - cbAction.addItem(actionIHaveNot); - cbAction.setSelectedItem(OtrActivator.scOtrKeyManager - .isVerified(contact) ? actionIHave : actionIHaveNot); - - pnlAction.add(cbAction, c); - - txtAction = new CustomTextArea(); c.weightx = 1.0; - pnlAction.add(txtAction, c); - - txtRemoteFingerprintComparison = new SIPCommTextField( - OtrActivator.resourceService - .getI18NString("plugin.otr.authbuddydialog.FINGERPRINT_CHECK", - new String[]{contact.getDisplayName()})); - txtRemoteFingerprintComparison.getDocument().addDocumentListener(this); - - c.gridwidth = 2; - c.gridy = 1; - pnlAction.add(txtRemoteFingerprintComparison, c); c.gridwidth = 1; - c.gridy = 0; // Buttons panel. JPanel buttonPanel = new TransparentPanel(new GridBagLayout()); @@ -254,19 +154,40 @@ public class OtrBuddyAuthenticationDialog { public void actionPerformed(ActionEvent e) { - ActionComboBoxItem actionItem = - (ActionComboBoxItem) cbAction.getSelectedItem(); - switch (actionItem.action) + String authenticationMethod = + (String)authenticationMethodComboBox.getSelectedItem(); + if (authenticationMethod.equals(am[0])) { - case I_HAVE: - OtrActivator.scOtrKeyManager.verify(contact); - break; - case I_HAVE_NOT: - OtrActivator.scOtrKeyManager.unverify(contact); - break; + String secret = secretQuestionPanel.getSecret(); + String question = secretQuestionPanel.getQuestion(); + + OtrActivator.scOtrEngine.initSmp(contact, question, secret); + dispose(); } + else if (authenticationMethod.equals(am[1])) + { + String secret = secretQuestionPanel.getSecret(); + String question = null; - dispose(); + OtrActivator.scOtrEngine.initSmp(contact, question, secret); + dispose(); + } + else if (authenticationMethod.equals(am[2])) + { + ActionComboBoxItem actionItem = + (ActionComboBoxItem) fingerprintPanel. + getCbAction().getSelectedItem(); + switch (actionItem.action) + { + case I_HAVE: + OtrActivator.scOtrKeyManager.verify(contact); + break; + case I_HAVE_NOT: + OtrActivator.scOtrKeyManager.unverify(contact); + break; + } + dispose(); + } } }); buttonPanel.add(authenticateButton, c); @@ -275,42 +196,4 @@ public class OtrBuddyAuthenticationDialog this.getContentPane().add(buttonPanel, BorderLayout.SOUTH); this.pack(); } - - public void removeUpdate(DocumentEvent e) - { - compareFingerprints(); - } - - public void insertUpdate(DocumentEvent e) - { - compareFingerprints(); - } - - public void changedUpdate(DocumentEvent e) - { - compareFingerprints(); - } - - public void compareFingerprints() - { - if(txtRemoteFingerprintComparison.getText() == null - || txtRemoteFingerprintComparison.getText().length() == 0) - { - txtRemoteFingerprintComparison.setBackground(Color.white); - return; - } - if(txtRemoteFingerprintComparison.getText().toLowerCase().contains( - OtrActivator.scOtrKeyManager - .getRemoteFingerprint(contact).toLowerCase())) - { - txtRemoteFingerprintComparison.setBackground(Color.green); - cbAction.setSelectedItem(actionIHave); - } - else - { - txtRemoteFingerprintComparison.setBackground( - new Color(243, 72, 48)); - cbAction.setSelectedItem(actionIHaveNot); - } - } } diff --git a/src/net/java/sip/communicator/plugin/otr/ScOtrEngine.java b/src/net/java/sip/communicator/plugin/otr/ScOtrEngine.java index 1e7b5e8..3e8e6e5 100644 --- a/src/net/java/sip/communicator/plugin/otr/ScOtrEngine.java +++ b/src/net/java/sip/communicator/plugin/otr/ScOtrEngine.java @@ -21,6 +21,38 @@ public interface ScOtrEngine // Proxy methods OtrEngine. /** + * Initializes Smp negotiation. + * See {@link http://en.wikipedia.org/wiki/Socialist_Millionaire_Problem} + * + * @param contact The contact with whom we want to start the Smp negotiation + * @param question The question that is asked during the Smp negotiation + * @param secret The secret answer for the question. + */ + public abstract void initSmp( + Contact contact, String question, String secret); + + /** + * Responds to a question that is asked during the Smp negotiation process. + * See {@link http://en.wikipedia.org/wiki/Socialist_Millionaire_Problem} + * + * @param contact The contact for whom we want to respond to a question + * during the Smp negotiation process. + * @param question The question that is asked during the Smp negotiation. + * @param secret The secret answer for the question. + */ + public abstract void respondSmp( + Contact contact, String question, String secret); + + /** + * Aborts the Smp negotiation process. + * See {@link http://en.wikipedia.org/wiki/Socialist_Millionaire_Problem} + * + * @param contact The contact with whom we want to abort the + * Smp negotiation process. + */ + public abstract void abortSmp(Contact contact); + + /** * Transforms an outgoing message. * * @param contact the destination {@link Contact}. diff --git a/src/net/java/sip/communicator/plugin/otr/ScOtrEngineImpl.java b/src/net/java/sip/communicator/plugin/otr/ScOtrEngineImpl.java index f60ef33..c465e94 100644 --- a/src/net/java/sip/communicator/plugin/otr/ScOtrEngineImpl.java +++ b/src/net/java/sip/communicator/plugin/otr/ScOtrEngineImpl.java @@ -6,13 +6,20 @@ */
package net.java.sip.communicator.plugin.otr;
+import java.awt.*;
+import java.awt.event.*;
import java.net.*;
import java.security.*;
import java.util.*;
+import java.util.List;
+import java.util.concurrent.*;
+
+import javax.swing.*;
+import javax.swing.plaf.basic.*;
import net.java.otr4j.*;
import net.java.otr4j.session.*;
-
+import net.java.sip.communicator.plugin.desktoputil.*;
import net.java.sip.communicator.service.browserlauncher.*;
import net.java.sip.communicator.service.contactlist.*;
import net.java.sip.communicator.service.gui.*;
@@ -36,7 +43,7 @@ public class ScOtrEngineImpl class ScOtrEngineHost
implements OtrEngineHost
{
- public KeyPair getKeyPair(SessionID sessionID)
+ public KeyPair getLocalKeyPair(SessionID sessionID)
{
AccountID accountID =
OtrActivator.getAccountIDByUID(sessionID.getAccountID());
@@ -83,11 +90,242 @@ public class ScOtrEngineImpl Chat.SYSTEM_MESSAGE, warn,
OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE);
}
+
+ @Override
+ public void unreadableMessageReceived(SessionID sessionID)
+ throws OtrException
+ {
+ Contact contact = getContact(sessionID);
+ if (contact == null)
+ return;
+
+ String error =
+ OtrActivator.resourceService.getI18NString(
+ "plugin.otr.activator.unreadablemsgreceived",
+ new String[] {contact.getDisplayName()});
+ OtrActivator.uiService.getChat(contact).addMessage(
+ contact.getDisplayName(), new Date(),
+ Chat.ERROR_MESSAGE, error,
+ OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE);
+ }
+
+ @Override
+ public void unencryptedMessageReceived(SessionID sessionID, String msg)
+ throws OtrException
+ {
+ Contact contact = getContact(sessionID);
+ if (contact == null)
+ return;
+
+ String warn =
+ OtrActivator.resourceService.getI18NString(
+ "plugin.otr.activator.unencryptedmsgreceived");
+ OtrActivator.uiService.getChat(contact).addMessage(
+ contact.getDisplayName(), new Date(),
+ Chat.SYSTEM_MESSAGE, warn,
+ OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE);
+ }
+
+ @Override
+ public void smpError(SessionID sessionID, int tlvType, boolean cheated)
+ throws OtrException
+ {
+ Contact contact = getContact(sessionID);
+ if (contact == null)
+ return;
+
+ logger.debug("SMP error occurred"
+ + ". Contact: " + contact.getDisplayName()
+ + ". TLV type: " + tlvType
+ + ". Cheated: " + cheated);
+
+ String error =
+ OtrActivator.resourceService.getI18NString(
+ "plugin.otr.activator.smperror");
+ OtrActivator.uiService.getChat(contact).addMessage(
+ contact.getDisplayName(), new Date(),
+ Chat.ERROR_MESSAGE, error,
+ OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE);
+
+ SmpProgressDialog progressDialog = progressDialogMap.get(contact);
+ if (progressDialog == null)
+ {
+ progressDialog = new SmpProgressDialog(contact);
+ progressDialogMap.put(contact, progressDialog);
+ }
+
+ progressDialog.setProgressFail();
+ progressDialog.setVisible(true);
+ }
+
+ @Override
+ public void smpAborted(SessionID sessionID) throws OtrException
+ {
+ Contact contact = getContact(sessionID);
+ if (contact == null)
+ return;
+
+ Session session = otrEngine.getSession(sessionID);
+ if (session.isSmpInProgress())
+ {
+ String warn =
+ OtrActivator.resourceService.getI18NString(
+ "plugin.otr.activator.smpaborted",
+ new String[] {contact.getDisplayName()});
+ OtrActivator.uiService.getChat(contact).addMessage(
+ contact.getDisplayName(), new Date(),
+ Chat.SYSTEM_MESSAGE, warn,
+ OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE);
+
+ SmpProgressDialog progressDialog = progressDialogMap.get(contact);
+ if (progressDialog == null)
+ {
+ progressDialog = new SmpProgressDialog(contact);
+ progressDialogMap.put(contact, progressDialog);
+ }
+
+ progressDialog.setProgressFail();
+ progressDialog.setVisible(true);
+ }
+ }
+
+ @Override
+ public void finishedSessionMessage(SessionID sessionID)
+ throws OtrException
+ {
+ Contact contact = getContact(sessionID);
+ if (contact == null)
+ return;
+
+ String error =
+ OtrActivator.resourceService.getI18NString(
+ "plugin.otr.activator.sessionfinishederror",
+ new String[] {contact.getDisplayName()});
+ OtrActivator.uiService.getChat(contact).addMessage(
+ contact.getDisplayName(), new Date(),
+ Chat.ERROR_MESSAGE, error,
+ OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE);
+ }
+
+ @Override
+ public void requireEncryptedMessage(SessionID sessionID, String msgText)
+ throws OtrException
+ {
+ Contact contact = getContact(sessionID);
+ if (contact == null)
+ return;
+
+ String error =
+ OtrActivator.resourceService.getI18NString(
+ "plugin.otr.activator.requireencryption",
+ new String[] {contact.getDisplayName()});
+ OtrActivator.uiService.getChat(contact).addMessage(
+ contact.getDisplayName(), new Date(),
+ Chat.ERROR_MESSAGE, error,
+ OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE);
+ }
+
+ @Override
+ public byte[] getLocalFingerprintRaw(SessionID sessionID)
+ {
+ AccountID accountID =
+ OtrActivator.getAccountIDByUID(sessionID.getAccountID());
+ return
+ OtrActivator.scOtrKeyManager.getLocalFingerprintRaw(accountID);
+ }
+
+ @Override
+ public void askForSecret(SessionID sessionID, String question)
+ {
+ Contact contact = getContact(sessionID);
+ if (contact == null)
+ return;
+
+ SmpAuthenticateBuddyDialog dialog =
+ new SmpAuthenticateBuddyDialog(contact, question);
+ dialog.setVisible(true);
+
+ SmpProgressDialog progressDialog = progressDialogMap.get(contact);
+ if (progressDialog == null)
+ {
+ progressDialog = new SmpProgressDialog(contact);
+ progressDialogMap.put(contact, progressDialog);
+ }
+
+ progressDialog.init();
+ progressDialog.setVisible(true);
+ }
+
+ @Override
+ public void verify(SessionID sessionID, boolean approved)
+ {
+ Contact contact = getContact(sessionID);
+ if (contact == null)
+ return;
+
+ OtrActivator.scOtrKeyManager.verify(contact);
+
+ SmpProgressDialog progressDialog = progressDialogMap.get(contact);
+ if (progressDialog == null)
+ {
+ progressDialog = new SmpProgressDialog(contact);
+ progressDialogMap.put(contact, progressDialog);
+ }
+
+ progressDialog.setProgressSuccess();
+ progressDialog.setVisible(true);
+ }
+
+ @Override
+ public void unverify(SessionID sessionID)
+ {
+ Contact contact = getContact(sessionID);
+ if (contact == null)
+ return;
+
+ OtrActivator.scOtrKeyManager.unverify(contact);
+
+ SmpProgressDialog progressDialog = progressDialogMap.get(contact);
+ if (progressDialog == null)
+ {
+ progressDialog = new SmpProgressDialog(contact);
+ progressDialogMap.put(contact, progressDialog);
+ }
+
+ progressDialog.setProgressFail();
+ progressDialog.setVisible(true);
+ }
+
+ @Override
+ public String getReplyForUnreadableMessage(SessionID sessionID)
+ {
+ AccountID accountID =
+ OtrActivator.getAccountIDByUID(sessionID.getAccountID());
+
+ return OtrActivator.resourceService.getI18NString(
+ "plugin.otr.activator.unreadablemsgreply",
+ new String[] {accountID.getDisplayName(),
+ accountID.getDisplayName()});
+ }
+
+ @Override
+ public String getFallbackMessage(SessionID sessionID)
+ {
+ AccountID accountID =
+ OtrActivator.getAccountIDByUID(sessionID.getAccountID());
+
+ return OtrActivator.resourceService.getI18NString(
+ "plugin.otr.activator.fallbackmessage",
+ new String[] {accountID.getDisplayName()});
+ }
}
private static final Map<ScSessionID, Contact> contactsMap =
new Hashtable<ScSessionID, Contact>();
+ private static final Map<Contact, SmpProgressDialog> progressDialogMap =
+ new ConcurrentHashMap<Contact, SmpProgressDialog>();
+
public static Contact getContact(SessionID sessionID)
{
return contactsMap.get(new ScSessionID(sessionID));
@@ -145,11 +383,14 @@ public class ScOtrEngineImpl */
private final Logger logger = Logger.getLogger(ScOtrEngineImpl.class);
- private final OtrEngine otrEngine
- = new OtrEngineImpl(new ScOtrEngineHost());
+ final OtrEngineHost otrEngineHost = new ScOtrEngineHost();
+
+ private final OtrEngine otrEngine;
public ScOtrEngineImpl()
{
+ otrEngine = new OtrEngineImpl(otrEngineHost);
+
// Clears the map after previous instance
// This is required because of OSGi restarts in the same VM on Android
contactsMap.clear();
@@ -449,6 +690,9 @@ public class ScOtrEngineImpl logger.debug(
"Unregistering a ProtocolProviderService, cleaning"
+ " OTR's ScSessionID to Contact map.");
+ logger.debug(
+ "Unregistering a ProtocolProviderService, cleaning"
+ + " OTR's Contact to SpmProgressDialog map.");
}
ProtocolProviderService provider
@@ -464,6 +708,14 @@ public class ScOtrEngineImpl i.remove();
}
}
+
+ Iterator<Contact> i = progressDialogMap.keySet().iterator();
+
+ while (i.hasNext())
+ {
+ if (provider.equals(i.next().getProtocolProvider()))
+ i.remove();
+ }
}
}
@@ -545,4 +797,398 @@ public class ScOtrEngineImpl return null;
}
}
+
+ private Session getSession(Contact contact)
+ {
+ SessionID sessionID = getSessionID(contact);
+ return otrEngine.getSession(sessionID);
+ }
+
+ @Override
+ public void initSmp(Contact contact, String question, String secret)
+ {
+ Session session = getSession(contact);
+ try
+ {
+ session.initSmp(question, secret);
+
+ SmpProgressDialog progressDialog = progressDialogMap.get(contact);
+ if (progressDialog == null)
+ {
+ progressDialog = new SmpProgressDialog(contact);
+ progressDialogMap.put(contact, progressDialog);
+ }
+
+ progressDialog.init();
+ progressDialog.setVisible(true);
+ }
+ catch (OtrException e)
+ {
+ logger.error("Error initializing SMP session with contact "
+ + contact.getDisplayName(), e);
+ showError(session.getSessionID(), e.getMessage());
+ }
+ }
+
+ @Override
+ public void respondSmp(Contact contact, String question, String secret)
+ {
+ Session session = getSession(contact);
+ try
+ {
+ session.respondSmp(question, secret);
+
+ SmpProgressDialog progressDialog = progressDialogMap.get(contact);
+ if (progressDialog == null)
+ {
+ progressDialog = new SmpProgressDialog(contact);
+ progressDialogMap.put(contact, progressDialog);
+ }
+
+ progressDialog.incrementProgress();
+ progressDialog.setVisible(true);
+ }
+ catch (OtrException e)
+ {
+ logger.error(
+ "Error occured when sending SMP response to contact "
+ + contact.getDisplayName(), e);
+ showError(session.getSessionID(), e.getMessage());
+ }
+ }
+
+ @Override
+ public void abortSmp(Contact contact)
+ {
+ Session session = getSession(contact);
+ try
+ {
+ session.abortSmp();
+
+ SmpProgressDialog progressDialog = progressDialogMap.get(contact);
+ if (progressDialog == null)
+ {
+ progressDialog = new SmpProgressDialog(contact);
+ progressDialogMap.put(contact, progressDialog);
+ }
+
+ progressDialog.dispose();
+ }
+ catch (OtrException e)
+ {
+ logger.error("Error aborting SMP session with contact "
+ + contact.getDisplayName(), e);
+ showError(session.getSessionID(), e.getMessage());
+ }
+
+ }
+
+ /**
+ * The dialog that pops up when SMP negotiation starts.
+ * It contains a progress bar that indicates the status of the SMP
+ * authentication process.
+ */
+ @SuppressWarnings("serial")
+ private class SmpProgressDialog
+ extends SIPCommDialog
+ {
+ private final JProgressBar progressBar = new JProgressBar(0, 100);
+
+ private final Color successColor = new Color(86, 140, 2);
+
+ private final Color failColor = new Color(204, 0, 0);
+
+ private final JLabel iconLabel = new JLabel();
+
+ /**
+ * Instantiates SmpProgressDialog.
+ *
+ * @param contact The contact that this dialog is associated with.
+ */
+ public SmpProgressDialog(Contact contact)
+ {
+ setTitle(
+ OtrActivator.resourceService.getI18NString(
+ "plugin.otr.smpprogressdialog.TITLE"));
+
+ JPanel mainPanel = new TransparentPanel();
+ mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
+ mainPanel.setBorder(
+ BorderFactory.createEmptyBorder(10, 10, 10, 10));
+ mainPanel.setPreferredSize(new Dimension(300, 70));
+
+ String authFromText =
+ String.format(
+ OtrActivator.resourceService
+ .getI18NString(
+ "plugin.otr.authbuddydialog.AUTHENTICATION_FROM",
+ new String[] {contact.getDisplayName()}));
+
+ JPanel labelsPanel = new TransparentPanel();
+ labelsPanel.setLayout(new BoxLayout(labelsPanel, BoxLayout.X_AXIS));
+
+ labelsPanel.add(iconLabel);
+ labelsPanel.add(Box.createRigidArea(new Dimension(5,0)));
+ labelsPanel.add(new JLabel(authFromText));
+
+ mainPanel.add(labelsPanel);
+ mainPanel.add(progressBar);
+
+ init();
+
+ this.getContentPane().add(mainPanel);
+ this.pack();
+ }
+
+ /**
+ * Initializes the progress bar and sets it's progression to 1/3.
+ */
+ public void init()
+ {
+ progressBar.setUI(new BasicProgressBarUI() {
+ private Rectangle r = new Rectangle();
+
+ @Override
+ protected void paintIndeterminate(Graphics g, JComponent c) {
+ Graphics2D g2d = (Graphics2D) g;
+ g2d.setRenderingHint(
+ RenderingHints.KEY_ANTIALIASING,
+ RenderingHints.VALUE_ANTIALIAS_ON);
+ r = getBox(r);
+ g.setColor(progressBar.getForeground());
+ g.fillOval(r.x, r.y, r.width, r.height);
+ }
+ });
+ progressBar.setValue(33);
+ progressBar.setForeground(successColor);
+ progressBar.setStringPainted(false);
+ iconLabel.setIcon(
+ OtrActivator.resourceService.getImage(
+ "plugin.otr.ENCRYPTED_UNVERIFIED_ICON_22x22"));
+ }
+
+ /**
+ * Sets the progress bar to 2/3 of completion.
+ */
+ public void incrementProgress()
+ {
+ progressBar.setValue(66);
+ }
+
+ /**
+ * Sets the progress bar to green.
+ */
+ public void setProgressSuccess()
+ {
+ progressBar.setValue(100);
+ progressBar.setForeground(successColor);
+ progressBar.setStringPainted(true);
+ progressBar.setString(
+ OtrActivator.resourceService
+ .getI18NString(
+ "plugin.otr.smpprogressdialog.AUTHENTICATION_SUCCESS"));
+ iconLabel.setIcon(
+ OtrActivator.resourceService.getImage(
+ "plugin.otr.ENCRYPTED_ICON_22x22"));
+ }
+
+ /**
+ * Sets the progress bar to red.
+ */
+ public void setProgressFail()
+ {
+ progressBar.setValue(100);
+ progressBar.setForeground(failColor);
+ progressBar.setStringPainted(true);
+ progressBar.setString(
+ OtrActivator.resourceService
+ .getI18NString(
+ "plugin.otr.smpprogressdialog.AUTHENTICATION_FAIL"));
+ }
+ }
+
+ /**
+ * The dialog that pops up when the remote party send us SMP
+ * request. It contains detailed information for the user about
+ * the authentication process and allows him to authenticate.
+ *
+ */
+ @SuppressWarnings("serial")
+ private class SmpAuthenticateBuddyDialog
+ extends SIPCommDialog
+ {
+ private final Contact contact;
+
+ private final String question;
+
+ SmpAuthenticateBuddyDialog(Contact contact, String question)
+ {
+ this.contact = contact;
+ this.question = question;
+ initComponents();
+ }
+
+ private void initComponents()
+ {
+ this.setTitle(
+ OtrActivator.resourceService
+ .getI18NString(
+ "plugin.otr.authbuddydialog.TITLE"));
+
+ // The main panel that contains all components.
+ JPanel mainPanel = new TransparentPanel();
+ mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
+ mainPanel.setBorder(
+ BorderFactory.createEmptyBorder(10, 10, 10, 10));
+ mainPanel.setPreferredSize(new Dimension(300, 350));
+
+ // Add "authentication from contact" to the main panel.
+ JTextArea authenticationFrom = new CustomTextArea();
+ Font newFont =
+ new Font(
+ UIManager.getDefaults().getFont("TextArea.font").
+ getFontName()
+ , Font.BOLD
+ , 14);
+ authenticationFrom.setFont(newFont);
+ String authFromText =
+ String.format(
+ OtrActivator.resourceService
+ .getI18NString(
+ "plugin.otr.authbuddydialog.AUTHENTICATION_FROM",
+ new String[] {contact.getDisplayName()}));
+ authenticationFrom.setText(authFromText);
+ mainPanel.add(authenticationFrom);
+
+ // Add "general info" text to the main panel.
+ JTextArea generalInfo = new CustomTextArea();
+ generalInfo.setText(OtrActivator.resourceService
+ .getI18NString(
+ "plugin.otr.authbuddydialog.AUTHENTICATION_INFO"));
+ mainPanel.add(generalInfo);
+
+ // Add "authentication-by-secret" info text to the main panel.
+ JTextArea authBySecretInfo = new CustomTextArea();
+ newFont =
+ new Font(
+ UIManager.getDefaults().getFont("TextArea.font").
+ getFontName()
+ , Font.ITALIC
+ , 10);
+ authBySecretInfo.setText(OtrActivator.resourceService
+ .getI18NString(
+ "plugin.otr.authbuddydialog.AUTH_BY_SECRET_INFO_RESPOND"));
+ authBySecretInfo.setFont(newFont);
+ mainPanel.add(authBySecretInfo);
+
+ // Create a panel to add question/answer related components
+ JPanel questionAnswerPanel = new JPanel(new GridBagLayout());
+ questionAnswerPanel.setBorder(BorderFactory.createEtchedBorder());
+
+ GridBagConstraints c = new GridBagConstraints();
+ c.gridx = 0;
+ c.gridy = 0;
+ c.fill = GridBagConstraints.HORIZONTAL;
+ c.insets = new Insets(5, 5, 0, 5);
+ c.weightx = 0;
+
+ // Add question label.
+ JLabel questionLabel =
+ new JLabel(
+ OtrActivator.resourceService
+ .getI18NString(
+ "plugin.otr.authbuddydialog.QUESTION_RESPOND"));
+ questionAnswerPanel.add(questionLabel, c);
+
+ // Add the question.
+ c.insets = new Insets(0, 5, 5, 5);
+ c.gridy = 1;
+ JTextArea questionArea =
+ new CustomTextArea();
+ newFont =
+ new Font(
+ UIManager.getDefaults().getFont("TextArea.font").
+ getFontName()
+ , Font.BOLD
+ , UIManager.getDefaults().getFont("TextArea.font")
+ .getSize());
+ questionArea.setFont(newFont);
+ questionArea.setText(question);
+ questionAnswerPanel.add(questionArea, c);
+
+ // Add answer label.
+ c.insets = new Insets(5, 5, 5, 5);
+ c.gridy = 2;
+ JLabel answerLabel =
+ new JLabel(OtrActivator.resourceService
+ .getI18NString("plugin.otr.authbuddydialog.ANSWER"));
+ questionAnswerPanel.add(answerLabel, c);
+
+ // Add the answer text field.
+ c.gridy = 3;
+ final JTextField answerTextBox = new JTextField();
+ questionAnswerPanel.add(answerTextBox, c);
+
+ // Add the question/answer panel to the main panel.
+ mainPanel.add(questionAnswerPanel);
+
+ // Buttons panel.
+ JPanel buttonPanel = new TransparentPanel(new GridBagLayout());
+ buttonPanel.setBorder(BorderFactory.createEmptyBorder(0, 5, 5, 5));
+
+ JButton helpButton =
+ new JButton(OtrActivator.resourceService
+ .getI18NString("plugin.otr.authbuddydialog.HELP"));
+ helpButton.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent arg0)
+ {
+ OtrActivator.scOtrEngine.launchHelp();
+ }
+ });
+
+ c.gridwidth = 1;
+ c.gridy = 0;
+ c.gridx = 0;
+ c.weightx = 0;
+ c.insets = new Insets(5, 5, 5, 20);
+ buttonPanel.add(helpButton, c);
+
+ JButton cancelButton =
+ new JButton(OtrActivator.resourceService
+ .getI18NString("plugin.otr.authbuddydialog.CANCEL"));
+ cancelButton.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ ScOtrEngineImpl.this.abortSmp(contact);
+ SmpAuthenticateBuddyDialog.this.dispose();
+ }
+ });
+ c.insets = new Insets(5, 5, 5, 5);
+ c.gridx = 1;
+ buttonPanel.add(cancelButton, c);
+
+ c.gridx = 2;
+ JButton authenticateButton =
+ new JButton(OtrActivator.resourceService
+ .getI18NString(
+ "plugin.otr.authbuddydialog.AUTHENTICATE_BUDDY"));
+ authenticateButton.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ ScOtrEngineImpl.this.respondSmp(
+ contact, question, answerTextBox.getText());
+ SmpAuthenticateBuddyDialog.this.dispose();
+ }
+ });
+
+ buttonPanel.add(authenticateButton, c);
+
+ this.getContentPane().add(mainPanel, BorderLayout.NORTH);
+ this.getContentPane().add(buttonPanel, BorderLayout.SOUTH);
+ this.pack();
+ }
+ }
}
diff --git a/src/net/java/sip/communicator/plugin/otr/ScOtrKeyManager.java b/src/net/java/sip/communicator/plugin/otr/ScOtrKeyManager.java index fef0f9f..bc83cd7 100755 --- a/src/net/java/sip/communicator/plugin/otr/ScOtrKeyManager.java +++ b/src/net/java/sip/communicator/plugin/otr/ScOtrKeyManager.java @@ -32,6 +32,8 @@ public interface ScOtrKeyManager public abstract String getLocalFingerprint(AccountID account);
+ public abstract byte[] getLocalFingerprintRaw(AccountID account);
+
public abstract void savePublicKey(Contact contact, PublicKey pubKey);
public abstract PublicKey loadPublicKey(Contact contact);
diff --git a/src/net/java/sip/communicator/plugin/otr/ScOtrKeyManagerImpl.java b/src/net/java/sip/communicator/plugin/otr/ScOtrKeyManagerImpl.java index c461ad0..37adc63 100755 --- a/src/net/java/sip/communicator/plugin/otr/ScOtrKeyManagerImpl.java +++ b/src/net/java/sip/communicator/plugin/otr/ScOtrKeyManagerImpl.java @@ -131,6 +131,26 @@ public class ScOtrKeyManagerImpl }
}
+ public byte[] getLocalFingerprintRaw(AccountID account)
+ {
+ KeyPair keyPair = loadKeyPair(account);
+
+ if (keyPair == null)
+ return null;
+
+ PublicKey pubKey = keyPair.getPublic();
+
+ try
+ {
+ return new OtrCryptoEngineImpl().getFingerprintRaw(pubKey);
+ }
+ catch (OtrCryptoException e)
+ {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
public void savePublicKey(Contact contact, PublicKey pubKey)
{
if (contact == null)
diff --git a/src/net/java/sip/communicator/plugin/otr/SecretQuestionAuthenticationPanel.java b/src/net/java/sip/communicator/plugin/otr/SecretQuestionAuthenticationPanel.java new file mode 100644 index 0000000..7134d7d --- /dev/null +++ b/src/net/java/sip/communicator/plugin/otr/SecretQuestionAuthenticationPanel.java @@ -0,0 +1,117 @@ +/* + * Jitsi, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. + * See terms of license at gnu.org. + */ +package net.java.sip.communicator.plugin.otr; + +import java.awt.*; + +import javax.swing.*; + +import net.java.sip.communicator.plugin.desktoputil.*; + +/** + * @author Marin Dzhigarov + */ +@SuppressWarnings("serial") +public class SecretQuestionAuthenticationPanel + extends TransparentPanel +{ + /** + * The text field where the authentication initiator will type his question. + */ + private final JTextField question = new JTextField(); + + /** + * The text field where the authentication initiator will type his answer. + */ + private final JTextField answer = new JTextField(); + + + /** + * Creates an instance SecretQuestionAuthenticationPanel. + */ + SecretQuestionAuthenticationPanel() + { + initComponents(); + } + + /** + * Initializes the {@link SecretQuestionAuthenticationPanel} components. + */ + private void initComponents() + { + setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + + JTextArea generalInformation = new CustomTextArea(); + generalInformation.setText( + OtrActivator.resourceService + .getI18NString( + "plugin.otr.authbuddydialog.AUTH_BY_QUESTION_INFO_INIT")); + this.add(generalInformation); + + this.add(Box.createVerticalStrut(10)); + + JPanel questionAnswerPanel = new JPanel(new GridBagLayout()); + questionAnswerPanel.setBorder(BorderFactory.createEtchedBorder()); + + GridBagConstraints c = new GridBagConstraints(); + c.gridx = 0; + c.gridy = 0; + c.fill = GridBagConstraints.HORIZONTAL; + c.insets = new Insets(5, 5, 0, 5); + c.weightx = 1; + + JLabel questionLabel = + new JLabel( + OtrActivator.resourceService + .getI18NString( + "plugin.otr.authbuddydialog.QUESTION_INIT")); + questionAnswerPanel.add(questionLabel, c); + + c.gridy = 1; + c.insets = new Insets(0, 5, 5, 5); + questionAnswerPanel.add(question, c); + + c.gridy = 2; + c.insets = new Insets(5, 5, 0, 5); + JLabel answerLabel = + new JLabel( + OtrActivator.resourceService + .getI18NString( + "plugin.otr.authbuddydialog.ANSWER")); + questionAnswerPanel.add(answerLabel, c); + + c.gridy = 3; + c.insets = new Insets(0, 5, 5, 5); + questionAnswerPanel.add(answer, c); + + this.add(questionAnswerPanel); + this.add(new Box.Filler( + new Dimension(300, 100), + new Dimension(300, 100), + new Dimension(300, 100))); + } + + /** + * Returns the secret answer text. + * + * @return The secret answer text. + */ + String getSecret() + { + return answer.getText(); + } + + /** + * Returns the secret question text. + * + * @return The secret question text. + */ + String getQuestion() + { + return question.getText(); + } +} diff --git a/src/net/java/sip/communicator/plugin/otr/SharedSecretAuthenticationPanel.java b/src/net/java/sip/communicator/plugin/otr/SharedSecretAuthenticationPanel.java new file mode 100644 index 0000000..39769f2 --- /dev/null +++ b/src/net/java/sip/communicator/plugin/otr/SharedSecretAuthenticationPanel.java @@ -0,0 +1,89 @@ +/* + * Jitsi, the OpenSource Java VoIP and Instant Messaging client. + * + * Distributable under LGPL license. + * See terms of license at gnu.org. + */ +package net.java.sip.communicator.plugin.otr; + +import java.awt.*; + +import javax.swing.*; + +import net.java.sip.communicator.plugin.desktoputil.*; + +/** + * @author Marin Dzhigarov + * + */ +@SuppressWarnings("serial") +public class SharedSecretAuthenticationPanel + extends TransparentPanel +{ + /** + * The text field where the authentication initiator will type his answer. + */ + private final JTextField secret = new JTextField(); + + /** + * Creates an instance SecretQuestionAuthenticationPanel. + */ + SharedSecretAuthenticationPanel() + { + initComponents(); + } + + /** + * Initializes the {@link SecretQuestionAuthenticationPanel} components. + */ + private void initComponents() + { + setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + + JTextArea generalInformation = new CustomTextArea(); + generalInformation.setText( + OtrActivator.resourceService + .getI18NString( + "plugin.otr.authbuddydialog.AUTH_BY_SECRET_INFO_INIT")); + this.add(generalInformation); + + this.add(Box.createVerticalStrut(10)); + + JPanel questionAnswerPanel = new JPanel(new GridBagLayout()); + questionAnswerPanel.setBorder(BorderFactory.createEtchedBorder()); + + GridBagConstraints c = new GridBagConstraints(); + c.gridx = 0; + c.gridy = 0; + c.fill = GridBagConstraints.HORIZONTAL; + c.insets = new Insets(5, 5, 0, 5); + c.weightx = 1; + + JLabel questionLabel = + new JLabel( + OtrActivator.resourceService + .getI18NString( + "plugin.otr.authbuddydialog.SHARED_SECRET")); + questionAnswerPanel.add(questionLabel, c); + + c.gridy = 1; + c.insets = new Insets(0, 5, 5, 5); + questionAnswerPanel.add(secret, c); + + this.add(questionAnswerPanel); + this.add(new Box.Filler( + new Dimension(300, 150), + new Dimension(300, 150), + new Dimension(300, 150))); + } + + /** + * Returns the shared secret text. + * + * @return The shared secret text. + */ + String getSecret() + { + return secret.getText(); + } +} diff --git a/src/net/java/sip/communicator/plugin/otr/otr.manifest.mf b/src/net/java/sip/communicator/plugin/otr/otr.manifest.mf index 3e74c53..71c607c 100644 --- a/src/net/java/sip/communicator/plugin/otr/otr.manifest.mf +++ b/src/net/java/sip/communicator/plugin/otr/otr.manifest.mf @@ -20,6 +20,8 @@ Import-Package: org.osgi.framework, javax.swing.table,
javax.swing.text,
javax.swing.event,
+ javax.swing.plaf,
+ javax.swing.plaf.basic,
javax.crypto,
javax.crypto.interfaces,
javax.crypto.spec,
|