Maven 1
  1. Maven 1
  2. MAVEN-456

unable to access remote repository via https

    Details

    • Type: Improvement Improvement
    • Status: Closed Closed
    • Priority: Major Major
    • Resolution: Won't Fix
    • Affects Version/s: 1.0-beta-10
    • Fix Version/s: None
    • Component/s: core
    • Labels:
      None
    • Number of attachments :
      0

      Description

      the remote repository is only accessable through http; it is not possible to access it via https.

      i needed to modify two methods in the class httputils to get this running (see below).

      ----------------------------------------

      public static void getFile( String url,
      File destinationFile,
      boolean ignoreErrors,
      boolean useTimestamp,
      String proxyHost,
      String proxyPort,
      String proxyUserName,
      String proxyPassword )
      throws Exception
      {
      String[] s = parseUrl( url );

      // *** MODIFIED - BEGIN ***

      // need to create url with separated parameters
      String protocol = s[0];
      String username = s[1];
      String password = s[2];
      String hostname = s[3];
      String hostport = s[4];
      String parsedUrl = s[5];

      /*
      String username = s[0];
      String password = s[1];
      String parsedUrl = s[2];

      URL source = new URL( parsedUrl );
      */

      URL source = new URL(protocol, hostname, Integer.parseInt(hostport), parsedUrl);

      // *** MODIFIED - END ***

      //set the timestamp to the file date.
      long timestamp = 0;
      boolean hasTimestamp = false;
      if ( useTimestamp && destinationFile.exists() )

      { timestamp = destinationFile.lastModified(); hasTimestamp = true; }

      //set proxy connection
      useProxyUser( proxyHost, proxyPort, proxyUserName, proxyPassword );

      //set up the URL connection
      URLConnection connection = source.openConnection();

      // *** MODIFIED - BEGIN ***

      // need to set <code>javax.net.ssl.HostnameVerifier</code> for <code>javax.net.ssl.HttpsURLConnection</code>, otherwise connection will be refused
      if (connection instanceof javax.net.ssl.HttpsURLConnection) {
      ( (javax.net.ssl.HttpsURLConnection) connection).setHostnameVerifier(
      new javax.net.ssl.HostnameVerifier() {
      public boolean verify(String hostname, javax.net.ssl.SSLSession session)

      { return true; }

      }
      );
      }

      // *** MODIFIED - END ***

      //modify the headers
      //NB: things like user authentication could go in here too.
      if ( useTimestamp && hasTimestamp )

      { connection.setIfModifiedSince( timestamp ); }

      // prepare Java 1.1 style credentials
      if ( username != null || password != null )
      {
      String up = username + ":" + password;
      String encoding = null;
      // check to see if sun's Base64 encoder is available.
      try

      { sun.misc.BASE64Encoder encoder = (sun.misc.BASE64Encoder) Class.forName( "sun.misc.BASE64Encoder" ).newInstance(); encoding = encoder.encode( up.getBytes() ); }

      catch ( Exception ex )

      { // Do nothing, as for MavenSession we will never use // auth and we will eventually move over httpclient // in the commons. }

      connection.setRequestProperty( "Authorization", "Basic " + encoding );
      }
      ...
      }

      ----------------------------------------

      static String[] parseUrl( String url )
      {
      // *** MODIFIED - BEGIN ***

      // parsed url into more paramters - it must be created with separated parameters
      // this also fixes a bug caused in <code>org.apache.maven.verifier.DependencyVerifier#getRemoteArtifact(Artifact)</code> when a https-url is used

      /*
      String[] parsedUrl = new String[3];
      parsedUrl[0] = null;
      parsedUrl[1] = null;
      parsedUrl[2] = url;

      // We want to be able to deal with Basic Auth where the username
      // and password are part of the URL. An example of the URL string
      // we would like to be able to parse is like the following:
      //
      // http://username:password@repository.mycompany.com

      int i = url.indexOf( "@" );
      if ( i > 0 )

      { String s = url.substring( 7, i ); int j = s.indexOf( ":" ); parsedUrl[0] = s.substring( 0, j ); parsedUrl[1] = s.substring( j + 1 ); parsedUrl[2] = "http://" + url.substring( i + 1 ); }

      */

      int pos0 = url.indexOf("://"); int step0 = 3;
      if (pos0 == -1)

      { pos0 = url.indexOf(":/"); step0 = 2; }

      int pos1 = url.indexOf('@');
      int pos2 = url.indexOf(':', pos0 + step0);
      if (pos2 > pos1)
      pos2 = -1;

      int pos3 = url.indexOf(':', (pos1 == -1 ? pos0 + step0 : pos1));
      int pos4 = url.indexOf('/', pos0 + step0);

      String[] parsedUrl = new String[6];

      parsedUrl[0] = url.substring(0, pos0);
      parsedUrl[1] = pos2 == -1 ? null : url.substring(pos0 + step0, pos2);
      parsedUrl[2] = pos2 == -1 ? null : url.substring(pos2 + 1, pos1);
      parsedUrl[3] = url.substring((pos1 == -1 ? pos0 + step0 : pos1 + 1), (pos3 == -1 ? (pos4 == -1 ? url.length() : pos4) : pos3));
      parsedUrl[4] = pos3 == -1 ? "-1" : url.substring(pos3 + 1, (pos4 == -1 ? url.length() : pos4));
      parsedUrl[5] = pos4 == -1 ? null : url.substring(pos4);

      // *** MODIFIED - END ***

      return parsedUrl;
      }

      ----------------------------------------

        Activity

        Hide
        Emmanuel Venisse added a comment -

        HttpsURLConnection is a 1.4 java class. Thus, we cannot use it.
        Perhaps, we can use Jakarta HttpClient instead of jdk api.

        Show
        Emmanuel Venisse added a comment - HttpsURLConnection is a 1.4 java class. Thus, we cannot use it. Perhaps, we can use Jakarta HttpClient instead of jdk api.
        Hide
        Brett Porter added a comment -

        HttpsUrlConnection is not a 1.4 class per se, it is a JSSE class, so it will work with JDK 1.3 + JSSE.

        However, this code doesn't seem like the right way to do it. I haven't tried it but I believe maven should work as is if the following is true:
        1) JSSE is properly installed (or using JDK 1.4)
        2) jssecacerts contains the certificate of the host you are trying to contact, or some other keystore is in place

        In my experience, setting up keystores, trusted servers, etc in code is not worth the effort - keystore files are much better.

        I don't know if HttpClient provides some way to add trusted servers easily, does it?

        Show
        Brett Porter added a comment - HttpsUrlConnection is not a 1.4 class per se, it is a JSSE class, so it will work with JDK 1.3 + JSSE. However, this code doesn't seem like the right way to do it. I haven't tried it but I believe maven should work as is if the following is true: 1) JSSE is properly installed (or using JDK 1.4) 2) jssecacerts contains the certificate of the host you are trying to contact, or some other keystore is in place In my experience, setting up keystores, trusted servers, etc in code is not worth the effort - keystore files are much better. I don't know if HttpClient provides some way to add trusted servers easily, does it?
        Hide
        Brett Porter added a comment -

        might already work - test

        Show
        Brett Porter added a comment - might already work - test
        Hide
        Juan F. Codagnone added a comment -

        with maven-1.0.2 I was able to use a private remote repository (using ssl, and a client certificate to restrict access).

        To make it work, I had to set some system properties. That is a bad thing because its a hell if you have to differents ssl repositories. I setuped the system properties in ~/.mavenrc:

        --8<------ ~/.mavenrc -----------
        REMOTE_REPO_CERTS=`pwd`/common/maven/bare/remote_repo/
        export MAVEN_OPTS="$MAVEN_OPTS -Djavax.net.ssl.trustStore=$REMOTE_REPO_CERTS/ca.keystore -Djavax.net.ssl.keyStore=$REMOTE_REPO_CERTS/clientkey.p12-Djavax.net.ssl.keyStorePassword=superSecretPassphrase"
        -----------------------------------

        I didn't found any way to achieve the same results from a build.properties. Should't be possible?

        Show
        Juan F. Codagnone added a comment - with maven-1.0.2 I was able to use a private remote repository (using ssl, and a client certificate to restrict access). To make it work, I had to set some system properties. That is a bad thing because its a hell if you have to differents ssl repositories. I setuped the system properties in ~/.mavenrc: -- 8< ------ ~/.mavenrc ----------- REMOTE_REPO_CERTS=`pwd`/common/maven/bare/remote_repo/ export MAVEN_OPTS="$MAVEN_OPTS -Djavax.net.ssl.trustStore=$REMOTE_REPO_CERTS/ca.keystore -Djavax.net.ssl.keyStore=$REMOTE_REPO_CERTS/clientkey.p12-Djavax.net.ssl.keyStorePassword=superSecretPassphrase" ----------------------------------- I didn't found any way to achieve the same results from a build.properties. Should't be possible?
        Hide
        Juan F. Codagnone added a comment -

        before the regrets begins, let me warn not to use the above script in computers shared between multiple users, because they can get the key passphrase.

        Show
        Juan F. Codagnone added a comment - before the regrets begins, let me warn not to use the above script in computers shared between multiple users, because they can get the key passphrase.
        Hide
        Michael Osipov added a comment -

        Please refer to https://cwiki.apache.org/confluence/display/MAVEN/The+Great+JIRA+Cleanup+of+2014 if you're wondering why this issue was closed out.

        Show
        Michael Osipov added a comment - Please refer to https://cwiki.apache.org/confluence/display/MAVEN/The+Great+JIRA+Cleanup+of+2014 if you're wondering why this issue was closed out.

          People

          • Assignee:
            Unassigned
            Reporter:
            Christoph Gruenwald
          • Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: