Fixed issue with connections after accepting/overwriting a certificate for a host. Synchronized the ItoopieHostnameVerifier.verify(). Beware of potential performance issues.

This commit is contained in:
dev
2011-07-27 08:38:21 +00:00
parent 91ced23635
commit 46f0456d83
3 changed files with 61 additions and 29 deletions

View File

@ -7,6 +7,7 @@ import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import net.i2p.itoopie.i18n.Transl;
import net.i2p.itoopie.security.CertificateHelper;
@ -20,7 +21,7 @@ public class CertificateGUI {
System.out.println("Overwrite cert: " + overwriteCert(null,null));
}
public static boolean saveNewCert(String hostname, X509Certificate cert){
public static synchronized boolean saveNewCert(String hostname, X509Certificate cert){
if (!isVerifying){
isVerifying = true;
JFrame frame = new JFrame();
@ -60,6 +61,7 @@ public class CertificateGUI {
if (n == JOptionPane.YES_OPTION){
CertificateManager.forcePutServerCert(hostname, CertificateHelper.convert(cert));
updateUI();
isVerifying = false;
return true;
} else {
@ -116,6 +118,7 @@ public class CertificateGUI {
JOptionPane.ERROR_MESSAGE);
if (n == JOptionPane.YES_OPTION){
CertificateManager.forcePutServerCert(hostname, CertificateHelper.convert(cert));
updateUI();
isVerifying = false;
return true; // Confirmation positive
} else {
@ -129,4 +132,28 @@ public class CertificateGUI {
return false;
}
}
/**
* Upon new cert accepted it is probable a good idea to show it by updating the GUI.
*/
private static void updateUI(){
// Sleep before updating.
(new Thread(){
@Override
public void run(){
System.out.println("CertGUI Thread populateInfo() - sleep");
try {
Thread.sleep(250);
} catch (InterruptedException e) {}
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run() {
System.out.println("CertGUI Thread invokeLater populateInfo()");
Main.fireNewChange();
}
});
}
}).start();
}
}

View File

@ -128,10 +128,11 @@ public class OverviewTab extends TabLogoPanel {
@Override
public void run() {
while (true) {
System.out.println("Overview populateInfo()");
populateInfo();
try {
Thread.sleep(updateInterval);
} catch (InterruptedException e){} // Doesn't matter.
} catch (Exception e){} // Never stop.
}
}
}).start();

View File

@ -12,48 +12,52 @@ import org.apache.commons.logging.LogFactory;
import net.i2p.itoopie.gui.CertificateGUI;
public class ItoopieHostnameVerifier implements HostnameVerifier{
public class ItoopieHostnameVerifier implements HostnameVerifier {
private static final Log _log = LogFactory.getLog(ItoopieHostnameVerifier.class);
private static final HashSet<String> recentlyDeniedHosts = new HashSet<String>();
private static final Object _uiLock = new Object();
public boolean verify(String urlHostName, SSLSession session) {
String serverHost = session.getPeerHost() + ":" + session.getPeerPort();
try {
javax.security.cert.X509Certificate[] certs = session.getPeerCertificateChain();
if (recentlyDeniedHosts.contains(session.getPeerHost() + ":" + session.getPeerPort())){
return false; // Deny recently denied hosts.
}
synchronized (_uiLock) {
try {
javax.security.cert.X509Certificate[] certs = session.getPeerCertificateChain();
if (CertificateManager.contains(serverHost)) {
if (CertificateManager.verifyCert(serverHost,
CertificateHelper.convert(certs[0]))) {
return true; // Remote host has provided valid certificate that is stored locally.
if (recentlyDeniedHosts.contains(session.getPeerHost() + ":" + session.getPeerPort())) {
return false; // Deny recently denied hosts.
}
if (CertificateManager.contains(serverHost)) {
if (CertificateManager.verifyCert(serverHost, CertificateHelper.convert(certs[0]))) {
return true; // Remote host has provided valid certificate that is stored locally.
} else {
// Remote host has provided a certificate that != the stored certificate for this host
if (CertificateGUI.overwriteCert(serverHost, certs[0])) {
return true;
} else {
recentlyDeniedHosts.add(session.getPeerHost() + ":"
+ session.getPeerPort());
return false;
}
}
} else {
// Remote host has provided a certificate that != the stored certificate for this host
if (CertificateGUI.overwriteCert(serverHost, certs[0])){
// GUI, Add new host! new host
if (CertificateGUI.saveNewCert(serverHost, certs[0])) {
return true;
} else {
recentlyDeniedHosts.add(session.getPeerHost() + ":" + session.getPeerPort());
return false;
}
}
} else {
// GUI, Add new host! new host
if (CertificateGUI.saveNewCert(serverHost, certs[0])){
return true;
} else {
recentlyDeniedHosts.add(session.getPeerHost() + ":" + session.getPeerPort());
return false;
}
} catch (SSLPeerUnverifiedException e) {
_log.fatal("Remote host could not be verified, possibly due to using not using athentication");
return false;
}
} catch (SSLPeerUnverifiedException e) {
_log.fatal("Remote host could not be verified, possibly due to using not using athentication");
return false;
}
}
public static void clearRecentlyDenied(){
public static void clearRecentlyDenied() {
recentlyDeniedHosts.clear();
}
}