/*
* Jitsi, the OpenSource Java VoIP and Instant Messaging client.
*
* Copyright @ 2015 Atlassian Pty Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.java.sip.communicator.plugin.otr.authdialog;
import java.awt.*;
import java.security.*;
import javax.swing.*;
import javax.swing.event.*;
import net.java.sip.communicator.plugin.desktoputil.*;
import net.java.sip.communicator.plugin.otr.*;
import net.java.sip.communicator.plugin.otr.OtrContactManager.OtrContact;
/**
* @author George Politis
* @author Marin Dzhigarov
*/
@SuppressWarnings("serial")
public class FingerprintAuthenticationPanel
extends TransparentPanel
implements DocumentListener
{
/**
* The Contact that we are authenticating.
*/
private final OtrContact otrContact;
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(OtrContact contact)
{
this.otrContact = 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;
cbAction = new JComboBox();
cbAction.addItem(actionIHave);
cbAction.addItem(actionIHaveNot);
PublicKey pubKey = OtrActivator.scOtrEngine.getRemotePublicKey(otrContact);
String remoteFingerprint =
OtrActivator.scOtrKeyManager.getFingerprintFromPublicKey(pubKey);
cbAction.setSelectedItem(OtrActivator.scOtrKeyManager
.isVerified(otrContact.contact, remoteFingerprint)
? actionIHave : actionIHaveNot);
pnlAction.add(cbAction, c);
txtAction = new CustomTextArea();
c.weightx = 1.0;
pnlAction.add(txtAction, c);
String resourceName = otrContact.resource != null ?
"/" + otrContact.resource.getResourceName() : "";
txtRemoteFingerprintComparison = new SIPCommTextField(
OtrActivator.resourceService
.getI18NString("plugin.otr.authbuddydialog.FINGERPRINT_CHECK",
new String[]
{otrContact.contact.getDisplayName() + resourceName}));
txtRemoteFingerprintComparison.getDocument().addDocumentListener(this);
c.gridwidth = 2;
c.gridy = 1;
pnlAction.add(txtRemoteFingerprintComparison, c);
c.gridwidth = 1;
c.gridy = 0;
}
public JComboBox getCbAction()
{
return cbAction;
}
/**
* Sets up the {@link OtrBuddyAuthenticationDialog} components so that they
* reflect the {@link OtrBuddyAuthenticationDialog#otrContact}
*/
private void loadContact()
{
// Local fingerprint.
String account =
otrContact.contact.getProtocolProvider().getAccountID().getDisplayName();
String localFingerprint =
OtrActivator.scOtrKeyManager.getLocalFingerprint(otrContact.contact
.getProtocolProvider().getAccountID());
txtLocalFingerprint.setText(OtrActivator.resourceService.getI18NString(
"plugin.otr.authbuddydialog.LOCAL_FINGERPRINT", new String[]
{ account, localFingerprint }));
// Remote fingerprint.
String user = otrContact.contact.getDisplayName();
PublicKey pubKey = OtrActivator.scOtrEngine.getRemotePublicKey(otrContact);
String remoteFingerprint =
OtrActivator.scOtrKeyManager.getFingerprintFromPublicKey(pubKey);
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()
{
PublicKey pubKey = OtrActivator.scOtrEngine.getRemotePublicKey(otrContact);
String remoteFingerprint =
OtrActivator.scOtrKeyManager.getFingerprintFromPublicKey(pubKey);
if(txtRemoteFingerprintComparison.getText() == null
|| txtRemoteFingerprintComparison.getText().length() == 0)
{
txtRemoteFingerprintComparison.setBackground(Color.white);
return;
}
if(txtRemoteFingerprintComparison.getText().toLowerCase().contains(
remoteFingerprint.toLowerCase()))
{
txtRemoteFingerprintComparison.setBackground(Color.green);
cbAction.setSelectedItem(actionIHave);
}
else
{
txtRemoteFingerprintComparison.setBackground(
new Color(243, 72, 48));
cbAction.setSelectedItem(actionIHaveNot);
}
}
/**
* 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;
}
}
}