📄 sippermissionchecker.java
字号:
/* * SipPermissionChecker.java * * Created on June 13, 2003, 3:11 PM */package gov.nist.security.permissions;import java.io.*;import java.util.*;import org.apache.bcel.classfile.*;import org.apache.bcel.generic.*;import org.apache.bcel.util.*;import gov.nist.security.bcs.*;import gov.nist.security.permissions.parser.*;import org.apache.log4j.Logger;/** * This class is used to find all the locations in the bytecode * where we have to add the security hooks * @author DERUELLE Jean */public class SipPermissionChecker { /**ConstantPoolGEn of the JavaClass*/ protected static ConstantPoolGen cp; /** Byte code Java Class representation of the class*/ protected JavaClass jclass =null; /**the directory path where we will dump the file rewritten*/ private String dumpPath=null; /**the ByteCodeRewriter used to rewrite the classes*/ private ByteCodeRewriter byteCodeRewriter=null; /**log4j logging*/ static private Logger logger = Logger.getLogger(SipPermissionChecker.class); /** * Creates a new instance of SipPermissionChecker * @param dumpPath - the directory path where we have the rewritten file * @param classLoader - the classLoader used to load the classes */ public SipPermissionChecker(String dumpPath,ByteCodeRewriter byteCodeRewriter) { this.byteCodeRewriter=byteCodeRewriter; //We create a new variable where we will dump the class file //rewritten with the bytecode rewriting technique this.dumpPath=dumpPath; logger.debug("dumpPath : "+dumpPath); //parse the class to check or rewrite the bytecode try{ jclass = new ClassParser(dumpPath).parse(); cp = new ConstantPoolGen(jclass.getConstantPool()); } catch(FileNotFoundException fnfe) { fnfe.printStackTrace(); } catch(IOException e) { e.printStackTrace(); } } /** * For all the methods of the service, we check before runtime in the bytecode * all the methods where we have to add some security hook. If this is before runtime * we just add the checking of the permission, else we will check * if some methods are called with the good values at runtime * and for that we have to add the runtime security hooks * @param methodsToCheck - the methods to check in the user's service bytecode * @param permissionName - the permission name(URI or Domain or wildcard) to test against at runtime * @return true, if there is no security constraint violations */ public boolean checkSipPermissions(Vector methodsToCheck,String permissionName){ boolean permission=true; Method methods[]=null; if(!jclass.isInterface() ){ methods = jclass.getMethods(); //We will check if some methods are called with the good values // and if the access to the correpsonding permissions is granted //and for that we have to add the runtime security hooks for(int j=0;j<methodsToCheck.size();j++){ MethodTag methodDescription=(MethodTag)methodsToCheck.get(j); for (int k = 0; k < methods.length; k++) { if (!methods[k].isAbstract() && !methods[k].isNative()) { MethodGen mg = new MethodGen(methods[k],jclass.getClassName(), cp); //Call a helper method which will find where to add the hooks Method newMethod=findRuntimeHooksToAdd( mg ,methodDescription ,permissionName ,methodDescription.getCheckValue()); if(newMethod!=null) methods[k] = newMethod; } //if this is a native method or an abstract method // return and don't agree to run the service else return false; try{ // Dump the class to the directory dump with the same name jclass.setConstantPool(cp.getFinalConstantPool()); jclass.dump(dumpPath); } catch(IOException ioe){ ioe.printStackTrace(); } } } } else{ try{ // Dump the class to the directory dump with the same name jclass.setConstantPool(cp.getFinalConstantPool()); jclass.dump(dumpPath); } catch(IOException ioe){ ioe.printStackTrace(); } } return permission; } /** * Helper method which will find where to add the hooks * @param methodGen - the original method where to add the hooks * @param methodDescription - the method to test against with * @param permissionName - the permission name(URI or Domain or wildcard) to test against at runtime * @param argumentChecking - tells if yes or no this is a runtime hook or no * @return the new method with the runtime security hooks added */ protected Method findRuntimeHooksToAdd( MethodGen methodGen, MethodTag methodDescription, String permissionName, boolean argumentChecking){ InstructionList il = methodGen.getInstructionList(); Method method=methodGen.getMethod(); //Create a finder to search for all the invoke methods InstructionFinder f = new InstructionFinder(il); String pat = "InvokeInstruction+"; for (Iterator it = f.search(pat); it.hasNext(); ) { InstructionHandle[] match = (InstructionHandle[])it.next(); InstructionHandle handle = match[match.length -1]; InvokeInstruction invokeInstruction = (InvokeInstruction)handle.getInstruction(); //if the methods have the same signature //then a restricted method has been found //and we add a runtime security hook if(checkEquality(methodDescription,invokeInstruction)){ //Add the security hooks methodGen=byteCodeRewriter.addSecurityHooks(methodGen, match, cp, permissionName, methodDescription, argumentChecking); methodGen.setMaxStack(); methodGen.setMaxLocals(); logger.warn("/**************************************************/"); logger.warn("we added a security hook before the method " +methodDescription.getClassName()+ "."+methodDescription.getMethodName()+ " in the method "+method.getName() + " in the class "+methodGen.getClassName()); logger.warn("/**************************************************/"); method=methodGen.getMethod(); } } //return either the original method //or the modified method return method; } /** * Check if the 2 methods in parameter have the same signature * @param methodTag - methodTag from the permissions.xml file * @param invokeInstruction - invokeInstruction from the user's service bytecode * @return true if they have the same signature */ protected boolean checkEquality(MethodTag methodTag,InvokeInstruction invokeInstruction){ //System.out.println("Find a method corresponding :"+invokeInstruction.getMethodName(cp)+" "+invokeInstruction.getClassName(cp)); //Check if the methods have the same name, return type and are invoked from the same class type if(invokeInstruction.getMethodName(cp).equals(methodTag.getMethodName()) && invokeInstruction.getClassName(cp).equals(methodTag.getClassName()) && invokeInstruction.getReturnType(cp).toString().equals(methodTag.getReturnType()) ){ //logger.debug("Find a method corresponding :"+invokeInstruction.getMethodName(cp)+" "+invokeInstruction.getClassName(cp) // +" "+ invokeInstruction.getReturnType(cp)); //Check if the arguments of the methods are the same Type[] types= invokeInstruction.getArgumentTypes(cp); int i=0; boolean check=true; while(i<types.length && check){ Vector arguments= methodTag.getArguments(); Enumeration methodArgs=arguments.elements(); boolean find=false; while(methodArgs.hasMoreElements() && !find){ //logger.debug("argument "+i+" : "+types[i].toString().replace('$','.')); if(types[i].toString().equals((String)methodArgs.nextElement())) find=true; } if(!find) check=false; i++; } /*if(check) System.out.println("Same args types between the 2 methods"); else System.out.println("args types between the 2 methods are not the same");*/ return check; } return false; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -