View Javadoc
1   package org.eclipse.aether.transport.http;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   * 
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   * 
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.net.InetAddress;
23  import java.net.UnknownHostException;
24  import java.util.HashMap;
25  import java.util.Iterator;
26  import java.util.Map;
27  
28  import org.apache.http.auth.AuthScope;
29  import org.apache.http.auth.Credentials;
30  import org.apache.http.auth.NTCredentials;
31  import org.apache.http.auth.UsernamePasswordCredentials;
32  import org.apache.http.client.CredentialsProvider;
33  import org.apache.http.impl.client.BasicCredentialsProvider;
34  import org.eclipse.aether.repository.AuthenticationContext;
35  
36  /**
37   * Credentials provider that defers calls into the auth context until authentication is actually requested.
38   */
39  final class DeferredCredentialsProvider
40      implements CredentialsProvider
41  {
42  
43      private final CredentialsProvider delegate;
44  
45      private final Map<AuthScope, Factory> factories;
46  
47      public DeferredCredentialsProvider()
48      {
49          delegate = new BasicCredentialsProvider();
50          factories = new HashMap<AuthScope, Factory>();
51      }
52  
53      public void setCredentials( AuthScope authScope, Factory factory )
54      {
55          factories.put( authScope, factory );
56      }
57  
58      public void setCredentials( AuthScope authScope, Credentials credentials )
59      {
60          delegate.setCredentials( authScope, credentials );
61      }
62  
63      public Credentials getCredentials( AuthScope authScope )
64      {
65          synchronized ( factories )
66          {
67              for ( Iterator<Map.Entry<AuthScope, Factory>> it = factories.entrySet().iterator(); it.hasNext(); )
68              {
69                  Map.Entry<AuthScope, Factory> entry = it.next();
70                  if ( authScope.match( entry.getKey() ) >= 0 )
71                  {
72                      it.remove();
73                      delegate.setCredentials( entry.getKey(), entry.getValue().newCredentials() );
74                  }
75              }
76          }
77          return delegate.getCredentials( authScope );
78      }
79  
80      public void clear()
81      {
82          delegate.clear();
83      }
84  
85      interface Factory
86      {
87  
88          Credentials newCredentials();
89  
90      }
91  
92      static class BasicFactory
93          implements Factory
94      {
95  
96          private final AuthenticationContext authContext;
97  
98          public BasicFactory( AuthenticationContext authContext )
99          {
100             this.authContext = authContext;
101         }
102 
103         public Credentials newCredentials()
104         {
105             String username = authContext.get( AuthenticationContext.USERNAME );
106             if ( username == null )
107             {
108                 return null;
109             }
110             String password = authContext.get( AuthenticationContext.PASSWORD );
111             return new UsernamePasswordCredentials( username, password );
112         }
113 
114     }
115 
116     static class NtlmFactory
117         implements Factory
118     {
119 
120         private final AuthenticationContext authContext;
121 
122         public NtlmFactory( AuthenticationContext authContext )
123         {
124             this.authContext = authContext;
125         }
126 
127         public Credentials newCredentials()
128         {
129             String username = authContext.get( AuthenticationContext.USERNAME );
130             if ( username == null )
131             {
132                 return null;
133             }
134             String password = authContext.get( AuthenticationContext.PASSWORD );
135             String domain = authContext.get( AuthenticationContext.NTLM_DOMAIN );
136             String workstation = authContext.get( AuthenticationContext.NTLM_WORKSTATION );
137 
138             if ( domain == null )
139             {
140                 int backslash = username.indexOf( '\\' );
141                 if ( backslash < 0 )
142                 {
143                     domain = guessDomain();
144                 }
145                 else
146                 {
147                     domain = username.substring( 0, backslash );
148                     username = username.substring( backslash + 1 );
149                 }
150             }
151             if ( workstation == null )
152             {
153                 workstation = guessWorkstation();
154             }
155 
156             return new NTCredentials( username, password, workstation, domain );
157         }
158 
159         private static String guessDomain()
160         {
161             return safeNtlmString( System.getProperty( "http.auth.ntlm.domain" ), System.getenv( "USERDOMAIN" ) );
162         }
163 
164         private static String guessWorkstation()
165         {
166             String localHost = null;
167             try
168             {
169                 localHost = InetAddress.getLocalHost().getHostName();
170             }
171             catch ( UnknownHostException e )
172             {
173                 // well, we have other options to try
174             }
175             return safeNtlmString( System.getProperty( "http.auth.ntlm.host" ), System.getenv( "COMPUTERNAME" ),
176                                    localHost );
177         }
178 
179         private static String safeNtlmString( String... strings )
180         {
181             for ( String string : strings )
182             {
183                 if ( string != null )
184                 {
185                     return string;
186                 }
187             }
188             // avoid NPE from httpclient and trigger proper auth failure instead
189             return "";
190         }
191 
192     }
193 
194 }