Package com.hp.hpl.jena.grddl.impl

Source Code of com.hp.hpl.jena.grddl.impl.SecManager$SecContext

package com.hp.hpl.jena.grddl.impl;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilePermission;
import java.io.IOException;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Constructor;
import java.lang.reflect.ReflectPermission;
import java.net.NetPermission;
import java.net.SocketPermission;
import java.net.URL;
import java.rmi.server.UID;
import java.security.Permission;
import java.security.SecureRandom;
import java.security.Security;
import java.security.SecurityPermission;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.PropertyPermission;
import java.util.Set;

import net.sf.saxon.Configuration;
import net.sf.saxon.Controller;
import net.sf.saxon.PreparedStylesheet;
import net.sf.saxon.TransformerFactoryImpl;
import net.sf.saxon.event.Sender;
import net.sf.saxon.functions.SystemFunction;
import net.sf.saxon.functions.SystemFunctionLibrary;
import net.sf.saxon.functions.SystemProperty;
import net.sf.saxon.style.XSLGeneralIncorporate;
import net.sf.saxon.style.XSLStylesheet;
import net.sf.saxon.type.TypeHierarchy;

import org.apache.xerces.impl.XMLEntityManager;

import sun.net.NetworkClient;
import sun.net.www.http.HttpClient;
import sun.net.www.http.KeepAliveCache;

import com.hp.hpl.jena.rdf.model.AnonId;
import com.hp.hpl.jena.shared.BrokenException;

public class SecManager extends SecurityManager {

  static {
    if (System.getSecurityManager() == null)
      System.setSecurityManager(new SecManager());
  }

  private class SecContext {
    final boolean untrusted;

    final Object fromSuper;

    SecContext(Object fS) {
      fromSuper = fS;
      untrusted = untrustedThreadGroup();
    }
  }

  public SecManager() {
  }

  static private ThreadGroup notTrustedTG = new ThreadGroup("untrusted");

  private static int sb = 0;

  boolean untrustedThreadGroup() {
    return Thread.currentThread().getThreadGroup() == notTrustedTG;
  }

  public Object getSecurityContext() {
    return new SecContext(super.getSecurityContext());
  }

  // static private String filesep = System.getProperty("file.separator");
  static private String javaHome = System.getProperty("java.home");

  static private Set<String> onClassPath = new HashSet<String>();

  static private Set<String> allowProps = new HashSet<String>();

  static private Set<String> nonJarsOnClassPath = new HashSet<String>();

  static {
    String classpath = System.getProperty("java.class.path");
    String pathsep = System.getProperty("path.separator");
    String cp[] = classpath.split(pathsep);
    for (int i = 0; i < cp.length; i++) {
      File f = new File(cp[i]);
      try {
        boolean isJar = false;
        String absP = f.getAbsolutePath();
        onClassPath.add(absP);
        String absPLC = absP.toLowerCase();
        if (absPLC.endsWith(".jar"))
          isJar = true;
        if (absPLC.endsWith(".zip"))
          isJar = true;
        if (!isJar)
          nonJarsOnClassPath.add(absP);
        String canP = f.getCanonicalPath();
        onClassPath.add(canP);
        if (!isJar)
          nonJarsOnClassPath.add(canP);
      } catch (IOException e) {
        // TODO panic message
        e.printStackTrace();
      }
    }
    allowProps.add("javax.xml.parsers.SAXParserFactory");
    allowProps.add("org.apache.xerces.xni.parser.XMLParserConfiguration");
    allowProps.add("java.home");
    allowProps.add("line.separator");
    allowProps.add("jaxp.debug");
    allowProps.add("java.version");
  }

  public void checkPermission(Permission p) {
    checkPerm(p);
  }

  private void checkPerm(Permission p) {
    String actions = p.getActions();
    String name = p.getName();
    if (untrustedThreadGroup()) {
      try {
        checkPerm(p, actions, name);
      } catch (SecurityException e) {
        trace(false, p, name, actions);
        throw e;
      }
      trace(true, p, name, actions);
    }
  }

  private void trace(boolean permit, Permission p, String name, String actions) {
     if (true)
     return;
    if (p instanceof FilePermission)
      return;
    if (permit)
      return;
    System.err.println((permit ? "Allow: " : "Deny: ") + p);
    if ((!permit)
    // ||name.equals("createClassLoader")
    )
      dumpClassContext();

  }

  private void checkPerm(Permission p, String actions, String name) {

    if (p instanceof FilePermission) {
      File f = new File(name);
      if (actions.equals("read")
          && (onClassPath.contains(name)
              || onClassPath.contains(f.getAbsolutePath()) || startsWithOKDir(name)))
        return;
    }
    if (p instanceof PropertyPermission) {
      if (actions.equals("read")) {
        if (!checkStack(noSystemProperty)) {
          if (allowProps.contains(name))
            return;
          if (p.getName().toLowerCase().contains("proxy"))
            return;
          if (isJenaAnonId(getClassContext())) {
            return;
          }
        }
      }
    }

    if (p instanceof NetPermission
        && (name.equals("getCookieHandler")
            || name.equals("getResponseCache") || name
            .equals("getProxySelector"))) {
      if (checkStack(xmlParserStack))
        return;
      if (checkStack(preparedStylesheetStack))
        return;
      if (checkStack(importStack))
        return;
    }
    if (p instanceof SocketPermission) {
      if (checkStack(xmlParserStack))
        return;
      if (checkStack(preparedStylesheetStack))
        return;
      if (checkStack(importStack))
        return;
    }
    if (p instanceof ReflectPermission
        && name.equals("suppressAccessChecks")) {

      if (isJenaAnonId(getClassContext())) {
        return;
      }

      if (checkStack(classLoaderMiniStack))
        return;
      if (checkStack(accesibleMiniStack))
        return;
      if (checkStack(accesibleMethodStack))
        return;
      if (checkStack(methodInvokeStack))
        return;

    }
    if (p instanceof RuntimePermission
        && name.startsWith("accessClassInPackage.")) {
      // TODO more specific

      if (isJenaAnonId(getClassContext())) {
        return;
      }
    }
    if (p instanceof RuntimePermission
        && name.equals("writeFileDescriptor")) {

      if (checkStack(preparedStyleSheetWriteSocket))
        return;
      if (checkStack(xmlParserWriteSocket))
        return;
      if (checkStack(importWriteSocket))
        return;
    }
    if (p instanceof RuntimePermission && name.equals("readFileDescriptor")) {

      if (checkStack(preparedStyleSheetReadSocket))
        return;
      if (checkStack(xmlParserReadSocket))
        return;
      if (checkStack(importReadSocket))
        return;
    }
    if (p instanceof RuntimePermission && name.equals("createClassLoader")) {

      if (checkStack(classLoaderMiniStack))
        return;

      if (checkStack(methodInvokeStack))
        return;
    }
    if (p instanceof RuntimePermission
        && (name.equals("modifyThreadGroup") || name
            .equals("modifyThread"))) {
      if (checkStack(httpClientStack))
        return;
    }
    if (p instanceof SecurityPermission
        && (name.startsWith("getProperty.") || name
            .startsWith("putProviderProperty."))) {
      if (isJenaAnonId(getClassContext()))
        return;

    }
    throw new SecurityException(p.toString());
  }

  private boolean checkStack(String[][] pattern) {
    Class st[] = getClassContext();
    int next = 0;
    int matchedSoFar = 0;
    for (int i = 0; i < st.length; i++) {
      if (next > pattern.length)
        return false;
      if (pattern[next][0].equals("weak")
          && match(pattern[next + 1][1], st[i].getName())) {
        next++;
      }
      if (pattern[next][0].equals("return")) {
        if (pattern[next][1].equals("allowedNewInstance")) {
          // System.err.println("Allowing new instance from: "+
          // st[i].getName());
          return allowedNewInstance.contains(st[i].getName());
        }
        throw new BrokenException("Internal error: detail: "
            + pattern[next][1]);
      }
      while (!match(pattern[next][1], st[i].getName())) {
        if ((pattern[next][0].equals("some") && matchedSoFar > 0)
            || pattern[next][0].equals("optional")
            || pattern[next][0].equals("any")) {
          next++;
          matchedSoFar = 0;
          continue;
        }
        return false;
      }
      if (pattern[next][0].equals("1")
          || pattern[next][0].equals("optional")) {
        next++;
        matchedSoFar = 0;
      } else {
        matchedSoFar++;
      }
    }
    return next==pattern.length || next==pattern.length-1;
  }

  private static boolean match(String pattern, String name) {
    boolean result = name.startsWith(pattern);
    return result;
  }

  private boolean startsWithOKDir(String name) {
    if (name.startsWith(javaHome)) {
      return true;
    }
    Iterator<String> it = nonJarsOnClassPath.iterator();
    while (it.hasNext()) {
      if (name.startsWith(it.next()))
        return true;
    }
    return false;
  }

  private boolean isJenaAnonId(Class[] classContext) {
    int anonId = -1;
    for (int i = 0; i < classContext.length; i++)
      if (classContext[i] == AnonId.class) {
        anonId = i;
        break;
      }
    if (anonId == -1)
      return false;
    dumpClassContext();
    // TODO: check stack??
    if (true)
      return true;

    for (int i = 0; i < anonId; i++) {
      Class c = classContext[i];
      if (c == SecManager.class)
        continue;
      if (c == UID.class)
        continue;
      if (c == Security.class)
        continue;
      if (c == SecureRandom.class)
        continue;
      // if (c==Providers.class)
      // continue;
      // if (c==ProviderList.class)
      // continue;
      if (c.getName().startsWith("sun.security.jca.Provider"))
        continue;
      // continue;
      return false;
    }
    return true;
  }

  public void checkPermission(Permission p, Object o) {
    checkPerm(p, o);
  }

  public void checkPerm(Permission p, Object o) {
    SecContext sc = (SecContext) o;
    if (sc.untrusted) {
      try {
        super.checkPermission(p, sc.fromSuper);
      } catch (SecurityException e) {
        System.err.println("Deny: " + p);
        throw e;
      }
      System.err.println("Permit: " + p);
    }
  }

  private void dumpClassContext() {
    Class st[] = getClassContext();
    for (int i = 0; i < st.length; i++)
      System.err.println(i + ": " + st[i].getName());

  }

  // TODO: max stack size param
  public static void sandbox(Runnable r) {
    Thread t = new Thread(notTrustedTG, r, "SandBoxed-" + sb++);
    t.start();
    try {
      t.join();
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }

  private static final String[][] socketOutputSubstack = new String[][] {
      { "1", FileOutputStream.class.getName() },
      { "1", "java.net.SocketOutputStream" }, };

  private static final String[][] socketInputSubstack = new String[][] {
      { "1", FileInputStream.class.getName() },
      { "1", "java.net.SocketInputStream" }, };

  private static final String[][] xmlParserSubstack = new String[][] {
      { "any", "java.net." },
      { "optional", NetworkClient.class.getName() },
      { "any", HttpClient.class.getName() },
      { "some", "sun.net.www.protocol.http." },
      { "optional", URL.class.getName() },
      { "some", XMLEntityManager.class.getName() },
      { "some", "org.apache.xerces." },
      { "some", Sender.class.getName() },
      { "1", Controller.class.getName() } };

  private static final String[][] preparedStyleSheetSubstack = new String[][] {
      { "any", "java.net." },
      { "optional", NetworkClient.class.getName() },
      { "any", HttpClient.class.getName() },
      { "some", "sun.net.www.protocol.http." },
      { "optional", URL.class.getName() },
      { "some", XMLEntityManager.class.getName() },
      { "some", "org.apache.xerces." },
      { "some", Sender.class.getName() },
      { "some", PreparedStylesheet.class.getName() },
      { "some", TransformerFactoryImpl.class.getName() } };

  private static final String[][] importSubstack = new String[][] {
      { "any", "java.net." },
      { "optional", NetworkClient.class.getName() },
      { "any", HttpClient.class.getName() },
      { "some", "sun.net.www.protocol.http." },
      { "optional", URL.class.getName() },
      { "some", XMLEntityManager.class.getName() },
      { "some", "org.apache.xerces." },
      { "some", Sender.class.getName() },
      { "some", PreparedStylesheet.class.getName() },
      { "some", XSLGeneralIncorporate.class.getName() },
      { "some", XSLStylesheet.class.getName() },
      { "some", PreparedStylesheet.class.getName() },
      { "some", TransformerFactoryImpl.class.getName() } };

  static private String[][] xmlParserStack = topTail(xmlParserSubstack);

  static private String[][] preparedStylesheetStack = topTail(preparedStyleSheetSubstack);

  static private String[][] importStack = topTail(importSubstack);

  static private String[][] xmlParserWriteSocket = topTail(

  concat(socketOutputSubstack, xmlParserSubstack));

  static private String[][] preparedStyleSheetWriteSocket = topTail(concat(
      socketOutputSubstack, preparedStyleSheetSubstack));

  static private String[][] importWriteSocket = topTail(

  concat(socketOutputSubstack, importSubstack));

  static private String[][] xmlParserReadSocket = topTail(

  concat(socketInputSubstack, xmlParserSubstack));

  static private String[][] importReadSocket = topTail(

  concat(socketInputSubstack, importSubstack));

  static private String[][] preparedStyleSheetReadSocket = topTail(concat(
      socketInputSubstack, preparedStyleSheetSubstack));

  static private String[][] noSystemProperty = new String[][] {
      { "weak", "" }, { "1", SystemProperty.class.getName() },
      { "some", "" }, };

  static private String[][] classLoaderMiniStack = new String[][] {
      { "weak", "" }, { "1", Constructor.class.getName() },
      { "1", Class.class.getName() }, { "1", Class.class.getName() },
      { "return", "allowedNewInstance" }, };
  static private String[][] accesibleMiniStack = new String[][] {
    { "weak", "" },
    { "1", AccessibleObject.class.getName() },
    { "1", Class.class.getName() },
    { "1", Class.class.getName() },
    { "1", Class.class.getName() },
    { "return", "allowedNewInstance" }, };
  static private String[][] accesibleMethodStack = new String[][] {
    { "weak", "" },
    { "1", AccessibleObject.class.getName() },
    { "1", Class.class.getName() },
    { "1", Class.class.getName() },
    { "1", Class.class.getName() },
    { "some", "sun.reflect.MethodAccessorGenerator" },
   
    { "some", "" }, };
  static private String[][] httpClientStack = new String[][] {
      { "some", SecManager.class.getName() },
      { "optional", SecurityManager.class.getName() },
      { "any", ThreadGroup.class.getName() },
      { "any", Thread.class.getName() },
      { "any", KeepAliveCache.class.getName() },
      { "some", HttpClient.class.getName() }, { "some", "" } };

  static private String[][] methodInvokeStack = new String[][] {
    { "weak", "" },
    { "some", "sun.reflect.ClassDefiner" },
    { "some", "sun.reflect.MethodAccessorGenerator" },
    { "some", "" } };

  private static String[][] topTail(String[][] strings) {
    String[][] result = new String[strings.length + 4][];
    System.arraycopy(strings, 0, result, 2, strings.length);
    result[0] = new String[] { "some", SecManager.class.getName() };
    result[1] = new String[] { "optional", SecurityManager.class.getName() };
    result[result.length - 1] = new String[] { "1", Thread.class.getName() };
    result[result.length - 2] = new String[] { "some",
        GRDDL.class.getName() };
    return result;
  }

  private static final Set<String> allowedNewInstance = new HashSet<String>(
      Arrays.asList(new String[] {
          "org.apache.xerces.impl.dv.ObjectFactory",
          SystemFunction.class.getName(),
          SystemFunctionLibrary.class.getName(),
          Configuration.class.getName(),
          "javax.xml.parsers.FactoryFinder",
          TypeHierarchy.class.getName(), }));

  private static String[][] concat(String[][] a, String[][] b) {
    String rslt[][] = new String[a.length + b.length][];
    System.arraycopy(a, 0, rslt, 0, a.length);
    System.arraycopy(b, 0, rslt, a.length, b.length);
    return rslt;
  }
}

/*
* java.net.ResponseCache 5: sun.net.www.protocol.http.HttpURLConnection$3 6:
* sun.net.www.protocol.http.HttpURLConnection 7:
* sun.net.www.protocol.http.Handler 8: sun.net.www.protocol.http.Handler 9:
* java.net.URL 10: org.apache.xerces.impl.XMLEntityManager 11:
* org.apache.xerces.impl.XMLEntityManager 12:
* org.apache.xerces.impl.XMLEntityManager 13:
* org.apache.xerces.impl.XMLDTDScannerImpl 14:
* org.apache.xerces.impl.XMLDocumentScannerImpl$DTDDispatcher 15:
* org.apache.xerces.impl.XMLDocumentFragmentScannerImpl 16:
* org.apache.xerces.parsers.XML11Configuration 17:
* org.apache.xerces.parsers.XML11Configuration 18:
* org.apache.xerces.parsers.XMLParser 19:
* org.apache.xerces.parsers.AbstractSAXParser 20: net.sf.saxon.event.Sender 21:
* net.sf.saxon.event.Sender 22: net.sf.saxon.event.Sender 23:
* net.sf.saxon.Controller 24: com.hp.hpl.jena.grddl.impl.GRDDL$1 25:
* com.hp.hpl.jena.grddl.impl.GRDDL$2 26: java.lang.Thread
*/
 
TOP

Related Classes of com.hp.hpl.jena.grddl.impl.SecManager$SecContext

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.