View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.internal.aether;
20  
21  import javax.inject.Inject;
22  import javax.inject.Named;
23  
24  import java.io.File;
25  import java.util.ArrayList;
26  import java.util.Arrays;
27  import java.util.Collections;
28  import java.util.HashMap;
29  import java.util.HashSet;
30  import java.util.LinkedHashMap;
31  import java.util.List;
32  import java.util.Map;
33  import java.util.stream.Collectors;
34  
35  import org.apache.maven.RepositoryUtils;
36  import org.apache.maven.api.services.TypeRegistry;
37  import org.apache.maven.api.xml.XmlNode;
38  import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager;
39  import org.apache.maven.artifact.repository.ArtifactRepository;
40  import org.apache.maven.artifact.repository.Authentication;
41  import org.apache.maven.bridge.MavenRepositorySystem;
42  import org.apache.maven.eventspy.internal.EventSpyDispatcher;
43  import org.apache.maven.execution.MavenExecutionRequest;
44  import org.apache.maven.internal.xml.XmlNodeImpl;
45  import org.apache.maven.internal.xml.XmlPlexusConfiguration;
46  import org.apache.maven.model.ModelBase;
47  import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
48  import org.apache.maven.rtinfo.RuntimeInformation;
49  import org.apache.maven.settings.Mirror;
50  import org.apache.maven.settings.Proxy;
51  import org.apache.maven.settings.Server;
52  import org.apache.maven.settings.building.SettingsProblem;
53  import org.apache.maven.settings.crypto.DefaultSettingsDecryptionRequest;
54  import org.apache.maven.settings.crypto.SettingsDecrypter;
55  import org.apache.maven.settings.crypto.SettingsDecryptionResult;
56  import org.codehaus.plexus.configuration.PlexusConfiguration;
57  import org.eclipse.aether.ConfigurationProperties;
58  import org.eclipse.aether.RepositoryListener;
59  import org.eclipse.aether.RepositorySystem;
60  import org.eclipse.aether.RepositorySystemSession;
61  import org.eclipse.aether.RepositorySystemSession.SessionBuilder;
62  import org.eclipse.aether.repository.AuthenticationContext;
63  import org.eclipse.aether.repository.AuthenticationSelector;
64  import org.eclipse.aether.repository.ProxySelector;
65  import org.eclipse.aether.repository.RemoteRepository;
66  import org.eclipse.aether.repository.RepositoryPolicy;
67  import org.eclipse.aether.repository.WorkspaceReader;
68  import org.eclipse.aether.resolution.ResolutionErrorPolicy;
69  import org.eclipse.aether.util.listener.ChainedRepositoryListener;
70  import org.eclipse.aether.util.repository.AuthenticationBuilder;
71  import org.eclipse.aether.util.repository.ChainedLocalRepositoryManager;
72  import org.eclipse.aether.util.repository.DefaultAuthenticationSelector;
73  import org.eclipse.aether.util.repository.DefaultMirrorSelector;
74  import org.eclipse.aether.util.repository.DefaultProxySelector;
75  import org.eclipse.aether.util.repository.SimpleArtifactDescriptorPolicy;
76  import org.eclipse.aether.util.repository.SimpleResolutionErrorPolicy;
77  import org.eclipse.sisu.Nullable;
78  import org.slf4j.Logger;
79  import org.slf4j.LoggerFactory;
80  
81  /**
82   * @since 3.3.0
83   */
84  @Named
85  public class DefaultRepositorySystemSessionFactory {
86      /**
87       * User property for chained LRM: list of "tail" local repository paths (separated by comma), to be used with
88       * {@link ChainedLocalRepositoryManager}.
89       * Default value: {@code null}, no chained LRM is used.
90       *
91       * @since 3.9.0
92       */
93      private static final String MAVEN_REPO_LOCAL_TAIL = "maven.repo.local.tail";
94  
95      /**
96       * User property for reverse dependency tree. If enabled, Maven will record ".tracking" directory into local
97       * repository with "reverse dependency tree", essentially explaining WHY given artifact is present in local
98       * repository.
99       * Default: {@code false}, will not record anything.
100      *
101      * @since 3.9.0
102      */
103     private static final String MAVEN_REPO_LOCAL_RECORD_REVERSE_TREE = "maven.repo.local.recordReverseTree";
104 
105     private static final String MAVEN_RESOLVER_TRANSPORT_KEY = "maven.resolver.transport";
106 
107     private static final String MAVEN_RESOLVER_TRANSPORT_DEFAULT = "default";
108 
109     private static final String MAVEN_RESOLVER_TRANSPORT_WAGON = "wagon";
110 
111     private static final String MAVEN_RESOLVER_TRANSPORT_APACHE = "apache";
112 
113     private static final String MAVEN_RESOLVER_TRANSPORT_JDK = "jdk";
114 
115     /**
116      * This name for Apache HttpClient transport is deprecated.
117      *
118      * @deprecated Renamed to {@link #MAVEN_RESOLVER_TRANSPORT_APACHE}
119      */
120     @Deprecated
121     private static final String MAVEN_RESOLVER_TRANSPORT_NATIVE = "native";
122 
123     private static final String MAVEN_RESOLVER_TRANSPORT_AUTO = "auto";
124 
125     private static final String WAGON_TRANSPORTER_PRIORITY_KEY = "aether.priority.WagonTransporterFactory";
126 
127     private static final String APACHE_HTTP_TRANSPORTER_PRIORITY_KEY = "aether.priority.ApacheTransporterFactory";
128 
129     private static final String JDK_HTTP_TRANSPORTER_PRIORITY_KEY = "aether.priority.JdkTransporterFactory";
130 
131     private static final String FILE_TRANSPORTER_PRIORITY_KEY = "aether.priority.FileTransporterFactory";
132 
133     private static final String RESOLVER_MAX_PRIORITY = String.valueOf(Float.MAX_VALUE);
134 
135     private final Logger logger = LoggerFactory.getLogger(getClass());
136 
137     private final ArtifactHandlerManager artifactHandlerManager;
138 
139     private final RepositorySystem repoSystem;
140 
141     private final WorkspaceReader workspaceRepository;
142 
143     private final SettingsDecrypter settingsDecrypter;
144 
145     private final EventSpyDispatcher eventSpyDispatcher;
146 
147     private final RuntimeInformation runtimeInformation;
148 
149     private final TypeRegistry typeRegistry;
150 
151     @SuppressWarnings("checkstyle:ParameterNumber")
152     @Inject
153     public DefaultRepositorySystemSessionFactory(
154             ArtifactHandlerManager artifactHandlerManager,
155             RepositorySystem repoSystem,
156             @Nullable @Named("ide") WorkspaceReader workspaceRepository,
157             SettingsDecrypter settingsDecrypter,
158             EventSpyDispatcher eventSpyDispatcher,
159             RuntimeInformation runtimeInformation,
160             TypeRegistry typeRegistry) {
161         this.artifactHandlerManager = artifactHandlerManager;
162         this.repoSystem = repoSystem;
163         this.workspaceRepository = workspaceRepository;
164         this.settingsDecrypter = settingsDecrypter;
165         this.eventSpyDispatcher = eventSpyDispatcher;
166         this.runtimeInformation = runtimeInformation;
167         this.typeRegistry = typeRegistry;
168     }
169 
170     @Deprecated
171     public RepositorySystemSession newRepositorySession(MavenExecutionRequest request) {
172         return newRepositorySessionBuilder(request).build();
173     }
174 
175     @SuppressWarnings("checkstyle:methodLength")
176     public SessionBuilder newRepositorySessionBuilder(MavenExecutionRequest request) {
177         SessionBuilder session = MavenRepositorySystemUtils.newSession(
178                 repoSystem.createSessionBuilder(), new TypeRegistryAdapter(typeRegistry));
179         session.setCache(request.getRepositoryCache());
180 
181         Map<Object, Object> configProps = new LinkedHashMap<>();
182         configProps.put(ConfigurationProperties.USER_AGENT, getUserAgent());
183         configProps.put(ConfigurationProperties.INTERACTIVE, request.isInteractiveMode());
184         configProps.put("maven.startTime", request.getStartTime());
185         // First add properties populated from settings.xml
186         configProps.putAll(getPropertiesFromRequestedProfiles(request));
187         // Resolver's ConfigUtils solely rely on config properties, that is why we need to add both here as well.
188         configProps.putAll(request.getSystemProperties());
189         configProps.putAll(request.getUserProperties());
190 
191         session.setOffline(request.isOffline());
192         session.setChecksumPolicy(request.getGlobalChecksumPolicy());
193         session.setUpdatePolicy(
194                 request.isNoSnapshotUpdates()
195                         ? RepositoryPolicy.UPDATE_POLICY_NEVER
196                         : request.isUpdateSnapshots() ? RepositoryPolicy.UPDATE_POLICY_ALWAYS : null);
197 
198         int errorPolicy = 0;
199         errorPolicy |= request.isCacheNotFound()
200                 ? ResolutionErrorPolicy.CACHE_NOT_FOUND
201                 : ResolutionErrorPolicy.CACHE_DISABLED;
202         errorPolicy |= request.isCacheTransferError()
203                 ? ResolutionErrorPolicy.CACHE_TRANSFER_ERROR
204                 : ResolutionErrorPolicy.CACHE_DISABLED;
205         session.setResolutionErrorPolicy(
206                 new SimpleResolutionErrorPolicy(errorPolicy, errorPolicy | ResolutionErrorPolicy.CACHE_NOT_FOUND));
207 
208         session.setArtifactDescriptorPolicy(new SimpleArtifactDescriptorPolicy(
209                 request.isIgnoreMissingArtifactDescriptor(), request.isIgnoreInvalidArtifactDescriptor()));
210 
211         session.setArtifactTypeRegistry(RepositoryUtils.newArtifactTypeRegistry(artifactHandlerManager));
212 
213         session.setWorkspaceReader(
214                 request.getWorkspaceReader() != null ? request.getWorkspaceReader() : workspaceRepository);
215 
216         DefaultSettingsDecryptionRequest decrypt = new DefaultSettingsDecryptionRequest();
217         decrypt.setProxies(request.getProxies());
218         decrypt.setServers(request.getServers());
219         SettingsDecryptionResult decrypted = settingsDecrypter.decrypt(decrypt);
220 
221         if (logger.isDebugEnabled()) {
222             for (SettingsProblem problem : decrypted.getProblems()) {
223                 logger.debug(problem.getMessage(), problem.getException());
224             }
225         }
226 
227         DefaultMirrorSelector mirrorSelector = new DefaultMirrorSelector();
228         for (Mirror mirror : request.getMirrors()) {
229             mirrorSelector.add(
230                     mirror.getId(),
231                     mirror.getUrl(),
232                     mirror.getLayout(),
233                     false,
234                     mirror.isBlocked(),
235                     mirror.getMirrorOf(),
236                     mirror.getMirrorOfLayouts());
237         }
238         session.setMirrorSelector(mirrorSelector);
239 
240         DefaultProxySelector proxySelector = new DefaultProxySelector();
241         for (Proxy proxy : decrypted.getProxies()) {
242             AuthenticationBuilder authBuilder = new AuthenticationBuilder();
243             authBuilder.addUsername(proxy.getUsername()).addPassword(proxy.getPassword());
244             proxySelector.add(
245                     new org.eclipse.aether.repository.Proxy(
246                             proxy.getProtocol(), proxy.getHost(), proxy.getPort(), authBuilder.build()),
247                     proxy.getNonProxyHosts());
248         }
249         session.setProxySelector(proxySelector);
250 
251         // Note: we do NOT use WagonTransportConfigurationKeys here as Maven Core does NOT depend on Wagon Transport
252         // and this is okay and "good thing".
253         DefaultAuthenticationSelector authSelector = new DefaultAuthenticationSelector();
254         for (Server server : decrypted.getServers()) {
255             AuthenticationBuilder authBuilder = new AuthenticationBuilder();
256             authBuilder.addUsername(server.getUsername()).addPassword(server.getPassword());
257             authBuilder.addPrivateKey(server.getPrivateKey(), server.getPassphrase());
258             authSelector.add(server.getId(), authBuilder.build());
259 
260             if (server.getConfiguration() != null) {
261                 XmlNode dom = server.getDelegate().getConfiguration();
262                 List<XmlNode> children = dom.getChildren().stream()
263                         .filter(c -> !"wagonProvider".equals(c.getName()))
264                         .collect(Collectors.toList());
265                 dom = new XmlNodeImpl(dom.getName(), null, null, children, null);
266                 PlexusConfiguration config = XmlPlexusConfiguration.toPlexusConfiguration(dom);
267                 configProps.put("aether.transport.wagon.config." + server.getId(), config);
268 
269                 // Translate to proper resolver configuration properties as well (as Plexus XML above is Wagon specific
270                 // only) but support only configuration/httpConfiguration/all, see
271                 // https://maven.apache.org/guides/mini/guide-http-settings.html
272                 Map<String, String> headers = null;
273                 Integer connectTimeout = null;
274                 Integer requestTimeout = null;
275 
276                 PlexusConfiguration httpHeaders = config.getChild("httpHeaders", false);
277                 if (httpHeaders != null) {
278                     PlexusConfiguration[] properties = httpHeaders.getChildren("property");
279                     if (properties != null && properties.length > 0) {
280                         headers = new HashMap<>();
281                         for (PlexusConfiguration property : properties) {
282                             headers.put(
283                                     property.getChild("name").getValue(),
284                                     property.getChild("value").getValue());
285                         }
286                     }
287                 }
288 
289                 PlexusConfiguration connectTimeoutXml = config.getChild("connectTimeout", false);
290                 if (connectTimeoutXml != null) {
291                     connectTimeout = Integer.parseInt(connectTimeoutXml.getValue());
292                 } else {
293                     // fallback configuration name
294                     PlexusConfiguration httpConfiguration = config.getChild("httpConfiguration", false);
295                     if (httpConfiguration != null) {
296                         PlexusConfiguration httpConfigurationAll = httpConfiguration.getChild("all", false);
297                         if (httpConfigurationAll != null) {
298                             connectTimeoutXml = httpConfigurationAll.getChild("connectionTimeout", false);
299                             if (connectTimeoutXml != null) {
300                                 connectTimeout = Integer.parseInt(connectTimeoutXml.getValue());
301                                 logger.warn("Settings for server {} uses legacy format", server.getId());
302                             }
303                         }
304                     }
305                 }
306 
307                 PlexusConfiguration requestTimeoutXml = config.getChild("requestTimeout", false);
308                 if (requestTimeoutXml != null) {
309                     requestTimeout = Integer.parseInt(requestTimeoutXml.getValue());
310                 } else {
311                     // fallback configuration name
312                     PlexusConfiguration httpConfiguration = config.getChild("httpConfiguration", false);
313                     if (httpConfiguration != null) {
314                         PlexusConfiguration httpConfigurationAll = httpConfiguration.getChild("all", false);
315                         if (httpConfigurationAll != null) {
316                             requestTimeoutXml = httpConfigurationAll.getChild("readTimeout", false);
317                             if (requestTimeoutXml != null) {
318                                 requestTimeout = Integer.parseInt(requestTimeoutXml.getValue());
319                                 logger.warn("Settings for server {} uses legacy format", server.getId());
320                             }
321                         }
322                     }
323                 }
324 
325                 // org.eclipse.aether.ConfigurationProperties.HTTP_HEADERS => Map<String, String>
326                 if (headers != null) {
327                     configProps.put(ConfigurationProperties.HTTP_HEADERS + "." + server.getId(), headers);
328                 }
329                 // org.eclipse.aether.ConfigurationProperties.CONNECT_TIMEOUT => int
330                 if (connectTimeout != null) {
331                     configProps.put(ConfigurationProperties.CONNECT_TIMEOUT + "." + server.getId(), connectTimeout);
332                 }
333                 // org.eclipse.aether.ConfigurationProperties.REQUEST_TIMEOUT => int
334                 if (requestTimeout != null) {
335                     configProps.put(ConfigurationProperties.REQUEST_TIMEOUT + "." + server.getId(), requestTimeout);
336                 }
337             }
338 
339             configProps.put("aether.transport.wagon.perms.fileMode." + server.getId(), server.getFilePermissions());
340             configProps.put("aether.transport.wagon.perms.dirMode." + server.getId(), server.getDirectoryPermissions());
341         }
342         session.setAuthenticationSelector(authSelector);
343 
344         Object transport = configProps.getOrDefault(MAVEN_RESOLVER_TRANSPORT_KEY, MAVEN_RESOLVER_TRANSPORT_DEFAULT);
345         if (MAVEN_RESOLVER_TRANSPORT_DEFAULT.equals(transport)) {
346             // The "default" mode (user did not set anything) from now on defaults to AUTO
347         } else if (MAVEN_RESOLVER_TRANSPORT_JDK.equals(transport)) {
348             // Make sure (whatever extra priority is set) that resolver file/jdk is selected
349             configProps.put(FILE_TRANSPORTER_PRIORITY_KEY, RESOLVER_MAX_PRIORITY);
350             configProps.put(JDK_HTTP_TRANSPORTER_PRIORITY_KEY, RESOLVER_MAX_PRIORITY);
351         } else if (MAVEN_RESOLVER_TRANSPORT_APACHE.equals(transport)
352                 || MAVEN_RESOLVER_TRANSPORT_NATIVE.equals(transport)) {
353             if (MAVEN_RESOLVER_TRANSPORT_NATIVE.equals(transport)) {
354                 logger.warn(
355                         "Transport name '{}' is DEPRECATED/RENAMED, use '{}' instead",
356                         MAVEN_RESOLVER_TRANSPORT_NATIVE,
357                         MAVEN_RESOLVER_TRANSPORT_APACHE);
358             }
359             // Make sure (whatever extra priority is set) that resolver file/apache is selected
360             configProps.put(FILE_TRANSPORTER_PRIORITY_KEY, RESOLVER_MAX_PRIORITY);
361             configProps.put(APACHE_HTTP_TRANSPORTER_PRIORITY_KEY, RESOLVER_MAX_PRIORITY);
362         } else if (MAVEN_RESOLVER_TRANSPORT_WAGON.equals(transport)) {
363             // Make sure (whatever extra priority is set) that wagon is selected
364             configProps.put(WAGON_TRANSPORTER_PRIORITY_KEY, RESOLVER_MAX_PRIORITY);
365         } else if (!MAVEN_RESOLVER_TRANSPORT_AUTO.equals(transport)) {
366             throw new IllegalArgumentException("Unknown resolver transport '" + transport
367                     + "'. Supported transports are: " + MAVEN_RESOLVER_TRANSPORT_WAGON + ", "
368                     + MAVEN_RESOLVER_TRANSPORT_APACHE + ", " + MAVEN_RESOLVER_TRANSPORT_JDK + ", "
369                     + MAVEN_RESOLVER_TRANSPORT_AUTO);
370         }
371 
372         session.setUserProperties(request.getUserProperties());
373         session.setSystemProperties(request.getSystemProperties());
374         session.setConfigProperties(configProps);
375 
376         session.setTransferListener(request.getTransferListener());
377 
378         RepositoryListener repositoryListener = eventSpyDispatcher.chainListener(new LoggingRepositoryListener(logger));
379 
380         boolean recordReverseTree = configProps.containsKey(MAVEN_REPO_LOCAL_RECORD_REVERSE_TREE)
381                 && Boolean.parseBoolean((String) configProps.get(MAVEN_REPO_LOCAL_RECORD_REVERSE_TREE));
382         if (recordReverseTree) {
383             repositoryListener = new ChainedRepositoryListener(repositoryListener, new ReverseTreeRepositoryListener());
384         }
385         session.setRepositoryListener(repositoryListener);
386 
387         injectMirror(request.getRemoteRepositories(), request.getMirrors());
388         injectProxy(proxySelector, request.getRemoteRepositories());
389         injectAuthentication(authSelector, request.getRemoteRepositories());
390 
391         injectMirror(request.getPluginArtifactRepositories(), request.getMirrors());
392         injectProxy(proxySelector, request.getPluginArtifactRepositories());
393         injectAuthentication(authSelector, request.getPluginArtifactRepositories());
394 
395         ArrayList<File> paths = new ArrayList<>();
396         paths.add(new File(request.getLocalRepository().getBasedir()));
397         String localRepoTail = (String) configProps.get(MAVEN_REPO_LOCAL_TAIL);
398         if (localRepoTail != null) {
399             Arrays.stream(localRepoTail.split(","))
400                     .filter(p -> p != null && !p.trim().isEmpty())
401                     .map(File::new)
402                     .forEach(paths::add);
403         }
404         session.withLocalRepositoryBaseDirectories(paths);
405 
406         return session;
407     }
408 
409     private Map<?, ?> getPropertiesFromRequestedProfiles(MavenExecutionRequest request) {
410         HashSet<String> activeProfileId =
411                 new HashSet<>(request.getProfileActivation().getRequiredActiveProfileIds());
412         activeProfileId.addAll(request.getProfileActivation().getOptionalActiveProfileIds());
413 
414         return request.getProfiles().stream()
415                 .filter(profile -> activeProfileId.contains(profile.getId()))
416                 .map(ModelBase::getProperties)
417                 .flatMap(properties -> properties.entrySet().stream())
418                 .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (k1, k2) -> k2));
419     }
420 
421     private String getUserAgent() {
422         String version = runtimeInformation.getMavenVersion();
423         version = version.isEmpty() ? version : "/" + version;
424         return "Apache-Maven" + version + " (Java " + System.getProperty("java.version") + "; "
425                 + System.getProperty("os.name") + " " + System.getProperty("os.version") + ")";
426     }
427 
428     private void injectMirror(List<ArtifactRepository> repositories, List<Mirror> mirrors) {
429         if (repositories != null && mirrors != null) {
430             for (ArtifactRepository repository : repositories) {
431                 Mirror mirror = MavenRepositorySystem.getMirror(repository, mirrors);
432                 injectMirror(repository, mirror);
433             }
434         }
435     }
436 
437     private void injectMirror(ArtifactRepository repository, Mirror mirror) {
438         if (mirror != null) {
439             ArtifactRepository original = MavenRepositorySystem.createArtifactRepository(
440                     repository.getId(),
441                     repository.getUrl(),
442                     repository.getLayout(),
443                     repository.getSnapshots(),
444                     repository.getReleases());
445 
446             repository.setMirroredRepositories(Collections.singletonList(original));
447 
448             repository.setId(mirror.getId());
449             repository.setUrl(mirror.getUrl());
450 
451             if (mirror.getLayout() != null && !mirror.getLayout().isEmpty()) {
452                 repository.setLayout(original.getLayout());
453             }
454 
455             repository.setBlocked(mirror.isBlocked());
456         }
457     }
458 
459     private void injectProxy(ProxySelector selector, List<ArtifactRepository> repositories) {
460         if (repositories != null && selector != null) {
461             for (ArtifactRepository repository : repositories) {
462                 repository.setProxy(getProxy(selector, repository));
463             }
464         }
465     }
466 
467     private org.apache.maven.repository.Proxy getProxy(ProxySelector selector, ArtifactRepository repository) {
468         if (selector != null) {
469             RemoteRepository repo = RepositoryUtils.toRepo(repository);
470             org.eclipse.aether.repository.Proxy proxy = selector.getProxy(repo);
471             if (proxy != null) {
472                 org.apache.maven.repository.Proxy p = new org.apache.maven.repository.Proxy();
473                 p.setHost(proxy.getHost());
474                 p.setProtocol(proxy.getType());
475                 p.setPort(proxy.getPort());
476                 if (proxy.getAuthentication() != null) {
477                     repo = new RemoteRepository.Builder(repo).setProxy(proxy).build();
478                     AuthenticationContext authCtx = AuthenticationContext.forProxy(null, repo);
479                     p.setUserName(authCtx.get(AuthenticationContext.USERNAME));
480                     p.setPassword(authCtx.get(AuthenticationContext.PASSWORD));
481                     p.setNtlmDomain(authCtx.get(AuthenticationContext.NTLM_DOMAIN));
482                     p.setNtlmHost(authCtx.get(AuthenticationContext.NTLM_WORKSTATION));
483                     authCtx.close();
484                 }
485                 return p;
486             }
487         }
488         return null;
489     }
490 
491     public void injectAuthentication(AuthenticationSelector selector, List<ArtifactRepository> repositories) {
492         if (repositories != null && selector != null) {
493             for (ArtifactRepository repository : repositories) {
494                 repository.setAuthentication(getAuthentication(selector, repository));
495             }
496         }
497     }
498 
499     private Authentication getAuthentication(AuthenticationSelector selector, ArtifactRepository repository) {
500         if (selector != null) {
501             RemoteRepository repo = RepositoryUtils.toRepo(repository);
502             org.eclipse.aether.repository.Authentication auth = selector.getAuthentication(repo);
503             if (auth != null) {
504                 repo = new RemoteRepository.Builder(repo)
505                         .setAuthentication(auth)
506                         .build();
507                 AuthenticationContext authCtx = AuthenticationContext.forRepository(null, repo);
508                 Authentication result = new Authentication(
509                         authCtx.get(AuthenticationContext.USERNAME), authCtx.get(AuthenticationContext.PASSWORD));
510                 result.setPrivateKey(authCtx.get(AuthenticationContext.PRIVATE_KEY_PATH));
511                 result.setPassphrase(authCtx.get(AuthenticationContext.PRIVATE_KEY_PASSPHRASE));
512                 authCtx.close();
513                 return result;
514             }
515         }
516         return null;
517     }
518 }