All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.mail.util.SocketFetcher.JDK7.diff Maven / Gradle / Ivy

There is a newer version: 2.0.1
Show newest version
diff -r 377a55e66991 mail/src/main/java/com/sun/mail/util/SocketFetcher.java
--- a/mail/src/main/java/com/sun/mail/util/SocketFetcher.java	Tue Nov 29 12:22:07 2016 -0800
+++ b/mail/src/main/java/com/sun/mail/util/SocketFetcher.java	Fri Dec 09 16:51:48 2016 -0800
@@ -314,6 +314,7 @@
 		logger.finest("set socket read timeout " + to);
 	    socket.setSoTimeout(to);
 	}
+
 	int writeTimeout = PropUtil.getIntProperty(props,
 						prefix + ".writetimeout", -1);
 	if (writeTimeout != -1) {	// wrap original
@@ -591,19 +592,24 @@
 	}
 
 	/*
+	 * Check server identity and trust (RFC 2595 check, identical to
+	 * RFC 2830, which the JDK implements for LDAPS).
+	 */
+	boolean idCheck = PropUtil.getBooleanProperty(props,
+			    prefix + ".ssl.checkserveridentity", false);
+	if (idCheck) {
+	    SSLParameters sslp = sslsocket.getSSLParameters();
+	    sslp.setEndpointIdentificationAlgorithm("LDAPS");
+	    sslsocket.setSSLParameters(sslp);
+	}
+
+	/*
 	 * Force the handshake to be done now so that we can report any
 	 * errors (e.g., certificate errors) to the caller of the startTLS
 	 * method.
 	 */
 	sslsocket.startHandshake();
 
-	/*
-	 * Check server identity and trust.
-	 */
-	boolean idCheck = PropUtil.getBooleanProperty(props,
-			    prefix + ".ssl.checkserveridentity", false);
-	if (idCheck)
-	    checkServerIdentity(host, sslsocket);
 	if (sf instanceof MailSSLSocketFactory) {
 	    MailSSLSocketFactory msf = (MailSSLSocketFactory)sf;
 	    if (!msf.isServerTrusted(host, sslsocket)) {
@@ -638,150 +644,6 @@
     }
 
     /**
-     * Check the server from the Socket connection against the server name(s)
-     * as expressed in the server certificate (RFC 2595 check).
-     * 
-     * @param	server		name of the server expected
-     * @param   sslSocket	SSLSocket connected to the server
-     * @exception	IOException	if we can't verify identity of server
-     */
-    private static void checkServerIdentity(String server, SSLSocket sslSocket)
-				throws IOException {
-
-	// Check against the server name(s) as expressed in server certificate
-	try {
-	    java.security.cert.Certificate[] certChain =
-		      sslSocket.getSession().getPeerCertificates();
-	    if (certChain != null && certChain.length > 0 &&
-		    certChain[0] instanceof X509Certificate &&
-		    matchCert(server, (X509Certificate)certChain[0]))
-		return;
-	} catch (SSLPeerUnverifiedException e) {
-	    sslSocket.close();
-	    IOException ioex = new IOException(
-		"Can't verify identity of server: " + server);
-	    ioex.initCause(e);
-	    throw ioex;
-	}
-
-	// If we get here, there is nothing to consider the server as trusted.
-	sslSocket.close();
-	throw new IOException("Can't verify identity of server: " + server);
-    }
-
-    /**
-     * Do any of the names in the cert match the server name?
-     *  
-     * @param	server	name of the server expected
-     * @param   cert	X509Certificate to get the subject's name from
-     * @return  true if it matches
-     */
-    private static boolean matchCert(String server, X509Certificate cert) {
-	if (logger.isLoggable(Level.FINER))
-	    logger.finer("matchCert server " +
-		server + ", cert " + cert);
-
-	/*
-	 * First, try to use sun.security.util.HostnameChecker,
-	 * which exists in Sun's JDK starting with 1.4.1.
-	 * We use reflection to access it in case it's not available
-	 * in the JDK we're running on.
-	 */
-	try {
-	    Class hnc = Class.forName("sun.security.util.HostnameChecker");
-	    // invoke HostnameChecker.getInstance(HostnameChecker.TYPE_LDAP)
-	    // HostnameChecker.TYPE_LDAP == 2
-	    // LDAP requires the same regex handling as we need
-	    Method getInstance = hnc.getMethod("getInstance", 
-					new Class[] { byte.class });
-	    Object hostnameChecker = getInstance.invoke(new Object(),
-					new Object[] { Byte.valueOf((byte)2) });
-
-	    // invoke hostnameChecker.match( server, cert)
-	    if (logger.isLoggable(Level.FINER))
-		logger.finer("using sun.security.util.HostnameChecker");
-	    Method match = hnc.getMethod("match",
-			new Class[] { String.class, X509Certificate.class });
-	    try {
-		match.invoke(hostnameChecker, new Object[] { server, cert });
-		return true;
-	    } catch (InvocationTargetException cex) {
-		logger.log(Level.FINER, "HostnameChecker FAIL", cex);
-		return false;
-	    }
-	} catch (Exception ex) {
-	    logger.log(Level.FINER, "NO sun.security.util.HostnameChecker", ex);
-	    // ignore failure and continue below
-	}
-
-	/*
-	 * Lacking HostnameChecker, we implement a crude version of
-	 * the same checks ourselves.
-	 */
-	try {
-	    /*
-	     * Check each of the subjectAltNames.
-	     * XXX - only checks DNS names, should also handle
-	     * case where server name is a literal IP address
-	     */
-	    Collection> names = cert.getSubjectAlternativeNames();
-	    if (names != null) {
-		boolean foundName = false;
-		for (Iterator> it = names.iterator(); it.hasNext(); ) {
-		    List nameEnt = it.next();
-		    Integer type = (Integer)nameEnt.get(0);
-		    if (type.intValue() == 2) {	// 2 == dNSName
-			foundName = true;
-			String name = (String)nameEnt.get(1);
-			if (logger.isLoggable(Level.FINER))
-			    logger.finer("found name: " + name);
-			if (matchServer(server, name))
-			    return true;
-		    }
-		}
-		if (foundName)	// found a name, but no match
-		    return false;
-	    }
-	} catch (CertificateParsingException ex) {
-	    // ignore it
-	}
-
-	// XXX - following is a *very* crude parse of the name and ignores
-	//	 all sorts of important issues such as quoting
-	Pattern p = Pattern.compile("CN=([^,]*)");
-	Matcher m = p.matcher(cert.getSubjectX500Principal().getName());
-	if (m.find() && matchServer(server, m.group(1).trim()))
-	    return true;
-
-	return false;
-    }
-
-    /**
-     * Does the server we're expecting to connect to match the
-     * given name from the server's certificate?
-     *
-     * @param	server		name of the server expected
-     * @param	name		name from the server's certificate
-     */
-    private static boolean matchServer(String server, String name) {
-	if (logger.isLoggable(Level.FINER))
-	    logger.finer("match server " + server + " with " + name);
-	if (name.startsWith("*.")) {
-	    // match "foo.example.com" with "*.example.com"
-	    String tail = name.substring(2);
-	    if (tail.length() == 0)
-		return false;
-	    int off = server.length() - tail.length();
-	    if (off < 1)
-		return false;
-	    // if tail matches and is preceeded by "."
-	    return server.charAt(off - 1) == '.' &&
-		    server.regionMatches(true, off, tail, 0, tail.length());
-	} else
-	    return server.equalsIgnoreCase(name);
-    }
-
-    /**
      * Parse a string into whitespace separated tokens
      * and return the tokens in an array.
      */




© 2015 - 2024 Weber Informatics LLC | Privacy Policy