151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* 251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved. 351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it 651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as 751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation. Oracle designates this 851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided 951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code. 1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT 1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that 1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code). 1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version 1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation, 1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any 2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions. 2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage sun.net.www.protocol.http; 2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.net.URL; 2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.IOException; 3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.net.Authenticator.RequestorType; 3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.HashMap; 3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.net.www.HeaderParser; 3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.misc.BASE64Decoder; 3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.misc.BASE64Encoder; 3551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport static sun.net.www.protocol.http.AuthScheme.NEGOTIATE; 3651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport static sun.net.www.protocol.http.AuthScheme.KERBEROS; 3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/** 3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * NegotiateAuthentication: 4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @author weijun.wang@sun.com 4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.6 4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiclass NegotiateAuthentication extends AuthenticationInfo { 4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final long serialVersionUID = 100L; 4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski final private HttpCallerInfo hci; 5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // These maps are used to manage the GSS availability for diffrent 5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // hosts. The key for both maps is the host name. 5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // <code>supported</code> is set when isSupported is checked, 5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // if it's true, a cached Negotiator is put into <code>cache</code>. 5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // the cache can be used only once, so after the first use, it's cleaned. 5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static HashMap <String, Boolean> supported = null; 5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static HashMap <String, Negotiator> cache = null; 5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // The HTTP Negotiate Helper 6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private Negotiator negotiator = null; 6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Constructor used for both WWW and proxy entries. 6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param hci a schemed object. 6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public NegotiateAuthentication(HttpCallerInfo hci) { 6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski super(RequestorType.PROXY==hci.authType ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION, 6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski hci.scheme.equalsIgnoreCase("Negotiate") ? NEGOTIATE : KERBEROS, 6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski hci.url, 7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ""); 7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.hci = hci; 7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return true if this authentication supports preemptive authorization 7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski @Override 7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean supportsPreemptiveAuthorization() { 7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Find out if the HttpCallerInfo supports Negotiate protocol. In order to 8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * find out yes or no, an initialization of a Negotiator object against it 8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * is tried. The generated object will be cached under the name of ths 8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * hostname at a success try.<br> 8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If this method is called for the second time on an HttpCallerInfo with 8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the same hostname, the answer is retrieved from cache. 9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return true if supported 9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized public static boolean isSupported(HttpCallerInfo hci) { 9451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (supported == null) { 9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski supported = new HashMap <String, Boolean>(); 9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cache = new HashMap <String, Negotiator>(); 9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String hostname = hci.host; 9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski hostname = hostname.toLowerCase(); 10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (supported.containsKey(hostname)) { 10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return supported.get(hostname); 10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Negotiator neg = Negotiator.getNegotiator(hci); 10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (neg != null) { 10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski supported.put(hostname, true); 10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // the only place cache.put is called. here we can make sure 10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // the object is valid and the oneToken inside is not null 10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cache.put(hostname, neg); 11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski supported.put(hostname, false); 11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Not supported. Must use the setHeaders() method 11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski @Override 12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public String getHeaderValue(URL url, String method) { 12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new RuntimeException ("getHeaderValue not supported"); 12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Check if the header indicates that the current auth. parameters are stale. 12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If so, then replace the relevant field with the new value 12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * and return true. Otherwise return false. 12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * returning true means the request can be retried with the same userid/password 13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * returning false means we have to go back to the user to ask for a new 13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * username password. 13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski @Override 13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public boolean isAuthorizationStale (String header) { 13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; /* should not be called for Negotiate */ 13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Set header(s) on the given connection. 14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param conn The connection to apply the header(s) to 14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param p A source of header values for this connection, not used because 14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * HeaderParser converts the fields to lower case, use raw instead 14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param raw The raw header field. 14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return true if all goes well, false if no headers were set. 14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski @Override 14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public synchronized boolean setHeaders(HttpURLConnection conn, HeaderParser p, String raw) { 14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String response; 15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski byte[] incoming = null; 15251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String[] parts = raw.split("\\s+"); 15351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (parts.length > 1) { 15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski incoming = new BASE64Decoder().decodeBuffer(parts[1]); 15551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski response = hci.scheme + " " + new B64Encoder().encode( 15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski incoming==null?firstToken():nextToken(incoming)); 15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski conn.setAuthenticationProperty(getHeaderName(), response); 16051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return true; 16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException e) { 16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return false; 16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * return the first token. 16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @returns the token 16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException if <code>Negotiator.getNegotiator()</code> or 17051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>Negotiator.firstToken()</code> failed. 17151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 17251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private byte[] firstToken() throws IOException { 17351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski negotiator = null; 17451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (cache != null) { 17551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized(cache) { 17651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski negotiator = cache.get(getHost()); 17751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (negotiator != null) { 17851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cache.remove(getHost()); // so that it is only used once 17951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 18051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (negotiator == null) { 18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski negotiator = Negotiator.getNegotiator(hci); 18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (negotiator == null) { 18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski IOException ioe = new IOException("Cannot initialize Negotiator"); 18651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw ioe; 18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return negotiator.firstToken(); 19151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * return more tokens 19551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param token the token to be fed into <code>negotiator.nextToken()</code> 19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @returns the token 19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @throws IOException if <code>negotiator.nextToken()</code> throws Exception. 19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * May happen if the input token is invalid. 19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private byte[] nextToken(byte[] token) throws IOException { 20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return negotiator.nextToken(token); 20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 20351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski class B64Encoder extends BASE64Encoder { 20551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected int bytesPerLine () { 20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 100000; // as big as it can be, maybe INT_MAX 20751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 21051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // MS will send a final WWW-Authenticate even if the status is already 21151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // 200 OK. The token can be fed into initSecContext() again to determine 21251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // if the server can be trusted. This is not the same concept as Digest's 21351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Authentication-Info header. 21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // 21551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Currently we ignore this header. 21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 21751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 218