Index: continuum-api/src/main/java/org/apache/maven/continuum/project/builder/ContinuumProjectBuilder.java =================================================================== --- continuum-api/src/main/java/org/apache/maven/continuum/project/builder/ContinuumProjectBuilder.java (revision 239452) +++ continuum-api/src/main/java/org/apache/maven/continuum/project/builder/ContinuumProjectBuilder.java (working copy) @@ -26,6 +26,6 @@ { String ROLE = ContinuumProjectBuilder.class.getName(); - ContinuumProjectBuildingResult buildProjectsFromMetadata( URL url ) + ContinuumProjectBuildingResult buildProjectsFromMetadata( URL url, String username, String password ) throws ContinuumProjectBuilderException; } Index: continuum-api/src/main/java/org/apache/maven/continuum/project/builder/AbstractContinuumProjectBuilder.java =================================================================== --- continuum-api/src/main/java/org/apache/maven/continuum/project/builder/AbstractContinuumProjectBuilder.java (revision 239452) +++ continuum-api/src/main/java/org/apache/maven/continuum/project/builder/AbstractContinuumProjectBuilder.java (working copy) @@ -20,8 +20,14 @@ import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; +import java.net.HttpURLConnection; import java.net.URL; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; + import org.codehaus.plexus.logging.AbstractLogEnabled; import org.codehaus.plexus.util.IOUtil; @@ -33,12 +39,18 @@ extends AbstractLogEnabled implements ContinuumProjectBuilder { - protected File createMetadataFile( URL metadata ) + protected File createMetadataFile( URL metadata, String username, String password ) throws IOException { getLogger().info( "Downloading " + metadata.toExternalForm() ); - InputStream is = metadata.openStream(); + InputStream is = null; + + if (metadata.getProtocol().equals("https")) { + is = getSecureHttpStream( metadata, username, password ); + } else { + is = metadata.openStream(); + } File file = File.createTempFile( "continuum-", ".tmp" ); @@ -54,4 +66,59 @@ return file; } + + /* this bit attempts to ignore certificates that might need to be accepted and also tries to + * conform to the format https://:@host + * + * adapted from code snippets from http://javaalmanac.com/egs/javax.net.ssl/TrustAll.html * + */ + public InputStream getSecureHttpStream( URL url, String username, String password ) throws IOException { + + InputStream is = null; + + try { + + // Create a trust manager that does not validate certificate + // chains + TrustManager[] trustAllCerts = new TrustManager[] { + new X509TrustManager() { + public java.security.cert.X509Certificate[] getAcceptedIssuers() { + return null; + } + public void checkClientTrusted( + java.security.cert.X509Certificate[] certs, String authType) { + } + public void checkServerTrusted( + java.security.cert.X509Certificate[] certs, String authType) { + } + } + }; + + // Install the all-trusting trust manager + + SSLContext sslContext = SSLContext.getInstance("SSL"); + sslContext.init(null, trustAllCerts, new java.security.SecureRandom()); + HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory()); + + String authString = username + ":" + password; + System.out.println("u: " + username + " p: " + password); + HttpURLConnection urlc = (HttpURLConnection) url.openConnection(); + + urlc.setDoInput( true ); + urlc.setUseCaches( false ); + + urlc.setRequestProperty( "Content-Type", "application/octet-stream" ); + + if (username != null && password != null) { + urlc.setRequestProperty( "Authorization", "Basic " + new sun.misc.BASE64Encoder().encode( authString.getBytes() ) ); + } + + is = urlc.getInputStream(); + + } catch (Exception e) { + throw new IOException("can't establish secure input stream"); + } + return is; + } + } Index: continuum-web/src/main/resources/forms/addMavenTwoProject.xml =================================================================== --- continuum-web/src/main/resources/forms/addMavenTwoProject.xml (revision 239452) +++ continuum-web/src/main/resources/forms/addMavenTwoProject.xml (working copy) @@ -9,10 +9,10 @@ required empty.error - + url-source urlSource.error Index: continuum-plexus-application/build.sh =================================================================== --- continuum-plexus-application/build.sh (revision 239452) +++ continuum-plexus-application/build.sh (working copy) @@ -1 +1 @@ -m2 -Denv=test clean:clean install +m2 -Denv=test -o clean:clean install Index: continuum-core/src/test/java/org/apache/maven/continuum/project/builder/maven/MavenTwoContinuumProjectBuilderTest.java =================================================================== --- continuum-core/src/test/java/org/apache/maven/continuum/project/builder/maven/MavenTwoContinuumProjectBuilderTest.java (revision 239452) +++ continuum-core/src/test/java/org/apache/maven/continuum/project/builder/maven/MavenTwoContinuumProjectBuilderTest.java (working copy) @@ -46,7 +46,7 @@ File pom = getTestFile( "src/test/repository/maven-builder-helper-1.xml" ); - ContinuumProjectBuildingResult result = projectBuilder.buildProjectsFromMetadata( pom.toURL() ); + ContinuumProjectBuildingResult result = projectBuilder.buildProjectsFromMetadata( pom.toURL(), null, null); assertNotNull( result.getWarnings() ); @@ -77,7 +77,7 @@ File pom = getTestFile( "src/test/repository/maven-builder-helper-2.xml" ); - ContinuumProjectBuildingResult result = projectBuilder.buildProjectsFromMetadata( pom.toURL() ); + ContinuumProjectBuildingResult result = projectBuilder.buildProjectsFromMetadata( pom.toURL(), null, null ); assertNotNull( result.getWarnings() ); @@ -113,7 +113,7 @@ System.setOut( new PrintStream( new ByteArrayOutputStream() ) ); - ContinuumProjectBuildingResult result = projectBuilder.buildProjectsFromMetadata( new URL( url ) ); + ContinuumProjectBuildingResult result = projectBuilder.buildProjectsFromMetadata( new URL( url ), null, null ); System.setOut( ps ); Index: continuum-core/src/test/java/org/apache/maven/continuum/project/builder/maven/MavenOneContinuumProjectBuilderTest.java =================================================================== --- continuum-core/src/test/java/org/apache/maven/continuum/project/builder/maven/MavenOneContinuumProjectBuilderTest.java (revision 239452) +++ continuum-core/src/test/java/org/apache/maven/continuum/project/builder/maven/MavenOneContinuumProjectBuilderTest.java (working copy) @@ -38,7 +38,7 @@ MavenOneContinuumProjectBuilder.ID ); ContinuumProjectBuildingResult result = projectBuilder.buildProjectsFromMetadata( - getTestFile( "src/test/resources/projects/maven-1.pom.xml" ).toURL() ); + getTestFile( "src/test/resources/projects/maven-1.pom.xml" ).toURL(), null, null ); assertNotNull( result.getWarnings() ); Index: continuum-core/src/main/java/org/apache/maven/continuum/core/action/CreateProjectsFromMetadata.java =================================================================== --- continuum-core/src/main/java/org/apache/maven/continuum/core/action/CreateProjectsFromMetadata.java (revision 239452) +++ continuum-core/src/main/java/org/apache/maven/continuum/core/action/CreateProjectsFromMetadata.java (working copy) @@ -10,10 +10,17 @@ import org.apache.maven.continuum.project.builder.manager.ContinuumProjectBuilderManager; import org.apache.maven.continuum.project.builder.manager.ContinuumProjectBuilderManagerException; +import java.io.InputStream; +import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.util.Map; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; + /** * @author Trygve Laugstøl * @version $Id$ @@ -38,19 +45,121 @@ URL url; + ContinuumProjectBuilder projectBuilder = projectBuilderManager.getProjectBuilder( projectBuilderId ); + ContinuumProjectBuildingResult result = null; + try { - url = new URL( u ); + if (!u.startsWith("https")) { + url = new URL( u ); + result = projectBuilder.buildProjectsFromMetadata( url, null, null ); + } else { + if (validateSecureURL(u)) { + url = new URL(scrapeUrl(u)); + result = projectBuilder.buildProjectsFromMetadata( url, scrapeUsername(u), scrapePassword(u) ); + } else { + throw new ContinuumException( "'" + u + "' is not a valid secureURL."); + } + } + } catch ( MalformedURLException e ) { throw new ContinuumException( "'" + u + "' is not a valid URL.", e ); } - ContinuumProjectBuilder projectBuilder = projectBuilderManager.getProjectBuilder( projectBuilderId ); + - ContinuumProjectBuildingResult result = projectBuilder.buildProjectsFromMetadata( url ); + context.put( KEY_PROJECT_BUILDING_RESULT, result ); } + + /* this bit attempts to ignore certificates that might need to be accepted and also tries to + * conform to the format https://:@host + * + * adapted from code snippets from http://javaalmanac.com/egs/javax.net.ssl/TrustAll.html * + */ + public boolean validateSecureURL( String urlString ) { + + try { + + // Create a trust manager that does not validate certificate + // chains + TrustManager[] trustAllCerts = new TrustManager[] { + new X509TrustManager() { + public java.security.cert.X509Certificate[] getAcceptedIssuers() { + return null; + } + public void checkClientTrusted( + java.security.cert.X509Certificate[] certs, String authType) { + } + public void checkServerTrusted( + java.security.cert.X509Certificate[] certs, String authType) { + } + } + }; + + // Install the all-trusting trust manager + + SSLContext sslContext = SSLContext.getInstance("SSL"); + sslContext.init(null, trustAllCerts, new java.security.SecureRandom()); + HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory()); + + String username = scrapeUsername( urlString ); + String password = scrapePassword( urlString ); + String authString = username + ":" + password; + String cleanUrl = scrapeUrl( urlString ); + System.out.println("u: " + username + " p: " + password + " u: " + cleanUrl); + + URL url = new URL( cleanUrl ); + + HttpURLConnection urlc = (HttpURLConnection) url.openConnection(); + + urlc.setDoInput( true ); + urlc.setUseCaches( false ); + + urlc.setRequestProperty( "Content-Type", "application/octet-stream" ); + + if (username != null && password != null) { + urlc.setRequestProperty( "Authorization", "Basic " + new sun.misc.BASE64Encoder().encode( authString.getBytes() ) ); + } + + InputStream is = urlc.getInputStream(); + is.close(); + + } catch (Exception e) { + return false; + } + return true; + } + + /* + * return the username from https://:@ + */ + private String scrapeUsername (String url) { + String t = url.substring(8, url.length()); + return t.substring(0, t.indexOf(":")); + } + + /* + * return to password from https://:@ + */ + private String scrapePassword (String url) { + String t = url.substring(8, url.length()); + return t.substring(t.indexOf(":") + 1, t.indexOf("@")); + } + + /* + * return the url from https://:@ + */ + private String scrapeUrl (String url) { + if (url.indexOf("@") != -1) { + return "https://" + url.substring(url.indexOf("@") + 1, url.length()); + } else { + return url; + } + } + + } Index: continuum-core/src/main/java/org/apache/maven/continuum/project/builder/maven/MavenTwoContinuumProjectBuilder.java =================================================================== --- continuum-core/src/main/java/org/apache/maven/continuum/project/builder/maven/MavenTwoContinuumProjectBuilder.java (revision 239452) +++ continuum-core/src/main/java/org/apache/maven/continuum/project/builder/maven/MavenTwoContinuumProjectBuilder.java (working copy) @@ -62,7 +62,7 @@ // AbstractContinuumProjectBuilder Implementation // ---------------------------------------------------------------------- - public ContinuumProjectBuildingResult buildProjectsFromMetadata( URL url ) + public ContinuumProjectBuildingResult buildProjectsFromMetadata( URL url, String username, String password ) throws ContinuumProjectBuilderException { // ---------------------------------------------------------------------- @@ -71,7 +71,7 @@ ContinuumProjectBuildingResult result = new ContinuumProjectBuildingResult(); - readModules( url, result, true ); + readModules( url, result, true, username, password ); return result; } @@ -80,7 +80,7 @@ // // ---------------------------------------------------------------------- - private void readModules( URL url, ContinuumProjectBuildingResult result, boolean groupPom ) + private void readModules( URL url, ContinuumProjectBuildingResult result, boolean groupPom, String username, String password ) { MavenProject mavenProject; @@ -88,7 +88,7 @@ { // TODO: this isn't finding parents due to relocating to the URL // TODO: the whole modules resolution is funky - mavenProject = builderHelper.getMavenProject( createMetadataFile( url ) ); + mavenProject = builderHelper.getMavenProject( createMetadataFile( url, username, password ) ); } catch ( MavenBuilderHelperException e ) { @@ -173,7 +173,7 @@ continue; } - readModules( moduleUrl, result, false ); + readModules( moduleUrl, result, false, username, password ); } } Index: continuum-core/src/main/java/org/apache/maven/continuum/project/builder/maven/MavenOneContinuumProjectBuilder.java =================================================================== --- continuum-core/src/main/java/org/apache/maven/continuum/project/builder/maven/MavenOneContinuumProjectBuilder.java (revision 239452) +++ continuum-core/src/main/java/org/apache/maven/continuum/project/builder/maven/MavenOneContinuumProjectBuilder.java (working copy) @@ -48,7 +48,7 @@ // ProjectCreator Implementation // ---------------------------------------------------------------------- - public ContinuumProjectBuildingResult buildProjectsFromMetadata( URL url ) + public ContinuumProjectBuildingResult buildProjectsFromMetadata( URL url, String username, String password ) { ContinuumProjectBuildingResult result = new ContinuumProjectBuildingResult(); @@ -56,7 +56,7 @@ try { - pomFile = createMetadataFile( url ); + pomFile = createMetadataFile( url, null, null ); } catch ( IOException e ) {