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.ntlm;
  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 import sun.net.www.protocol.http.AuthenticationInfo;
  35 import sun.net.www.protocol.http.AuthScheme;
  36 import sun.net.www.protocol.http.HttpURLConnection;
  37 
  38 /**
  39  * NTLMAuthentication:
  40  *
  41  * @author Michael McMahon
  42  */
  43 
  44 public class NTLMAuthentication extends AuthenticationInfo {
  45 
  46     private static final long serialVersionUID = 100L;
  47 
  48     private String hostname;
  49     private static String defaultDomain; /* Domain to use if not specified by user */
  50 
  51     static {
  52         defaultDomain = java.security.AccessController.doPrivileged(
  53             new sun.security.action.GetPropertyAction("http.auth.ntlm.domain",
  54                                                       "domain"));
  55     };
  56 
  57     private void init0() {
  58 
  59         hostname = java.security.AccessController.doPrivileged(
  60             new java.security.PrivilegedAction<String>() {
  61             public String run() {
  62                 String localhost;
  63                 try {
  64                     localhost = InetAddress.getLocalHost().getHostName().toUpperCase();
  65                 } catch (UnknownHostException e) {
  66                      localhost = "localhost";
  67                 }
  68                 return localhost;
  69             }
  70         });
  71         int x = hostname.indexOf ('.');
  72         if (x != -1) {
  73             hostname = hostname.substring (0, x);
  74         }
  75     }
  76 
  77     String username;
  78     String ntdomain;
  79     String password;
  80 
  81     /**
  82      * Create a NTLMAuthentication:
  83      * Username may be specified as domain<BACKSLASH>username in the application Authenticator.
  84      * If this notation is not used, then the domain will be taken
  85      * from a system property: "http.auth.ntlm.domain".
  86      */
  87     public NTLMAuthentication(boolean isProxy, URL url, PasswordAuthentication pw) {
  88         super(isProxy ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION,
  89               AuthScheme.NTLM,
  90               url,
  91               "");
  92         init (pw);
  93     }
  94 
  95     private void init (PasswordAuthentication pw) {
  96         this.pw = pw;
  97         if (pw != null) {
  98             String s = pw.getUserName();
  99             int i = s.indexOf ('\\');
 100             if (i == -1) {
 101                 username = s;
 102                 ntdomain = defaultDomain;
 103             } else {
 104                 ntdomain = s.substring (0, i).toUpperCase();
 105                 username = s.substring (i+1);
 106             }
 107             password = new String (pw.getPassword());
 108         } else {
 109             /* credentials will be acquired from OS */
 110             username = null;
 111             ntdomain = null;
 112             password = null;
 113         }
 114         init0();
 115     }
 116 
 117    /**
 118     * Constructor used for proxy entries
 119     */
 120     public NTLMAuthentication(boolean isProxy, String host, int port,
 121                                 PasswordAuthentication pw) {
 122         super(isProxy?PROXY_AUTHENTICATION:SERVER_AUTHENTICATION,
 123               AuthScheme.NTLM,
 124               host,
 125               port,
 126               "");
 127         init (pw);
 128     }
 129 
 130     /**
 131      * @return true if this authentication supports preemptive authorization
 132      */
 133     @Override
 134     public boolean supportsPreemptiveAuthorization() {
 135         return false;
 136     }
 137 
 138     /**
 139      * @return true if NTLM supported transparently (no password needed, SSO)
 140      */
 141     public static boolean supportsTransparentAuth() {
 142         return true;
 143     }
 144 
 145     /**











 146      * Not supported. Must use the setHeaders() method
 147      */
 148     @Override
 149     public String getHeaderValue(URL url, String method) {
 150         throw new RuntimeException ("getHeaderValue not supported");
 151     }
 152 
 153     /**
 154      * Check if the header indicates that the current auth. parameters are stale.
 155      * If so, then replace the relevant field with the new value
 156      * and return true. Otherwise return false.
 157      * returning true means the request can be retried with the same userid/password
 158      * returning false means we have to go back to the user to ask for a new
 159      * username password.
 160      */
 161     @Override
 162     public boolean isAuthorizationStale (String header) {
 163         return false; /* should not be called for ntlm */
 164     }
 165 
 166     /**
 167      * Set header(s) on the given connection.
 168      * @param conn The connection to apply the header(s) to
 169      * @param p A source of header values for this connection, not used because
 170      *          HeaderParser converts the fields to lower case, use raw instead
 171      * @param raw The raw header field.
 172      * @return true if all goes well, false if no headers were set.
 173      */
 174     @Override
 175     public synchronized boolean setHeaders(HttpURLConnection conn, HeaderParser p, String raw) {
 176 
 177         try {
 178             NTLMAuthSequence seq = (NTLMAuthSequence)conn.authObj();
 179             if (seq == null) {
 180                 seq = new NTLMAuthSequence (username, password, ntdomain);
 181                 conn.authObj(seq);
 182             }
 183             String response = "NTLM " + seq.getAuthHeader (raw.length()>6?raw.substring(5):null);
 184             conn.setAuthenticationProperty(getHeaderName(), response);
 185             return true;
 186         } catch (IOException e) {
 187             return false;
 188         }
 189     }
 190 
 191 }
--- EOF ---