You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by ol...@apache.org on 2016/05/01 12:56:34 UTC

[32/50] [abbrv] maven-aether git commit: Bug 445283 - HTTP transporter can mistake server authentication for proxy authentication

Bug 445283 - HTTP transporter can mistake server authentication for proxy authentication

Stored server and proxy credentials in separate providers and used new DemuxCredentialsProvider to delegate to one of those providers depending on host in auth request


Project: http://git-wip-us.apache.org/repos/asf/maven-aether/repo
Commit: http://git-wip-us.apache.org/repos/asf/maven-aether/commit/f718cfb9
Tree: http://git-wip-us.apache.org/repos/asf/maven-aether/tree/f718cfb9
Diff: http://git-wip-us.apache.org/repos/asf/maven-aether/diff/f718cfb9

Branch: refs/heads/master
Commit: f718cfb98d31b0188a165d9c5baa367dca59dc20
Parents: dae0615
Author: Benjamin Bentmann <be...@sonatype.com>
Authored: Sun Sep 28 18:43:56 2014 +0200
Committer: Benjamin Bentmann <be...@sonatype.com>
Committed: Sun Sep 28 18:43:56 2014 +0200

----------------------------------------------------------------------
 .../http/DemuxCredentialsProvider.java          | 67 ++++++++++++++++++++
 .../aether/transport/http/HttpTransporter.java  | 26 +++++---
 .../transport/http/HttpTransporterTest.java     | 40 ++++++++++++
 3 files changed, 124 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/maven-aether/blob/f718cfb9/aether-transport-http/src/main/java/org/eclipse/aether/transport/http/DemuxCredentialsProvider.java
----------------------------------------------------------------------
diff --git a/aether-transport-http/src/main/java/org/eclipse/aether/transport/http/DemuxCredentialsProvider.java b/aether-transport-http/src/main/java/org/eclipse/aether/transport/http/DemuxCredentialsProvider.java
new file mode 100644
index 0000000..4b89639
--- /dev/null
+++ b/aether-transport-http/src/main/java/org/eclipse/aether/transport/http/DemuxCredentialsProvider.java
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Sonatype, Inc.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Sonatype, Inc. - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.aether.transport.http;
+
+import org.apache.http.HttpHost;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.Credentials;
+import org.apache.http.client.CredentialsProvider;
+
+/**
+ * Credentials provider that helps to isolate server from proxy credentials. Apache HttpClient uses a single provider
+ * for both server and proxy auth, using the auth scope (host, port, etc.) to select the proper credentials. With regard
+ * to redirects, we use an auth scope for server credentials that's not specific enough to not be mistaken for proxy
+ * auth. This provider helps to maintain the proper isolation.
+ */
+final class DemuxCredentialsProvider
+    implements CredentialsProvider
+{
+
+    private final CredentialsProvider serverCredentialsProvider;
+
+    private final CredentialsProvider proxyCredentialsProvider;
+
+    private final HttpHost proxy;
+
+    public DemuxCredentialsProvider( CredentialsProvider serverCredentialsProvider,
+                                     CredentialsProvider proxyCredentialsProvider, HttpHost proxy )
+    {
+        this.serverCredentialsProvider = serverCredentialsProvider;
+        this.proxyCredentialsProvider = proxyCredentialsProvider;
+        this.proxy = proxy;
+    }
+
+    private CredentialsProvider getDelegate( AuthScope authScope )
+    {
+        if ( proxy.getPort() == authScope.getPort() && proxy.getHostName().equalsIgnoreCase( authScope.getHost() ) )
+        {
+            return proxyCredentialsProvider;
+        }
+        return serverCredentialsProvider;
+    }
+
+    public Credentials getCredentials( AuthScope authScope )
+    {
+        return getDelegate( authScope ).getCredentials( authScope );
+    }
+
+    public void setCredentials( AuthScope authScope, Credentials credentials )
+    {
+        getDelegate( authScope ).setCredentials( authScope, credentials );
+    }
+
+    public void clear()
+    {
+        serverCredentialsProvider.clear();
+        proxyCredentialsProvider.clear();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/maven-aether/blob/f718cfb9/aether-transport-http/src/main/java/org/eclipse/aether/transport/http/HttpTransporter.java
----------------------------------------------------------------------
diff --git a/aether-transport-http/src/main/java/org/eclipse/aether/transport/http/HttpTransporter.java b/aether-transport-http/src/main/java/org/eclipse/aether/transport/http/HttpTransporter.java
index 5ac9b8f..931e04e 100644
--- a/aether-transport-http/src/main/java/org/eclipse/aether/transport/http/HttpTransporter.java
+++ b/aether-transport-http/src/main/java/org/eclipse/aether/transport/http/HttpTransporter.java
@@ -32,6 +32,7 @@ import org.apache.http.HttpResponse;
 import org.apache.http.HttpStatus;
 import org.apache.http.auth.AuthScope;
 import org.apache.http.auth.params.AuthParams;
+import org.apache.http.client.CredentialsProvider;
 import org.apache.http.client.HttpClient;
 import org.apache.http.client.HttpResponseException;
 import org.apache.http.client.methods.HttpGet;
@@ -134,13 +135,7 @@ final class HttpTransporter
 
         configureClient( client.getParams(), session, repository, proxy );
 
-        DeferredCredentialsProvider credsProvider = new DeferredCredentialsProvider();
-        addCredentials( credsProvider, server.getHostName(), AuthScope.ANY_PORT, repoAuthContext );
-        if ( proxy != null )
-        {
-            addCredentials( credsProvider, proxy.getHostName(), proxy.getPort(), proxyAuthContext );
-        }
-        client.setCredentialsProvider( credsProvider );
+        client.setCredentialsProvider( toCredentialsProvider( server, repoAuthContext, proxy, proxyAuthContext ) );
 
         this.client = new DecompressingHttpClient( client );
     }
@@ -182,9 +177,21 @@ final class HttpTransporter
                                                                         ConfigurationProperties.USER_AGENT ) );
     }
 
-    private static void addCredentials( DeferredCredentialsProvider provider, String host, int port,
-                                        AuthenticationContext ctx )
+    private static CredentialsProvider toCredentialsProvider( HttpHost server, AuthenticationContext serverAuthCtx,
+                                                              HttpHost proxy, AuthenticationContext proxyAuthCtx )
+    {
+        CredentialsProvider provider = toCredentialsProvider( server.getHostName(), AuthScope.ANY_PORT, serverAuthCtx );
+        if ( proxy != null )
+        {
+            CredentialsProvider p = toCredentialsProvider( proxy.getHostName(), proxy.getPort(), proxyAuthCtx );
+            provider = new DemuxCredentialsProvider( provider, p, proxy );
+        }
+        return provider;
+    }
+
+    private static CredentialsProvider toCredentialsProvider( String host, int port, AuthenticationContext ctx )
     {
+        DeferredCredentialsProvider provider = new DeferredCredentialsProvider();
         if ( ctx != null )
         {
             AuthScope basicScope = new AuthScope( host, port );
@@ -193,6 +200,7 @@ final class HttpTransporter
             AuthScope ntlmScope = new AuthScope( host, port, AuthScope.ANY_REALM, "ntlm" );
             provider.setCredentials( ntlmScope, new DeferredCredentialsProvider.NtlmFactory( ctx ) );
         }
+        return provider;
     }
 
     LocalState getState()

http://git-wip-us.apache.org/repos/asf/maven-aether/blob/f718cfb9/aether-transport-http/src/test/java/org/eclipse/aether/transport/http/HttpTransporterTest.java
----------------------------------------------------------------------
diff --git a/aether-transport-http/src/test/java/org/eclipse/aether/transport/http/HttpTransporterTest.java b/aether-transport-http/src/test/java/org/eclipse/aether/transport/http/HttpTransporterTest.java
index b4a38d6..4dbc730 100644
--- a/aether-transport-http/src/test/java/org/eclipse/aether/transport/http/HttpTransporterTest.java
+++ b/aether-transport-http/src/test/java/org/eclipse/aether/transport/http/HttpTransporterTest.java
@@ -1141,6 +1141,46 @@ public class HttpTransporterTest
     }
 
     @Test
+    public void testServerAuthScope_NotUsedForProxy()
+        throws Exception
+    {
+        String username = "testuser", password = "testpass";
+        httpServer.setProxyAuthentication( username, password );
+        auth = new AuthenticationBuilder().addUsername( username ).addPassword( password ).build();
+        proxy = new Proxy( Proxy.TYPE_HTTP, httpServer.getHost(), httpServer.getHttpPort() );
+        newTransporter( "http://" + httpServer.getHost() + ":12/" );
+        try
+        {
+            transporter.get( new GetTask( URI.create( "repo/file.txt" ) ) );
+            fail( "Server auth must not be used as proxy auth" );
+        }
+        catch ( HttpResponseException e )
+        {
+            assertEquals( 407, e.getStatusCode() );
+        }
+    }
+
+    @Test
+    public void testProxyAuthScope_NotUsedForServer()
+        throws Exception
+    {
+        String username = "testuser", password = "testpass";
+        httpServer.setAuthentication( username, password );
+        Authentication auth = new AuthenticationBuilder().addUsername( username ).addPassword( password ).build();
+        proxy = new Proxy( Proxy.TYPE_HTTP, httpServer.getHost(), httpServer.getHttpPort(), auth );
+        newTransporter( "http://" + httpServer.getHost() + ":12/" );
+        try
+        {
+            transporter.get( new GetTask( URI.create( "repo/file.txt" ) ) );
+            fail( "Proxy auth must not be used as server auth" );
+        }
+        catch ( HttpResponseException e )
+        {
+            assertEquals( 401, e.getStatusCode() );
+        }
+    }
+
+    @Test
     public void testAuthSchemeReuse()
         throws Exception
     {