1 /*
   2  * Copyright (c) 1997, 2013, 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  */
  25 
  26 package java.net;
  27 
  28 /**
  29  * The class Authenticator represents an object that knows how to obtain
  30  * authentication for a network connection.  Usually, it will do this
  31  * by prompting the user for information.
  32  * <p>
  33  * Applications use this class by overriding {@link
  34  * #getPasswordAuthentication()} in a sub-class. This method will
  35  * typically use the various getXXX() accessor methods to get information
  36  * about the entity requesting authentication. It must then acquire a
  37  * username and password either by interacting with the user or through
  38  * some other non-interactive means. The credentials are then returned
  39  * as a {@link PasswordAuthentication} return value.
  40  * <p>
  41  * An instance of this concrete sub-class is then registered
  42  * with the system by calling {@link #setDefault(Authenticator)}.
  43  * When authentication is required, the system will invoke one of the
  44  * requestPasswordAuthentication() methods which in turn will call the
  45  * getPasswordAuthentication() method of the registered object.
  46  * <p>
  47  * All methods that request authentication have a default implementation
  48  * that fails.
  49  *
  50  * @see java.net.Authenticator#setDefault(java.net.Authenticator)
  51  * @see java.net.Authenticator#getPasswordAuthentication()
  52  *
  53  * @author  Bill Foote
  54  * @since   1.2
  55  */
  56 
  57 // There are no abstract methods, but to be useful the user must
  58 // subclass.
  59 public abstract
  60 class Authenticator {
  61 
  62     // The system-wide authenticator object.  See setDefault().
  63     private static volatile Authenticator theAuthenticator;
  64 
  65     private String requestingHost;
  66     private InetAddress requestingSite;
  67     private int requestingPort;
  68     private String requestingProtocol;
  69     private String requestingPrompt;
  70     private String requestingScheme;
  71     private URL requestingURL;
  72     private RequestorType requestingAuthType;
  73 
  74     /**
  75      * The type of the entity requesting authentication.
  76      *
  77      * @since 1.5
  78      */
  79     public enum RequestorType {
  80         /**
  81          * Entity requesting authentication is a HTTP proxy server.
  82          */
  83         PROXY,
  84         /**
  85          * Entity requesting authentication is a HTTP origin server.
  86          */
  87         SERVER
  88     }
  89 
  90     private void reset() {
  91         requestingHost = null;
  92         requestingSite = null;
  93         requestingPort = -1;
  94         requestingProtocol = null;
  95         requestingPrompt = null;
  96         requestingScheme = null;
  97         requestingURL = null;
  98         requestingAuthType = RequestorType.SERVER;
  99     }
 100 
 101 
 102     /**
 103      * Sets the authenticator that will be used by the networking code
 104      * when a proxy or an HTTP server asks for authentication.
 105      * <p>
 106      * First, if there is a security manager, its {@code checkPermission}
 107      * method is called with a
 108      * {@code NetPermission("setDefaultAuthenticator")} permission.
 109      * This may result in a java.lang.SecurityException.
 110      *
 111      * @param   a       The authenticator to be set. If a is {@code null} then
 112      *                  any previously set authenticator is removed.
 113      *
 114      * @throws SecurityException
 115      *        if a security manager exists and its
 116      *        {@code checkPermission} method doesn't allow
 117      *        setting the default authenticator.
 118      *
 119      * @see SecurityManager#checkPermission
 120      * @see java.net.NetPermission
 121      */
 122     public synchronized static void setDefault(Authenticator a) {
 123         SecurityManager sm = System.getSecurityManager();
 124         if (sm != null) {
 125             NetPermission setDefaultPermission
 126                 = new NetPermission("setDefaultAuthenticator");
 127             sm.checkPermission(setDefaultPermission);
 128         }
 129 
 130         theAuthenticator = a;
 131     }
 132 
 133     /**
 134      * Ask the authenticator that has been registered with the system
 135      * for a password.
 136      * <p>
 137      * First, if there is a security manager, its {@code checkPermission}
 138      * method is called with a
 139      * {@code NetPermission("requestPasswordAuthentication")} permission.
 140      * This may result in a java.lang.SecurityException.
 141      *
 142      * @param addr The InetAddress of the site requesting authorization,
 143      *             or null if not known.
 144      * @param port the port for the requested connection
 145      * @param protocol The protocol that's requesting the connection
 146      *          ({@link java.net.Authenticator#getRequestingProtocol()})
 147      * @param prompt A prompt string for the user
 148      * @param scheme The authentication scheme
 149      *
 150      * @return The username/password, or null if one can't be gotten.
 151      *
 152      * @throws SecurityException
 153      *        if a security manager exists and its
 154      *        {@code checkPermission} method doesn't allow
 155      *        the password authentication request.
 156      *
 157      * @see SecurityManager#checkPermission
 158      * @see java.net.NetPermission
 159      */
 160     public static PasswordAuthentication requestPasswordAuthentication(
 161                                             InetAddress addr,
 162                                             int port,
 163                                             String protocol,
 164                                             String prompt,
 165                                             String scheme) {
 166 
 167         SecurityManager sm = System.getSecurityManager();
 168         if (sm != null) {
 169             NetPermission requestPermission
 170                 = new NetPermission("requestPasswordAuthentication");
 171             sm.checkPermission(requestPermission);
 172         }
 173 
 174         Authenticator a = theAuthenticator;
 175         if (a == null) {
 176             return null;
 177         } else {
 178             synchronized(a) {
 179                 a.reset();
 180                 a.requestingSite = addr;
 181                 a.requestingPort = port;
 182                 a.requestingProtocol = protocol;
 183                 a.requestingPrompt = prompt;
 184                 a.requestingScheme = scheme;
 185                 return a.getPasswordAuthentication();
 186             }
 187         }
 188     }
 189 
 190     /**
 191      * Ask the authenticator that has been registered with the system
 192      * for a password. This is the preferred method for requesting a password
 193      * because the hostname can be provided in cases where the InetAddress
 194      * is not available.
 195      * <p>
 196      * First, if there is a security manager, its {@code checkPermission}
 197      * method is called with a
 198      * {@code NetPermission("requestPasswordAuthentication")} permission.
 199      * This may result in a java.lang.SecurityException.
 200      *
 201      * @param host The hostname of the site requesting authentication.
 202      * @param addr The InetAddress of the site requesting authentication,
 203      *             or null if not known.
 204      * @param port the port for the requested connection.
 205      * @param protocol The protocol that's requesting the connection
 206      *          ({@link java.net.Authenticator#getRequestingProtocol()})
 207      * @param prompt A prompt string for the user which identifies the authentication realm.
 208      * @param scheme The authentication scheme
 209      *
 210      * @return The username/password, or null if one can't be gotten.
 211      *
 212      * @throws SecurityException
 213      *        if a security manager exists and its
 214      *        {@code checkPermission} method doesn't allow
 215      *        the password authentication request.
 216      *
 217      * @see SecurityManager#checkPermission
 218      * @see java.net.NetPermission
 219      * @since 1.4
 220      */
 221     public static PasswordAuthentication requestPasswordAuthentication(
 222                                             String host,
 223                                             InetAddress addr,
 224                                             int port,
 225                                             String protocol,
 226                                             String prompt,
 227                                             String scheme) {
 228 
 229         SecurityManager sm = System.getSecurityManager();
 230         if (sm != null) {
 231             NetPermission requestPermission
 232                 = new NetPermission("requestPasswordAuthentication");
 233             sm.checkPermission(requestPermission);
 234         }
 235 
 236         Authenticator a = theAuthenticator;
 237         if (a == null) {
 238             return null;
 239         } else {
 240             synchronized(a) {
 241                 a.reset();
 242                 a.requestingHost = host;
 243                 a.requestingSite = addr;
 244                 a.requestingPort = port;
 245                 a.requestingProtocol = protocol;
 246                 a.requestingPrompt = prompt;
 247                 a.requestingScheme = scheme;
 248                 return a.getPasswordAuthentication();
 249             }
 250         }
 251     }
 252 
 253     /**
 254      * Ask the authenticator that has been registered with the system
 255      * for a password.
 256      * <p>
 257      * First, if there is a security manager, its {@code checkPermission}
 258      * method is called with a
 259      * {@code NetPermission("requestPasswordAuthentication")} permission.
 260      * This may result in a java.lang.SecurityException.
 261      *
 262      * @param host The hostname of the site requesting authentication.
 263      * @param addr The InetAddress of the site requesting authorization,
 264      *             or null if not known.
 265      * @param port the port for the requested connection
 266      * @param protocol The protocol that's requesting the connection
 267      *          ({@link java.net.Authenticator#getRequestingProtocol()})
 268      * @param prompt A prompt string for the user
 269      * @param scheme The authentication scheme
 270      * @param url The requesting URL that caused the authentication
 271      * @param reqType The type (server or proxy) of the entity requesting
 272      *              authentication.
 273      *
 274      * @return The username/password, or null if one can't be gotten.
 275      *
 276      * @throws SecurityException
 277      *        if a security manager exists and its
 278      *        {@code checkPermission} method doesn't allow
 279      *        the password authentication request.
 280      *
 281      * @see SecurityManager#checkPermission
 282      * @see java.net.NetPermission
 283      *
 284      * @since 1.5
 285      */
 286     public static PasswordAuthentication requestPasswordAuthentication(
 287                                     String host,
 288                                     InetAddress addr,
 289                                     int port,
 290                                     String protocol,
 291                                     String prompt,
 292                                     String scheme,
 293                                     URL url,
 294                                     RequestorType reqType) {
 295 
 296         SecurityManager sm = System.getSecurityManager();
 297         if (sm != null) {
 298             NetPermission requestPermission
 299                 = new NetPermission("requestPasswordAuthentication");
 300             sm.checkPermission(requestPermission);
 301         }
 302 
 303         Authenticator a = theAuthenticator;
 304         if (a == null) {
 305             return null;
 306         } else {
 307             synchronized(a) {
 308                 a.reset();
 309                 a.requestingHost = host;
 310                 a.requestingSite = addr;
 311                 a.requestingPort = port;
 312                 a.requestingProtocol = protocol;
 313                 a.requestingPrompt = prompt;
 314                 a.requestingScheme = scheme;
 315                 a.requestingURL = url;
 316                 a.requestingAuthType = reqType;
 317                 return a.getPasswordAuthentication();
 318             }
 319         }
 320     }
 321 
 322     /**
 323      * Gets the {@code hostname} of the
 324      * site or proxy requesting authentication, or {@code null}
 325      * if not available.
 326      *
 327      * @return the hostname of the connection requiring authentication, or null
 328      *          if it's not available.
 329      * @since 1.4
 330      */
 331     protected final String getRequestingHost() {
 332         return requestingHost;
 333     }
 334 
 335     /**
 336      * Gets the {@code InetAddress} of the
 337      * site requesting authorization, or {@code null}
 338      * if not available.
 339      *
 340      * @return the InetAddress of the site requesting authorization, or null
 341      *          if it's not available.
 342      */
 343     protected final InetAddress getRequestingSite() {
 344         return requestingSite;
 345     }
 346 
 347     /**
 348      * Gets the port number for the requested connection.
 349      * @return an {@code int} indicating the
 350      * port for the requested connection.
 351      */
 352     protected final int getRequestingPort() {
 353         return requestingPort;
 354     }
 355 
 356     /**
 357      * Give the protocol that's requesting the connection.  Often this
 358      * will be based on a URL, but in a future JDK it could be, for
 359      * example, "SOCKS" for a password-protected SOCKS5 firewall.
 360      *
 361      * @return the protocol, optionally followed by "/version", where
 362      *          version is a version number.
 363      *
 364      * @see java.net.URL#getProtocol()
 365      */
 366     protected final String getRequestingProtocol() {
 367         return requestingProtocol;
 368     }
 369 
 370     /**
 371      * Gets the prompt string given by the requestor.
 372      *
 373      * @return the prompt string given by the requestor (realm for
 374      *          http requests)
 375      */
 376     protected final String getRequestingPrompt() {
 377         return requestingPrompt;
 378     }
 379 
 380     /**
 381      * Gets the scheme of the requestor (the HTTP scheme
 382      * for an HTTP firewall, for example).
 383      *
 384      * @return the scheme of the requestor
 385      *
 386      */
 387     protected final String getRequestingScheme() {
 388         return requestingScheme;
 389     }
 390 
 391     /**
 392      * Called when password authorization is needed.  Subclasses should
 393      * override the default implementation, which returns null.
 394      * @return The PasswordAuthentication collected from the
 395      *          user, or null if none is provided.
 396      */
 397     protected PasswordAuthentication getPasswordAuthentication() {
 398         return null;
 399     }
 400 
 401     /**
 402      * Returns the URL that resulted in this
 403      * request for authentication.
 404      *
 405      * @since 1.5
 406      *
 407      * @return the requesting URL
 408      *
 409      */
 410     protected URL getRequestingURL () {
 411         return requestingURL;
 412     }
 413 
 414     /**
 415      * Returns whether the requestor is a Proxy or a Server.
 416      *
 417      * @since 1.5
 418      *
 419      * @return the authentication type of the requestor
 420      *
 421      */
 422     protected RequestorType getRequestorType () {
 423         return requestingAuthType;
 424     }
 425 }