1 /*
   2  * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.security.jgss.wrapper;
  27 
  28 import java.util.HashMap;
  29 import java.security.Provider;
  30 import java.security.AccessController;
  31 import java.security.PrivilegedAction;
  32 import org.ietf.jgss.Oid;
  33 import sun.security.action.PutAllAction;
  34 import static sun.security.util.SecurityConstants.PROVIDER_VER;
  35 
  36 /**
  37  * Defines the Sun NativeGSS provider for plugging in the
  38  * native GSS mechanisms to Java GSS.
  39  *
  40  * List of supported mechanisms depends on the local
  41  * machine configuration.
  42  *
  43  * @author Yu-Ching Valerie Peng
  44  */
  45 
  46 public final class SunNativeProvider extends Provider {
  47 
  48     private static final long serialVersionUID = -238911724858694204L;
  49 
  50     private static final String NAME = "SunNativeGSS";
  51     private static final String INFO = "Sun Native GSS provider";
  52     private static final String MF_CLASS =
  53         "sun.security.jgss.wrapper.NativeGSSFactory";
  54     private static final HashMap<String, String> MECH_MAP;
  55     static final Provider INSTANCE;
  56     static boolean DEBUG;
  57     static void debug(String message) {
  58         if (DEBUG) {
  59             if (message == null) {
  60                 throw new NullPointerException();
  61             }
  62             System.out.println(NAME + ": " + message);
  63         }
  64     }
  65 
  66     static {
  67         MECH_MAP =
  68             AccessController.doPrivileged(
  69                 new PrivilegedAction<>() {
  70                     public HashMap<String, String> run() {
  71                         DEBUG = Boolean.parseBoolean(
  72                             System.getProperty("sun.security.nativegss.debug"));
  73                         try {
  74                             System.loadLibrary("j2gss");
  75                         } catch (Error err) {
  76                             debug("No j2gss library found!");
  77                             if (DEBUG) err.printStackTrace();
  78                             return null;
  79                         }
  80                         String[] gssLibs;
  81                         String defaultLib
  82                                 = System.getProperty("sun.security.jgss.lib");
  83                         if (defaultLib == null || defaultLib.trim().equals("")) {
  84                             String osname = System.getProperty("os.name");
  85                             if (osname.startsWith("Linux")) {
  86                                 gssLibs = new String[]{
  87                                     "libgssapi.so",
  88                                     "libgssapi_krb5.so",
  89                                     "libgssapi_krb5.so.2",
  90                                 };
  91                             } else if (osname.contains("OS X")) {
  92                                 gssLibs = new String[]{
  93                                     "libgssapi_krb5.dylib",
  94                                     "/usr/lib/sasl2/libgssapiv2.2.so",
  95                                };
  96                             } else if (osname.contains("Windows")) {
  97                                 // Full path needed, DLL is in jre/bin
  98                                 gssLibs = new String[]{ System.getProperty("java.home")
  99                                         + "\\bin\\sspi_bridge.dll" };
 100                             } else {
 101                                 gssLibs = new String[0];
 102                             }
 103                         } else {
 104                             gssLibs = new String[]{ defaultLib };
 105                         }
 106                         for (String libName: gssLibs) {
 107                             if (GSSLibStub.init(libName, DEBUG)) {
 108                                 debug("Loaded GSS library: " + libName);
 109                                 Oid[] mechs = GSSLibStub.indicateMechs();
 110                                 HashMap<String,String> map = new HashMap<>();
 111                                 for (int i = 0; i < mechs.length; i++) {
 112                                     debug("Native MF for " + mechs[i]);
 113                                     map.put("GssApiMechanism." + mechs[i],
 114                                             MF_CLASS);
 115                                 }
 116                                 return map;
 117                             }
 118                         }
 119                         return null;
 120                     }
 121                 });
 122         // initialize INSTANCE after MECH_MAP is constructed
 123         INSTANCE = new SunNativeProvider();
 124     }
 125 
 126     public SunNativeProvider() {
 127         /* We are the Sun NativeGSS provider */
 128         super(NAME, PROVIDER_VER, INFO);
 129 
 130         if (MECH_MAP != null) {
 131             AccessController.doPrivileged(new PutAllAction(this, MECH_MAP));
 132         }
 133     }
 134 }