blob: 124a8c051e2373b14815e1864261115de6893066 [file] [log] [blame]
package org.eclipse.aether.transport.http;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.Credentials;
import org.apache.http.auth.NTCredentials;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.eclipse.aether.repository.AuthenticationContext;
/**
* Credentials provider that defers calls into the auth context until authentication is actually requested.
*/
final class DeferredCredentialsProvider
implements CredentialsProvider
{
private final CredentialsProvider delegate;
private final Map<AuthScope, Factory> factories;
DeferredCredentialsProvider()
{
delegate = new BasicCredentialsProvider();
factories = new HashMap<>();
}
public void setCredentials( AuthScope authScope, Factory factory )
{
factories.put( authScope, factory );
}
public void setCredentials( AuthScope authScope, Credentials credentials )
{
delegate.setCredentials( authScope, credentials );
}
public Credentials getCredentials( AuthScope authScope )
{
synchronized ( factories )
{
for ( Iterator<Map.Entry<AuthScope, Factory>> it = factories.entrySet().iterator(); it.hasNext(); )
{
Map.Entry<AuthScope, Factory> entry = it.next();
if ( authScope.match( entry.getKey() ) >= 0 )
{
it.remove();
delegate.setCredentials( entry.getKey(), entry.getValue().newCredentials() );
}
}
}
return delegate.getCredentials( authScope );
}
public void clear()
{
delegate.clear();
}
interface Factory
{
Credentials newCredentials();
}
static class BasicFactory
implements Factory
{
private final AuthenticationContext authContext;
BasicFactory( AuthenticationContext authContext )
{
this.authContext = authContext;
}
public Credentials newCredentials()
{
String username = authContext.get( AuthenticationContext.USERNAME );
if ( username == null )
{
return null;
}
String password = authContext.get( AuthenticationContext.PASSWORD );
return new UsernamePasswordCredentials( username, password );
}
}
static class NtlmFactory
implements Factory
{
private final AuthenticationContext authContext;
NtlmFactory( AuthenticationContext authContext )
{
this.authContext = authContext;
}
public Credentials newCredentials()
{
String username = authContext.get( AuthenticationContext.USERNAME );
if ( username == null )
{
return null;
}
String password = authContext.get( AuthenticationContext.PASSWORD );
String domain = authContext.get( AuthenticationContext.NTLM_DOMAIN );
String workstation = authContext.get( AuthenticationContext.NTLM_WORKSTATION );
if ( domain == null )
{
int backslash = username.indexOf( '\\' );
if ( backslash < 0 )
{
domain = guessDomain();
}
else
{
domain = username.substring( 0, backslash );
username = username.substring( backslash + 1 );
}
}
if ( workstation == null )
{
workstation = guessWorkstation();
}
return new NTCredentials( username, password, workstation, domain );
}
private static String guessDomain()
{
return safeNtlmString( System.getProperty( "http.auth.ntlm.domain" ), System.getenv( "USERDOMAIN" ) );
}
private static String guessWorkstation()
{
String localHost = null;
try
{
localHost = InetAddress.getLocalHost().getHostName();
}
catch ( UnknownHostException e )
{
// well, we have other options to try
}
return safeNtlmString( System.getProperty( "http.auth.ntlm.host" ), System.getenv( "COMPUTERNAME" ),
localHost );
}
private static String safeNtlmString( String... strings )
{
for ( String string : strings )
{
if ( string != null )
{
return string;
}
}
// avoid NPE from httpclient and trigger proper auth failure instead
return "";
}
}
}