GSSManagerFactory.java

  1. /*
  2.  * Copyright (C) 2014 Laurent Goujon <lgoujon@twitter.com> and others
  3.  *
  4.  * This program and the accompanying materials are made available under the
  5.  * terms of the Eclipse Distribution License v. 1.0 which is available at
  6.  * https://www.eclipse.org/org/documents/edl-v10.php.
  7.  *
  8.  * SPDX-License-Identifier: BSD-3-Clause
  9.  */

  10. package org.eclipse.jgit.util;

  11. import java.lang.reflect.Constructor;
  12. import java.lang.reflect.InvocationTargetException;
  13. import java.net.URL;

  14. import org.ietf.jgss.GSSManager;

  15. /**
  16.  * Factory to detect which GSSManager implementation should be used.
  17.  *
  18.  * @since 3.4
  19.  */
  20. public abstract class GSSManagerFactory {
  21.     /**
  22.      * Auto-detects the GSSManager factory to use based on system.
  23.      *
  24.      * @return detected GSSManager factory
  25.      */
  26.     public static GSSManagerFactory detect() {
  27.         return (SunGSSManagerFactory.isSupported()) ? new SunGSSManagerFactory()
  28.                 : new DefaultGSSManagerFactory();
  29.     }

  30.     /**
  31.      * Returns a GSS Manager instance for the provided url
  32.      *
  33.      * @param url
  34.      *            the repository url
  35.      * @return a GSSManager instance
  36.      */
  37.     public abstract GSSManager newInstance(URL url);

  38.     /**
  39.      * DefaultGSSManagerFactory uses @link {@link GSSManager#getInstance()} but
  40.      * you might need to set
  41.      * <code>javax.security.auth.useSubjectCredsOnly</code> system property to
  42.      * <code>false</code> for authentication to work.
  43.      */
  44.     private static class DefaultGSSManagerFactory extends GSSManagerFactory {
  45.         private static final GSSManager INSTANCE = GSSManager.getInstance();

  46.         @Override
  47.         public GSSManager newInstance(URL url) {
  48.             return INSTANCE;
  49.         }
  50.     }

  51.     private static class SunGSSManagerFactory extends GSSManagerFactory {
  52.         private static boolean IS_SUPPORTED;
  53.         private static Constructor<?> HTTP_CALLER_INFO_CONSTRUCTOR;
  54.         private static Constructor<?> HTTP_CALLER_CONSTRUCTOR;

  55.         private static Constructor<?> GSS_MANAGER_IMPL_CONSTRUCTOR;

  56.         static {
  57.             try {
  58.                 init();
  59.                 IS_SUPPORTED = true;
  60.             } catch (Exception e) {
  61.                 IS_SUPPORTED = false;
  62.             }
  63.         }

  64.         private static void init() throws ClassNotFoundException,
  65.                 NoSuchMethodException {
  66.             Class<?> httpCallerInfoClazz = Class
  67.                     .forName("sun.net.www.protocol.http.HttpCallerInfo"); //$NON-NLS-1$
  68.             HTTP_CALLER_INFO_CONSTRUCTOR = httpCallerInfoClazz
  69.                     .getConstructor(URL.class);

  70.             Class<?> httpCallerClazz = Class
  71.                     .forName("sun.security.jgss.HttpCaller"); //$NON-NLS-1$
  72.             HTTP_CALLER_CONSTRUCTOR = httpCallerClazz
  73.                     .getConstructor(httpCallerInfoClazz);

  74.             Class<?> gssCallerClazz = Class
  75.                     .forName("sun.security.jgss.GSSCaller"); //$NON-NLS-1$
  76.             Class<?> gssManagerImplClazz = Class
  77.                     .forName("sun.security.jgss.GSSManagerImpl"); //$NON-NLS-1$
  78.             GSS_MANAGER_IMPL_CONSTRUCTOR = gssManagerImplClazz
  79.                     .getConstructor(gssCallerClazz);

  80.         }

  81.         /**
  82.          * Detects if SunGSSManagerProvider is supported by the system
  83.          *
  84.          * @return true if it is supported
  85.          */
  86.         public static boolean isSupported() {
  87.             return IS_SUPPORTED;
  88.         }

  89.         @Override
  90.         public GSSManager newInstance(URL url) {
  91.             try {
  92.                 Object httpCallerInfo = HTTP_CALLER_INFO_CONSTRUCTOR
  93.                         .newInstance(url);
  94.                 Object httpCaller = HTTP_CALLER_CONSTRUCTOR
  95.                         .newInstance(httpCallerInfo);

  96.                 return (GSSManager) GSS_MANAGER_IMPL_CONSTRUCTOR
  97.                         .newInstance(httpCaller);
  98.             } catch (InstantiationException | IllegalAccessException
  99.                     | IllegalArgumentException | InvocationTargetException e) {
  100.                 throw new Error(e);
  101.             }
  102.         }
  103.     }
  104. }