1/* 2 * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25package sun.net.www.protocol.http; 26 27import java.net.URL; 28import java.net.PasswordAuthentication; 29import java.lang.reflect.Constructor; 30import java.lang.reflect.Method; 31import sun.util.logging.PlatformLogger; 32 33/** 34 * Proxy class for loading NTLMAuthentication, so as to remove static 35 * dependancy. 36 */ 37class NTLMAuthenticationProxy { 38 private static Method supportsTA; 39 private static Method isTrustedSite; 40 private static final String clazzStr = "sun.net.www.protocol.http.ntlm.NTLMAuthentication"; 41 private static final String supportsTAStr = "supportsTransparentAuth"; 42 private static final String isTrustedSiteStr = "isTrustedSite"; 43 44 static final NTLMAuthenticationProxy proxy = tryLoadNTLMAuthentication(); 45 static final boolean supported = proxy != null ? true : false; 46 static final boolean supportsTransparentAuth = supported ? supportsTransparentAuth() : false; 47 48 private final Constructor<? extends AuthenticationInfo> fourArgCtr; 49 private final Constructor<? extends AuthenticationInfo> sixArgCtr; 50 51 private NTLMAuthenticationProxy(Constructor<? extends AuthenticationInfo> fourArgCtr, 52 Constructor<? extends AuthenticationInfo> sixArgCtr) { 53 this.fourArgCtr = fourArgCtr; 54 this.sixArgCtr = sixArgCtr; 55 } 56 57 58 AuthenticationInfo create(boolean isProxy, 59 URL url, 60 PasswordAuthentication pw, 61 String authenticatorKey) { 62 try { 63 return fourArgCtr.newInstance(isProxy, url, pw, authenticatorKey); 64 } catch (ReflectiveOperationException roe) { 65 finest(roe); 66 } 67 68 return null; 69 } 70 71 AuthenticationInfo create(boolean isProxy, 72 String host, 73 int port, 74 PasswordAuthentication pw, 75 String authenticatorKey) { 76 try { 77 return sixArgCtr.newInstance(isProxy, host, port, pw, authenticatorKey); 78 } catch (ReflectiveOperationException roe) { 79 finest(roe); 80 } 81 82 return null; 83 } 84 85 /* Returns true if the NTLM implementation supports transparent 86 * authentication (try with the current users credentials before 87 * prompting for username and password, etc). 88 */ 89 private static boolean supportsTransparentAuth() { 90 try { 91 return (Boolean)supportsTA.invoke(null); 92 } catch (ReflectiveOperationException roe) { 93 finest(roe); 94 } 95 96 return false; 97 } 98 99 /* Transparent authentication should only be tried with a trusted 100 * site ( when running in a secure environment ). 101 */ 102 public static boolean isTrustedSite(URL url) { 103 try { 104 return (Boolean)isTrustedSite.invoke(null, url); 105 } catch (ReflectiveOperationException roe) { 106 finest(roe); 107 } 108 109 return false; 110 } 111 112 /** 113 * Loads the NTLM authentiation implementation through reflection. If 114 * the class is present, then it must have the required constructors and 115 * method. Otherwise, it is considered an error. 116 */ 117 @SuppressWarnings("unchecked") 118 private static NTLMAuthenticationProxy tryLoadNTLMAuthentication() { 119 Class<? extends AuthenticationInfo> cl; 120 Constructor<? extends AuthenticationInfo> fourArg, sixArg; 121 try { 122 cl = (Class<? extends AuthenticationInfo>)Class.forName(clazzStr, true, null); 123 if (cl != null) { 124 fourArg = cl.getConstructor(boolean.class, 125 URL.class, 126 PasswordAuthentication.class, 127 String.class); 128 sixArg = cl.getConstructor(boolean.class, 129 String.class, 130 int.class, 131 PasswordAuthentication.class, 132 String.class); 133 supportsTA = cl.getDeclaredMethod(supportsTAStr); 134 isTrustedSite = cl.getDeclaredMethod(isTrustedSiteStr, java.net.URL.class); 135 return new NTLMAuthenticationProxy(fourArg, 136 sixArg); 137 } 138 } catch (ClassNotFoundException cnfe) { 139 finest(cnfe); 140 } catch (ReflectiveOperationException roe) { 141 throw new AssertionError(roe); 142 } 143 144 return null; 145 } 146 147 static void finest(Exception e) { 148 PlatformLogger logger = HttpURLConnection.getHttpLogger(); 149 if (logger.isLoggable(PlatformLogger.Level.FINEST)) { 150 logger.finest("NTLMAuthenticationProxy: " + e); 151 } 152 } 153} 154