1 /* 2 * Copyright 2002-2005 Sun Microsystems, Inc. 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. Sun designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 22 * CA 95054 USA or visit www.sun.com if you need additional information or 23 * have any questions. 24 */ 25 26 package sun.net.www.protocol.http; 27 28 import java.io.IOException; 29 import java.net.InetAddress; 30 import java.net.PasswordAuthentication; 31 import java.net.UnknownHostException; 32 import java.net.URL; 33 import sun.net.www.HeaderParser; 34 35 /** 36 * NTLMAuthentication: 37 * 38 * @author Michael McMahon 39 */ 40 41 class NTLMAuthentication extends AuthenticationInfo { 42 43 private static final long serialVersionUID = 100L; 44 45 private String hostname; 46 private static String defaultDomain; /* Domain to use if not specified by user */ 47 48 static { 49 defaultDomain = java.security.AccessController.doPrivileged( 50 new sun.security.action.GetPropertyAction("http.auth.ntlm.domain", 51 "domain")); 52 }; 53 54 private void init0() { 55 56 hostname = java.security.AccessController.doPrivileged( 57 new java.security.PrivilegedAction<String>() { 58 public String run() { 59 String localhost; 60 try { 61 localhost = InetAddress.getLocalHost().getHostName().toUpperCase(); 62 } catch (UnknownHostException e) { 63 localhost = "localhost"; 64 } 65 return localhost; 66 } 67 }); 68 int x = hostname.indexOf ('.'); 69 if (x != -1) { 70 hostname = hostname.substring (0, x); 71 } 72 } 73 74 String username; 75 String ntdomain; 76 String password; 77 78 /** 79 * Create a NTLMAuthentication: 80 * Username may be specified as domain<BACKSLASH>username in the application Authenticator. 81 * If this notation is not used, then the domain will be taken 82 * from a system property: "http.auth.ntlm.domain". 83 */ 84 public NTLMAuthentication(boolean isProxy, URL url, PasswordAuthentication pw) { 85 super(isProxy ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION, 86 AuthScheme.NTLM, 87 url, 88 ""); 89 init (pw); 90 } 91 92 private void init (PasswordAuthentication pw) { 93 this.pw = pw; 94 if (pw != null) { 95 String s = pw.getUserName(); 96 int i = s.indexOf ('\\'); 97 if (i == -1) { 98 username = s; 99 ntdomain = defaultDomain; 100 } else { 101 ntdomain = s.substring (0, i).toUpperCase(); 102 username = s.substring (i+1); 103 } 104 password = new String (pw.getPassword()); 105 } else { 106 /* credentials will be acquired from OS */ 107 username = null; 108 ntdomain = null; 109 password = null; 110 } 111 init0(); 112 } 113 114 /** 115 * Constructor used for proxy entries 116 */ 117 public NTLMAuthentication(boolean isProxy, String host, int port, 118 PasswordAuthentication pw) { 119 super(isProxy?PROXY_AUTHENTICATION:SERVER_AUTHENTICATION, 120 AuthScheme.NTLM, 121 host, 122 port, 123 ""); 124 init (pw); 125 } 126 127 /** 128 * @return true if this authentication supports preemptive authorization 129 */ 130 boolean supportsPreemptiveAuthorization() { 131 return false; 132 } 133 134 /** 135 * @return true if NTLM supported transparently (no password needed, SSO) 136 */ 137 static boolean supportsTransparentAuth() { 138 return true; 139 } 140 141 /** 142 * @return the name of the HTTP header this authentication wants set 143 */ 144 String getHeaderName() { 145 if (type == SERVER_AUTHENTICATION) { 146 return "Authorization"; 147 } else { 148 return "Proxy-authorization"; 149 } 150 } 151 152 /** 153 * Not supported. Must use the setHeaders() method 154 */ 155 String getHeaderValue(URL url, String method) { 156 throw new RuntimeException ("getHeaderValue not supported"); 157 } 158 159 /** 160 * Check if the header indicates that the current auth. parameters are stale. 161 * If so, then replace the relevant field with the new value 162 * and return true. Otherwise return false. 163 * returning true means the request can be retried with the same userid/password 164 * returning false means we have to go back to the user to ask for a new 165 * username password. 166 */ 167 boolean isAuthorizationStale (String header) { 168 return false; /* should not be called for ntlm */ 169 } 170 171 /** 172 * Set header(s) on the given connection. 173 * @param conn The connection to apply the header(s) to 174 * @param p A source of header values for this connection, not used because 175 * HeaderParser converts the fields to lower case, use raw instead 176 * @param raw The raw header field. 177 * @return true if all goes well, false if no headers were set. 178 */ 179 synchronized boolean setHeaders(HttpURLConnection conn, HeaderParser p, String raw) { 180 181 try { 182 NTLMAuthSequence seq = (NTLMAuthSequence)conn.authObj; 183 if (seq == null) { 184 seq = new NTLMAuthSequence (username, password, ntdomain); 185 conn.authObj = seq; 186 } 187 String response = "NTLM " + seq.getAuthHeader (raw.length()>6?raw.substring(5):null); 188 conn.setAuthenticationProperty(getHeaderName(), response); 189 return true; 190 } catch (IOException e) { 191 return false; 192 } 193 } 194 195 }