Re-added SecureBPMN core module.

This commit is contained in:
Achim D. Brucker 2015-05-30 16:09:08 +02:00
parent 3fe42c341b
commit 6d53f71120
44 changed files with 10150 additions and 0 deletions

View File

@ -0,0 +1,31 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Activiti Designer - SecureBPMN Extension
Bundle-SymbolicName: eu.aniketos.securebpmn;singleton:=true
Bundle-Version: 5.8.0
Bundle-Activator: eu.aniketos.securebpmn.Activator
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Require-Bundle: org.eclipse.core.runtime,
org.eclipse.ui,
org.activiti.designer.model,
org.eclipse.graphiti,
org.eclipse.jdt.core,
org.eclipse.core.resources,
org.activiti.designer.eclipse,
org.activiti.designer.util,
org.antlr.runtime,
org.eclipse.emf.transaction,
org.eclipse.ui.ide
Export-Package: eu.aniketos.securebpmn.features,
eu.aniketos.securebpmn.ntk,
eu.aniketos.securebpmn.util,
eu.aniketos.securebpmn.visualization.rbac
Bundle-ClassPath: .,
xalan-2.7.1.jar,
serializer-2.7.1.jar,
xml-apis-1.3.04.jar,
com.sun.xacml-0.1.jar,
jdi.jar,
jdimodel.jar,
junit.jar

View File

@ -0,0 +1,5 @@
source.. = src/main/java/
output.. = target/
bin.includes = META-INF/,\
plugin.xml,\
.

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.6"?>
<plugin>
<extension
point="org.eclipse.ui.views">
<view
class="eu.aniketos.securebpmn.validation.view.ValidationView"
id="eu.aniketos.securebpmn.validation.view"
name="SecureBPMN Validation"
restorable="true">
</view>
</extension>
</plugin>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.activiti.designer</groupId>
<artifactId>org.activiti.designer.parent</artifactId>
<version>5.8.0</version>
<relativePath>../org.activiti.designer.parent/pom.xml</relativePath>
</parent>
<artifactId>eu.aniketos.securebpmn</artifactId>
<packaging>eclipse-plugin</packaging>
<name>Activiti Designer - SecureBPMN Extension</name>
</project>

View File

@ -0,0 +1,56 @@
/* Copyright 2012-2015 SAP SE
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package eu.aniketos.securebpmn;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
/**
* The activator class controls the plug-in life cycle
*
*
*/
public class Activator implements BundleActivator {
// The plug-in ID
public static final String PLUGIN_ID = "eu.aniketos.securebpmn"; //$NON-NLS-1$
private static BundleContext context;
static BundleContext getContext() {
return context;
}
/*
* (non-Javadoc)
*
* @see
* org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext
* )
*/
public void start(BundleContext bundleContext) throws Exception {
Activator.context = bundleContext;
}
/*
* (non-Javadoc)
*
* @see
* org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
*/
public void stop(BundleContext bundleContext) throws Exception {
Activator.context = null;
}
}

View File

@ -0,0 +1,300 @@
/* Copyright 2012-2015 SAP SE
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package eu.aniketos.securebpmn.features;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.activiti.designer.util.eclipse.ActivitiUiUtil;
import org.eclipse.bpmn2.ServiceTask;
import org.eclipse.bpmn2.impl.ServiceTaskImpl;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.graphiti.features.IFeatureProvider;
import org.eclipse.graphiti.features.context.ICustomContext;
import org.eclipse.graphiti.features.custom.AbstractCustomFeature;
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.ui.IEditorDescriptor;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.part.FileEditorInput;
import eu.aniketos.securebpmn.util.DialogUtil;
import eu.aniketos.securebpmn.validation.ProcVarCheckASTVisitor;
/**
* This feature provides a feature that checks a provided ServiceTask Java implementation if
* it accesses a process variable with a provided name and displays the result
* to the user.
*
*
*/
public class CheckServiceTaskFeature extends AbstractCustomFeature {
public CheckServiceTaskFeature(IFeatureProvider fp) {
super(fp);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.graphiti.features.impl.AbstractFeature#getName()
*/
@Override
public String getName() {
return "Check service task"; //$NON-NLS-1$
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.graphiti.features.custom.AbstractCustomFeature#getDescription
* ()
*/
@Override
public String getDescription() {
return "Check if service task accesses a specific process variable"; //$NON-NLS-1$
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.graphiti.features.custom.AbstractCustomFeature#canExecute
* (org.eclipse.graphiti.features.context.ICustomContext)
*/
@Override
public boolean canExecute(ICustomContext context) {
if (context.getPictogramElements() == null)
return false;
for (PictogramElement pictogramElement : context.getPictogramElements()) {
if (pictogramElement.getLink() == null)
continue;
Object boObject = getBusinessObjectForPictogramElement(pictogramElement);
if (boObject instanceof ServiceTask == false) {
return false;
}
}
return true;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.graphiti.features.custom.ICustomFeature#execute(org.eclipse
* .graphiti.features.context.ICustomContext)
*/
public void execute(ICustomContext context) {
ServiceTask servicetask = null;
// get BusinessObject
try {
servicetask = (ServiceTask) ActivitiUiUtil
.getBusinessObjectFromContext(context,
ServiceTaskImpl.class);
} catch (Exception e) {
DialogUtil.openMessageDialog("BO Missing",
"No ServiceTask BusinessObject for Context found",
DialogUtil.ERROR);
}
if (servicetask == null)
return;
// check if service task has java impl
if (servicetask.getImplementationType() == null
|| !(servicetask.getImplementationType().equals("classType"))) {
DialogUtil.openMessageDialog("Wrong Type",
"Type must be \"Java class\" to perform this check.",
DialogUtil.ERROR);
return;
}
if (servicetask.getImplementation() == null
|| servicetask.getImplementation().length() == 0) {
DialogUtil.openMessageDialog("Missing Class definition",
"No Java class specified.", DialogUtil.ERROR);
return;
}
// prompt user for process variable
String procVar = DialogUtil.openInputDialog("Process Variable",
"Enter the process variable that should not be accessed.", "",
null);
if (procVar == null) {
// user canceled
return;
}
// map FQ class name to java file
// TODO hack, do this nicely
String[] classParts = servicetask.getImplementation().split("\\.");
String implFileName = classParts[classParts.length - 1] + ".java";
StringBuilder sb = new StringBuilder();
sb.append("/");
sb.append("src");
sb.append("/");
sb.append("main");
sb.append("/");
sb.append("java");
sb.append("/");
for (int i = 0; i < classParts.length - 1; i++) {
sb.append(classParts[i]);
sb.append("/");
}
sb.append(implFileName);
IResource resourceToRead = null;
int filesFound = 0;
IWorkspace workspace = ResourcesPlugin.getWorkspace();
IWorkspaceRoot root = workspace.getRoot();
IProject[] projects = root.getProjects();
for (IProject project : projects) {
IResource resourceInRuntimeWorkspace = root.findMember(project
.getName() + sb.toString());
if (resourceInRuntimeWorkspace != null) {
filesFound++;
if (resourceToRead == null) {
resourceToRead = resourceInRuntimeWorkspace;
}
}
}
if (filesFound == 0) {
DialogUtil.openMessageDialog("Missing source",
"Implementation source file not found in workspace.",
DialogUtil.ERROR);
return;
} else if (filesFound > 1) {
DialogUtil
.openMessageDialog(
"Multiple files",
"Found "
+ filesFound
+ " matching source files in workspace, using the following:\n\n"
+ resourceToRead.getFullPath(),
DialogUtil.WARNING);
}
// read file
StringBuffer fileData = new StringBuffer(1000);
try {
BufferedReader reader = new BufferedReader(new FileReader(new File(
resourceToRead.getLocationURI())));
char[] buf = new char[1024];
int numRead = 0;
while ((numRead = reader.read(buf)) != -1) {
String readData = String.valueOf(buf, 0, numRead);
fileData.append(readData);
buf = new char[1024];
}
reader.close();
} catch (Exception e) {
e.printStackTrace();
DialogUtil.openMessageDialog("IO Error",
"Error while reading source file: " + e.getMessage(),
DialogUtil.ERROR);
return;
}
// build AST for Impl
List<Integer> locationList = new ArrayList<Integer>();
ASTParser parser = ASTParser.newParser(AST.JLS3);
parser.setKind(ASTParser.K_COMPILATION_UNIT);
parser.setSource(fileData.toString().toCharArray());
CompilationUnit node = (CompilationUnit) parser.createAST(null);
node.accept(new ProcVarCheckASTVisitor(procVar, locationList));
// remove duplicates
List<Integer> uniqueLocationList = new ArrayList<Integer>();
for (Integer i : locationList) {
Integer newLoc = node.getLineNumber(i);
if (!uniqueLocationList.contains(newLoc))
uniqueLocationList.add(newLoc);
}
if (uniqueLocationList.size() > 0) {
// notify user
StringBuilder msgSB = new StringBuilder();
msgSB.append("Process variable access of \"" + procVar
+ "\" found in implementation at ");
if (uniqueLocationList.size() > 1) {
msgSB.append("lines ");
for (int i = 0; i < uniqueLocationList.size() - 1; i++) {
msgSB.append(uniqueLocationList.get(i) + ", ");
}
msgSB.append("and "
+ uniqueLocationList.get(uniqueLocationList.size() - 1));
} else {
msgSB.append("line " + uniqueLocationList.get(0));
}
msgSB.append(".");
int answer = DialogUtil.openMessageDialog("Violation",
msgSB.toString(), DialogUtil.ERROR, new String[] { "OK",
"Open File"
}, 0);
if (answer == 1) {
// open source file
IWorkbench wb = PlatformUI.getWorkbench();
IWorkbenchPage page = wb.getActiveWorkbenchWindow()
.getActivePage();
IFile file = (IFile) resourceToRead;
IEditorDescriptor desc = wb.getEditorRegistry()
.getDefaultEditor(file.getName());
HashMap<String, Integer> map = new HashMap<String, Integer>();
map.put(IMarker.LINE_NUMBER, uniqueLocationList.get(0));
try {
IMarker marker = file.createMarker(IMarker.TEXT);
marker.setAttributes(map);
page.openEditor(new FileEditorInput(file), desc.getId());
IDE.openEditor(page, marker);
marker.delete();
} catch (Exception e) {
e.printStackTrace();
}
}
} else {
DialogUtil.openMessageDialog("No violation",
"No process variable access of \"" + procVar
+ "\" found in implementation.", DialogUtil.INFO);
}
}
}

View File

@ -0,0 +1,175 @@
/* Copyright 2012-2015 SAP SE
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package eu.aniketos.securebpmn.features;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.bpmn2.ServiceTask;
import org.eclipse.bpmn2.UserTask;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.graphiti.features.IFeatureProvider;
import org.eclipse.graphiti.features.context.ICustomContext;
import org.eclipse.graphiti.features.custom.AbstractCustomFeature;
import eu.aniketos.securebpmn.ntk.NeedToKnowUtil;
import eu.aniketos.securebpmn.util.DialogUtil;
import eu.aniketos.securebpmn.validation.ProcVarAccess;
/**
* The feature collects a list of all process variables that are accessed in the
* process and the way they are accessed (read, write or both) and displays it
* to the user.
*
*
*/
public class ListProcessVariablesFeature extends AbstractCustomFeature {
public ListProcessVariablesFeature(IFeatureProvider fp) {
super(fp);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.graphiti.features.impl.AbstractFeature#getName()
*/
@Override
public String getName() {
return "List process variables"; //$NON-NLS-1$
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.graphiti.features.custom.AbstractCustomFeature#getDescription
* ()
*/
@Override
public String getDescription() {
return "Retrieve all processs variables accessed and display them to the user."; //$NON-NLS-1$
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.graphiti.features.custom.AbstractCustomFeature#canExecute
* (org.eclipse.graphiti.features.context.ICustomContext)
*/
@Override
public boolean canExecute(ICustomContext context) {
return true;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.graphiti.features.custom.ICustomFeature#execute(org.eclipse
* .graphiti.features.context.ICustomContext)
*/
public void execute(ICustomContext context) {
// fill list
Map<String, String> accesses = new HashMap<String, String>();
List<EObject> diagramContents = getDiagram().eResource().getContents();
for (EObject object : diagramContents) {
if (object instanceof ServiceTask) {
ServiceTask sTask = (ServiceTask) object;
for (ProcVarAccess varAccess : NeedToKnowUtil
.getAccessedProcessVariables(sTask)) {
if (accesses.containsKey(varAccess.getName())) {
// update
String currentAccess = accesses
.get(varAccess.getName());
if (currentAccess.length() > 1) {
// nothing to do, already rw
continue;
}
if ((currentAccess.equals("r") && varAccess.isWrite())
|| (currentAccess.equals("w") && !varAccess
.isWrite())) {
accesses.put(varAccess.getName(), "rw");
} else
continue;
} else {
accesses.put(varAccess.getName(),
varAccess.isWrite() ? "w" : "r");
}
}
} else if (object instanceof UserTask) {
UserTask uTask = (UserTask) object;
for (ProcVarAccess varAccess : NeedToKnowUtil
.getAccessedProcessVariables(uTask)) {
if (accesses.containsKey(varAccess.getName())) {
// update
String currentAccess = accesses
.get(varAccess.getName());
if (currentAccess.length() > 1) {
// nothing to do, already rw
continue;
}
if ((currentAccess.equals("r") && varAccess.isWrite())
|| (currentAccess.equals("w") && !varAccess
.isWrite())) {
accesses.put(varAccess.getName(), "rw");
} else
continue;
} else {
accesses.put(varAccess.getName(),
varAccess.isWrite() ? "w" : "r");
}
}
}
}
// notify user
StringBuilder sb = new StringBuilder();
Set<String> accessedVars = accesses.keySet();
if (accessedVars.size() == 0) {
sb.append("No process variables are accessed in this process.");
} else {
sb.append("The following process variables are being accessed:\n");
for (String s : accessedVars) {
sb.append(s + " (" + accesses.get(s) + ")\n");
}
}
DialogUtil.openMessageDialog("Process variable access", sb.toString(),
DialogUtil.INFO);
}
}

View File

@ -0,0 +1,276 @@
/* Copyright 2012-2015 SAP SE
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package eu.aniketos.securebpmn.features;
import java.util.List;
import org.eclipse.bpmn2.DataInput;
import org.eclipse.bpmn2.DataOutput;
import org.eclipse.bpmn2.InputSet;
import org.eclipse.bpmn2.OutputSet;
import org.eclipse.bpmn2.ServiceTask;
import org.eclipse.bpmn2.Task;
import org.eclipse.bpmn2.UserTask;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.graphiti.features.IFeatureProvider;
import org.eclipse.graphiti.features.context.ICustomContext;
import org.eclipse.graphiti.features.custom.AbstractCustomFeature;
import org.eclipse.securebpmn2.ActivityAuthorizationConstraint;
import org.eclipse.securebpmn2.AuthorizationConstraint;
import org.eclipse.securebpmn2.CompositeItemAwareElementAction;
import org.eclipse.securebpmn2.ItemAwareElementAction;
import org.eclipse.securebpmn2.NeedToKnow;
import org.eclipse.securebpmn2.Permission;
import eu.aniketos.securebpmn.ntk.NeedToKnowUtil;
import eu.aniketos.securebpmn.util.DialogUtil;
/**
* This feature performs an analysis of the need-to-know specification and
* constraints in the process and notifies the user with the result, i.e., if
* violations were found or not.
*
*
*/
public class PerformNtkAnalysisFeature extends AbstractCustomFeature {
public PerformNtkAnalysisFeature(IFeatureProvider fp) {
super(fp);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.graphiti.features.impl.AbstractFeature#getName()
*/
@Override
public String getName() {
return "Perform NtK analysis"; //$NON-NLS-1$
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.graphiti.features.custom.AbstractCustomFeature#getDescription
* ()
*/
@Override
public String getDescription() {
return "Perform the analysis of need-to-know specifications"; //$NON-NLS-1$
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.graphiti.features.custom.AbstractCustomFeature#canExecute
* (org.eclipse.graphiti.features.context.ICustomContext)
*/
@Override
public boolean canExecute(ICustomContext context) {
return true;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.graphiti.features.custom.ICustomFeature#execute(org.eclipse
* .graphiti.features.context.ICustomContext)
*/
@Override
public void execute(ICustomContext context) {
final List<EObject> diagramElements = getDiagram().eResource()
.getContents();
for (EObject obj : diagramElements) {
if (!(obj instanceof UserTask || obj instanceof ServiceTask))
continue;
final Task t = (Task) obj;
if (t.getIoSpecification() == null)
continue;
// check read access
for (InputSet inSet : t.getIoSpecification().getInputSets()) {
for (DataInput in : inSet.getDataInputRefs()) {
boolean isValid = false;
for (ItemAwareElementAction iaea : in
.getItemAwareElementActions()) {
if (isValid)
break;
if (!iaea.getActionName().equals("read"))
continue;
for (CompositeItemAwareElementAction comp : iaea
.getCompositeItemAwareElementActions()) {
if (comp.getActionName().equals("read/write")) {
// analyze parent composite action from this
// point on
iaea = comp;
break;
}
}
for (Permission p : iaea.getPermissions()) {
if (isValid)
break;
if (!(p instanceof NeedToKnow))
continue;
for (AuthorizationConstraint ac : p
.getAuthorizationConstraints()) {
if (!(ac instanceof ActivityAuthorizationConstraint))
continue;
ActivityAuthorizationConstraint aac = (ActivityAuthorizationConstraint) ac;
if (aac.getActivities().contains(t)) {
isValid = true;
break;
}
}
}
}
if (!isValid) {
String varName = in.getId().substring(
NeedToKnowUtil.ID_PREFIX_INPUT.length());
if (t instanceof UserTask) {
// UserTask message
DialogUtil
.openMessageDialog(
"Validation error",
"Read access of process variable \""
+ varName
+ "\" is not permitted at Task \""
+ t.getId()
+ "\".\n\nRemove the corresponding form field or review your need-to-know specification.",
DialogUtil.ERROR);
} else if (t instanceof ServiceTask) {
// ServiceTask message
DialogUtil
.openMessageDialog(
"Validation error",
"Read access of process variable \""
+ varName
+ "\" is not permitted at Task \""
+ t.getId()
+ "\".\n\nReview your Java implementation or your need-to-know specification. To see where the access occurs in the implementation, use the \"Check Service Task\" feature available via the context menu.",
DialogUtil.ERROR);
}
return;
}
}
}
// check write access
for (OutputSet outSet : t.getIoSpecification().getOutputSets()) {
for (DataOutput out : outSet.getDataOutputRefs()) {
boolean isValid = false;
for (ItemAwareElementAction iaea : out
.getItemAwareElementActions()) {
if (isValid)
break;
if (!iaea.getActionName().equals("write"))
continue;
for (CompositeItemAwareElementAction comp : iaea
.getCompositeItemAwareElementActions()) {
if (comp.getActionName().equals("read/write")) {
// analyze parent composite action from this
// point on
iaea = comp;
break;
}
}
for (Permission p : iaea.getPermissions()) {
if (isValid)
break;
if (!(p instanceof NeedToKnow))
continue;
for (AuthorizationConstraint ac : p
.getAuthorizationConstraints()) {
if (!(ac instanceof ActivityAuthorizationConstraint))
continue;
ActivityAuthorizationConstraint aac = (ActivityAuthorizationConstraint) ac;
if (aac.getActivities().contains(t)) {
isValid = true;
break;
}
}
}
}
if (!isValid) {
String varName = out.getId().substring(
NeedToKnowUtil.ID_PREFIX_OUTPUT.length());
if (t instanceof UserTask) {
// UserTask message
DialogUtil
.openMessageDialog(
"Validation error",
"Write access of process variable \""
+ varName
+ "\" is not permitted at Task \""
+ t.getId()
+ "\".\n\nRemove the corresponding form field or review your need-to-know specification.",
DialogUtil.ERROR);
} else if (t instanceof ServiceTask) {
// ServiceTask message
DialogUtil
.openMessageDialog(
"Validation error",
"Write access of process variable \""
+ varName
+ "\" is not permitted at Task \""
+ t.getId()
+ "\".\n\nReview your Java implementation or your need-to-know specification. To see where the access occurs in the implementation, use the \"Check Service Task\" feature available via the context menu.",
DialogUtil.ERROR);
}
return;
}
}
}
}
// no errors
DialogUtil
.openMessageDialog(
"No validation errors",
"All process variables are accessed according to the specification.",
DialogUtil.INFO);
}
}

View File

@ -0,0 +1,565 @@
/* Copyright 2012-2015 SAP SE
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package eu.aniketos.securebpmn.features;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import org.eclipse.bpmn2.BoundaryEvent;
import org.eclipse.bpmn2.CallActivity;
import org.eclipse.bpmn2.FlowElement;
import org.eclipse.bpmn2.FlowNode;
import org.eclipse.bpmn2.InclusiveGateway;
import org.eclipse.bpmn2.StartEvent;
import org.eclipse.bpmn2.SubProcess;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.graphiti.features.IFeatureProvider;
import org.eclipse.graphiti.features.context.ICustomContext;
import org.eclipse.graphiti.features.custom.AbstractCustomFeature;
import org.eclipse.graphiti.mm.pictograms.ContainerShape;
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
import org.eclipse.graphiti.services.Graphiti;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.progress.IProgressService;
import eu.aniketos.securebpmn.satmc.SatmcFact;
import eu.aniketos.securebpmn.satmc.SatmcFunction;
import eu.aniketos.securebpmn.satmc.SatmcMessage;
import eu.aniketos.securebpmn.satmc.SatmcTraceStep;
import eu.aniketos.securebpmn.satmc.Summary;
import eu.aniketos.securebpmn.util.DialogUtil;
import eu.aniketos.securebpmn.validation.SCVMValidationConstants;
import eu.aniketos.securebpmn.validation.ValidateAslanRunnable;
import eu.aniketos.securebpmn.visualization.ActionType;
import eu.aniketos.securebpmn.visualization.VisualizationElement;
import eu.aniketos.securebpmn.visualization.rbac.AttackTracePlayer;
import eu.aniketos.securebpmn.visualization.rbac.AttackTraceStep;
import eu.aniketos.securebpmn.visualization.rbac.RbacVisualization;
/**
* This feature performs an analysis of the access control specification and
* constraints contained in the process and notifies the user, if violations
* were found or not. This feature is not intended for direct use, you should
* use the class ValidateAslanLocalFeature or ValidateAslanWebFeature, depending
* on how you want SATMC to be executed.
*
*
*/
public class ValidateAslanFeature extends AbstractCustomFeature {
public ValidateAslanFeature(IFeatureProvider fp) {
super(fp);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.graphiti.features.impl.AbstractFeature#getName()
*/
@Override
public String getName() {
return "Validate ASLan"; //$NON-NLS-1$
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.graphiti.features.custom.AbstractCustomFeature#getDescription
* ()
*/
@Override
public String getDescription() {
return "Validate ASLan using SATMC"; //$NON-NLS-1$
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.graphiti.features.custom.AbstractCustomFeature#canExecute
* (org.eclipse.graphiti.features.context.ICustomContext)
*/
@Override
public boolean canExecute(ICustomContext context) {
return true;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.graphiti.features.custom.ICustomFeature#execute(org.eclipse
* .graphiti.features.context.ICustomContext)
*/
public void execute(ICustomContext context) {
this.execute(true);
}
/**
* Starts the analysis of the ASLan representation and reacts according to
* the result, either displaying a message to the user or starting the
* attack trace visualization if an attack was found.
*
* @param local
* true if the local SATMC binary should be used, false if the
* SATMC web service should be used.
*/
public void execute(boolean local) {
// check for unsupported elements.
List<String> unsupportedElements = getUnsupportedElementTypes();
if (unsupportedElements.size() > 0) {
// ask user what to do
StringBuilder ueMessage = new StringBuilder();
ueMessage
.append("The diagram contains the following currently unsupported elements:\n");
for (String ue : unsupportedElements) {
ueMessage.append(ue.endsWith("Impl") ? ue.substring(0,
ue.length() - 4) : ue);
ueMessage.append("\n");
}
ueMessage
.append("\nThe analysis result might be incorrect. Continue anyway?");
String[] ueButtons = { "Continue", "Cancel" };
int ueContinue = DialogUtil.openMessageDialog(
"Unsupported elements found!", ueMessage.toString(),
DialogUtil.WARNING, ueButtons, 1);
if (ueContinue == 1)
return;
}
// get & parse result
SatmcMessage result = new SatmcMessage(null, null, null, null);
try {
final IProgressService progressService = PlatformUI.getWorkbench()
.getProgressService();
final ValidateAslanRunnable runnable = new ValidateAslanRunnable(
getDiagram(), result, local);
progressService.busyCursorWhile(runnable);
} catch (Exception e) {
e.printStackTrace();
}
// check if validation/parsing was successful
if (result.summary == null) {
return;
} else if (result.summary == Summary.ERROR) {
DialogUtil.openMessageDialog("Error", "SATMC Error",
DialogUtil.ERROR);
return;
} else if (result.summary == Summary.INCONCLUSIVE) {
DialogUtil.openMessageDialog("Validation inconclusive",
"SATMC analysis was inconclusive.", DialogUtil.INFO);
return;
} else if (result.summary == Summary.NO_ATTACK_FOUND) {
DialogUtil.openMessageDialog("No attack found", "No attack found!",
DialogUtil.INFO);
return;
} else if (result.summary == Summary.UNKNOWN) {
DialogUtil.openMessageDialog("Unknown result",
"SATMC result is unknown!", DialogUtil.WARNING);
return;
} else if (result.summary == Summary.ATTACK_FOUND) {
List<AttackTraceStep> traceList = extractElementIDsAndDescription(result);
DialogUtil.openMessageDialog("Attack found",
"Attack found!\n\nViolated goal: " + result.goal,
DialogUtil.ERROR);
// set result in storage
RbacVisualization.getInstance().setResult(result);
findBusinessObjectsAndPictogramElements(traceList);
// create & store player
RbacVisualization.getInstance().setPlayer(
new AttackTracePlayer(getDiagram(), traceList));
// open view
try {
PlatformUI
.getWorkbench()
.getActiveWorkbenchWindow()
.getActivePage()
.showView(
"eu.aniketos.securebpmn.validation.view");
} catch (PartInitException e) {
e.printStackTrace();
}
}
}
/**
* Replaces the task instance IDs with the task IDs in the violated goal of
* the result. Extracts the attack trace steps and for each step the task
* ID, the type of the step (claim, execute or violation) and the
* description of the step.
*
* @param result
* The SATMC result that should be analyzed and modified.
* @return A List of AttackTraceSteps, each step containing the task ID,
* type and description.
*/
private List<AttackTraceStep> extractElementIDsAndDescription(
SatmcMessage result) {
List<AttackTraceStep> traceList = new ArrayList<AttackTraceStep>();
// dummy step for StartEvent
traceList.add(new AttackTraceStep());
// get number of tasks in goal
int tasksInGoal = 0;
for (SatmcFact fact : result.goal.args) {
if (fact instanceof SatmcFunction) {
SatmcFunction func = (SatmcFunction) fact;
if (func.name.equals("n") && func.args.size() == 1) {
tasksInGoal++;
}
}
}
int goalTasksStartIndex = result.goal.args.size() - tasksInGoal;
// Goals:
// name: sod; args: 0. user 1. task1 2. task2
// name: bod; args: 0. user1 1. user2 2. task1 3. task2
// Rules:
// name: h_TaskExecution; args: 0. user 1. role 2. task 3. tInstance
// 4. inData 5. outData
// name: atask_execution; args: 0. task 1. tInstance 2. inData 3.
// outData
// name: authorizeTaskExecution; args: 0. user 1. role 2. task 3.
// tInstance
for (SatmcTraceStep sts : result.trace) {
AttackTraceStep traceElement = new AttackTraceStep();
String stepText = "";
for (SatmcFunction rule : sts.rules) {
if (rule.args.size() > 5
&& rule.name
.equals(SCVMValidationConstants.HUMAN_TASK_RULE_NAME)) {
// UserTask
// replace taskInstances with taskIDs in goal
if (result.goal.args.size() > 2
&& result.goal.name
.startsWith(SCVMValidationConstants.GOAL_SOD_PREFIX)) {
for (int i = goalTasksStartIndex; i < result.goal.args
.size(); i++) {
if (rule.args.get(3).toString()
.equals(result.goal.args.get(i).toString())) {
result.goal.args.set(i, rule.args.get(2));
}
}
} else if (result.goal.args.size() > 3
&& result.goal.name
.startsWith(SCVMValidationConstants.GOAL_BOD_PREFIX)) {
for (int i = goalTasksStartIndex; i < result.goal.args
.size(); i++) {
if (rule.args.get(3).toString()
.equals(result.goal.args.get(i).toString())) {
result.goal.args.set(i, rule.args.get(2));
}
}
}
traceElement.addInvolvedElement(new VisualizationElement(
rule.args.get(2).toString(), ActionType.EXECUTE));
stepText += "Human task \"" + rule.args.get(2).toString()
+ "\" executed by user \""
+ rule.args.get(0).toString() + "\" with role \""
+ rule.args.get(1).toString() + "\".\n";
} else if (rule.args.size() > 3
&& rule.name
.equals(SCVMValidationConstants.AUTOMATED_TASK_RULE_NAME)) {
// any other Task
traceElement.addInvolvedElement(new VisualizationElement(
rule.args.get(0).toString(), ActionType.EXECUTE));
stepText += "Automated task \""
+ rule.args.get(0).toString() + "\" executed.\n";
} else if (rule.args.size() > 3
&& rule.name
.equals(SCVMValidationConstants.TASK_AUTHORIZATION_RULE_NAME)) {
// claiming of a Task
traceElement.addInvolvedElement(new VisualizationElement(
rule.args.get(2).toString(), ActionType.CLAIM));
stepText += "User \"" + rule.args.get(0).toString()
+ "\" claimed task \""
+ rule.args.get(2).toString() + "\" using role \""
+ rule.args.get(1).toString() + "\".\n";
} else {
// check for gateway
String[] ruleNameParts = rule.name.split("_");
if (ruleNameParts.length > 1) {
if (ruleNameParts[0].equals("w")
&& ruleNameParts[1].contains("gateway")) {
// AND-split or AND-join
traceElement
.addInvolvedElement(new VisualizationElement(
ruleNameParts[1],
ActionType.WORKFLOW));
stepText += "Passing parallel gateway \""
+ ruleNameParts[1] + "\".\n";
} else if (ruleNameParts[0].contains("gateway")
&& ruleNameParts[1].startsWith("branch")) {
// XOR-split or XOR-join
traceElement
.addInvolvedElement(new VisualizationElement(
ruleNameParts[0],
ActionType.WORKFLOW));
stepText += "Passing exclusive gateway \""
+ ruleNameParts[0] + "\".\n";
}
}
}
}
if (traceElement.getInvolvedElements().size() > 0) {
traceElement.setDescription(stepText);
traceList.add(traceElement);
}
}
// step for goal violation highlighting
AttackTraceStep goalStep = new AttackTraceStep();
goalStep.setDescription("Violation of goal \"" + result.goal.toString()
+ "\".");
if (result.goal.args.size() > 2
&& result.goal.name
.startsWith(SCVMValidationConstants.GOAL_SOD_PREFIX)) {
// SoD
for (int i = goalTasksStartIndex; i < result.goal.args.size(); i++) {
goalStep.addInvolvedElement(new VisualizationElement(
result.goal.args.get(i).toString(),
ActionType.VIOLATION));
}
String sodElementID = result.goal.name.substring(
SCVMValidationConstants.GOAL_SOD_PREFIX.length(),
result.goal.name.lastIndexOf("_"));
goalStep.addInvolvedElement(new VisualizationElement(sodElementID,
ActionType.VIOLATION));
} else if (result.goal.args.size() > 3
&& result.goal.name
.startsWith(SCVMValidationConstants.GOAL_BOD_PREFIX)) {
// BoD
for (int i = goalTasksStartIndex; i < result.goal.args.size(); i++) {
goalStep.addInvolvedElement(new VisualizationElement(
result.goal.args.get(i).toString(),
ActionType.VIOLATION));
}
String bodElementID = result.goal.name.substring(
SCVMValidationConstants.GOAL_BOD_PREFIX.length(),
result.goal.name.lastIndexOf("_"));
goalStep.addInvolvedElement(new VisualizationElement(bodElementID,
ActionType.VIOLATION));
}
traceList.add(goalStep);
return traceList;
}
/**
* Finds the BusinessObjects and PictogramElements for each task ID in the
* provided lists and adds these to the single elements in the list.
*
* @param traceList
* The List of AttackTraceSteps for which the BOs and PEs should
* be found.
*/
private void findBusinessObjectsAndPictogramElements(
List<AttackTraceStep> traceList) {
// get diagram elements
List<FlowElement> diagramElements = new ArrayList<FlowElement>();
for (EObject object : getDiagram().eResource().getContents()) {
if (object instanceof FlowElement)
diagramElements.add((FlowElement) object);
}
for (AttackTraceStep traceStep : traceList) {
for (VisualizationElement element : traceStep.getInvolvedElements()) {
// find BO
for (FlowElement bo : diagramElements) {
if (bo.getId().equals(element.getId())) {
element.setbObject(bo);
break;
}
}
if (element.getbObject() == null) {
System.err
.println("[SCVM-RBAC] No FlowElement found for ID \""
+ element.getId() + "\"!");
}
// find corresponding PE
List<PictogramElement> pElements = Graphiti.getLinkService()
.getPictogramElements(getDiagram(),
element.getbObject());
for (PictogramElement pElement : pElements) {
if (pElement instanceof ContainerShape) {
ContainerShape cs = (ContainerShape) pElement;
element.setpElement(cs);
}
}
if (element.getpElement() == null) {
System.err
.println("[SCVM-RBAC] No PictogramElement found for ID \""
+ element.getId() + "\"!");
}
}
}
// get and add start event
// there should only be one FlowNode after a StartEvent
StartEvent startEvent = null;
// find start event
if (traceList.size() > 1) {
List<VisualizationElement> firstElements = traceList.get(1)
.getInvolvedElements();
if (firstElements.size() > 0) {
FlowNode firstNode = (FlowNode) firstElements.get(0)
.getbObject();
if (firstNode.getIncoming().size() > 0) {
FlowNode start = firstNode.getIncoming().get(0)
.getSourceRef();
if (start instanceof StartEvent) {
startEvent = (StartEvent) start;
}
}
}
}
// create entry if we found it
if (startEvent != null) {
VisualizationElement startElement = new VisualizationElement(
startEvent.getId(), ActionType.WORKFLOW);
startElement.setbObject(startEvent);
// find corresponding pictogram element
List<PictogramElement> pElements = Graphiti.getLinkService()
.getPictogramElements(getDiagram(), startEvent);
for (PictogramElement pElement : pElements) {
// change element representation
if (pElement instanceof ContainerShape) {
ContainerShape cs = (ContainerShape) pElement;
startElement.setpElement(cs);
}
}
traceList.get(0).addInvolvedElement(startElement);
traceList.get(0).setDescription("The process has been started.");
}
}
/**
* Returns a list with the names of the BPMN 2.0 elements that are currently
* not supported by the analysis.
*
* @return A List with the names of the unsupported elements as Strings.
*/
private List<String> getUnsupportedElementTypes() {
List<String> res = new ArrayList<String>();
for (EObject object : getDiagram().eResource().getContents()) {
if (object instanceof SubProcess || object instanceof CallActivity
|| object instanceof InclusiveGateway
|| object instanceof BoundaryEvent) {
res.add(object.getClass().getSimpleName());
}
}
// remove duplicates
HashSet<String> h = new HashSet<String>(res);
res.clear();
res.addAll(h);
return res;
}
}

View File

@ -0,0 +1,82 @@
/* Copyright 2012-2015 SAP SE
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package eu.aniketos.securebpmn.features;
import org.eclipse.graphiti.features.IFeatureProvider;
import org.eclipse.graphiti.features.context.ICustomContext;
/**
* This feature performs an analysis of the access control specification and
* constraints contained in the process and notifies the user, if violations
* were found or not. For analysis of the ASLan file, the local SATMC binary is
* used.
*
*
*/
public class ValidateAslanLocalFeature extends ValidateAslanFeature {
public ValidateAslanLocalFeature(IFeatureProvider fp) {
super(fp);
}
/*
* (non-Javadoc)
*
* @see
* eu.aniketos.securebpmn.features.ValidateAslanFeature
* #getName()
*/
@Override
public String getName() {
return "Validate security local"; //$NON-NLS-1$
}
/*
* (non-Javadoc)
*
* @see
* eu.aniketos.securebpmn.features.ValidateAslanFeature
* #getDescription()
*/
@Override
public String getDescription() {
return "Validate security featues using local SATMC binary"; //$NON-NLS-1$
}
/*
* (non-Javadoc)
*
* @see
* eu.aniketos.securebpmn.features.ValidateAslanFeature
* #canExecute(org.eclipse.graphiti.features.context.ICustomContext)
*/
@Override
public boolean canExecute(ICustomContext context) {
return true;
}
/*
* (non-Javadoc)
*
* @see
* eu.aniketos.securebpmn.features.ValidateAslanFeature
* #execute(org.eclipse.graphiti.features.context.ICustomContext)
*/
@Override
public void execute(ICustomContext context) {
super.execute(true);
}
}

View File

@ -0,0 +1,82 @@
/* Copyright 2012-2015 SAP SE
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package eu.aniketos.securebpmn.features;
import org.eclipse.graphiti.features.IFeatureProvider;
import org.eclipse.graphiti.features.context.ICustomContext;
/**
* This feature performs an analysis of the access control specification and
* constraints contained in the process and notifies the user, if violations
* were found or not. For analysis of the ASLan file, the SATMC web service is
* used.
*
*
*/
public class ValidateAslanWebFeature extends ValidateAslanFeature {
public ValidateAslanWebFeature(IFeatureProvider fp) {
super(fp);
}
/*
* (non-Javadoc)
*
* @see
* eu.aniketos.securebpmn.features.ValidateAslanFeature
* #getName()
*/
@Override
public String getName() {
return "Validate security web"; //$NON-NLS-1$
}
/*
* (non-Javadoc)
*
* @see
* eu.aniketos.securebpmn.features.ValidateAslanFeature
* #getDescription()
*/
@Override
public String getDescription() {
return "Validate security featues using SATMC web service"; //$NON-NLS-1$
}
/*
* (non-Javadoc)
*
* @see
* eu.aniketos.securebpmn.features.ValidateAslanFeature
* #canExecute(org.eclipse.graphiti.features.context.ICustomContext)
*/
@Override
public boolean canExecute(ICustomContext context) {
return true;
}
/*
* (non-Javadoc)
*
* @see
* eu.aniketos.securebpmn.features.ValidateAslanFeature
* #execute(org.eclipse.graphiti.features.context.ICustomContext)
*/
@Override
public void execute(ICustomContext context) {
super.execute(false);
}
}

View File

@ -0,0 +1,453 @@
/* Copyright 2012-2015 SAP SE
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package eu.aniketos.securebpmn.ntk;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.bpmn2.Bpmn2Factory;
import org.eclipse.bpmn2.DataInput;
import org.eclipse.bpmn2.DataOutput;
import org.eclipse.bpmn2.FormProperty;
import org.eclipse.bpmn2.InputOutputSpecification;
import org.eclipse.bpmn2.InputSet;
import org.eclipse.bpmn2.OutputSet;
import org.eclipse.bpmn2.ServiceTask;
import org.eclipse.bpmn2.Task;
import org.eclipse.bpmn2.UserTask;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.graphiti.mm.pictograms.Diagram;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.securebpmn2.AuthorizationConstraint;
import org.eclipse.securebpmn2.ItemAwareElementAction;
import org.eclipse.securebpmn2.NeedToKnow;
import org.eclipse.securebpmn2.Permission;
import eu.aniketos.securebpmn.validation.ProcVarAccess;
import eu.aniketos.securebpmn.validation.ProcVarListASTVisitor;
/**
* This class contains utility methods that are being used in the need-to-know
* analysis.
*
*
*/
public class NeedToKnowUtil {
public static final String ID_PREFIX_IOSPEC = "iospec_";
public static final String ID_PREFIX_INSET = "inset_ntk_";
public static final String ID_PREFIX_OUTSET = "outset_ntk_";
public static final String ID_PREFIX_INPUT = "input_ntk_";
public static final String ID_PREFIX_OUTPUT = "output_ntk_";
/**
* Provides the names of the SecureBPMN ItemAwareElementActions that are
* used.
*
* @return An Array containing the names of the ItemAwareElementActions as
* Strings.
*/
public static String[] getItemAwareElementActionNames() {
return new String[] { "read", "write", "read/write" };
}
/**
* Finds the names of the process variables that are accessed in the
* provided task. Only the HTML forms of a UserTask and the Java
* implementation of a ServiceTask can be analyzed.
*
* @param task
* The task (UserTask or ServiceTask) that should be analyzed.
* @return A List with the names of the accessed process variables as
* Strings.
*/
public static List<String> getAccessedProcessVariableNames(Task task) {
List<String> result = new ArrayList<String>();
List<ProcVarAccess> varAccesses = new ArrayList<ProcVarAccess>();
if (task instanceof UserTask) {
varAccesses = getAccessedProcessVariables((UserTask) task);
} else if (task instanceof ServiceTask) {
varAccesses = getAccessedProcessVariables((ServiceTask) task);
}
for (ProcVarAccess var : varAccesses) {
final String varName = var.getName();
if (!result.contains(varName))
result.add(varName);
}
return result;
}
/**
* Analyzes a UserTask and extracts the process variables that are accesses
* and the type of access (read, write or both). Note that only the Activiti
* built-in HTML forms are analyzed.
*
* @param userTask
* The UserTask that should be analyzed.
* @return A List containing the process variable accesses represented as
* ProcVarAccess.
*/
public static List<ProcVarAccess> getAccessedProcessVariables(
UserTask userTask) {
List<ProcVarAccess> result = new ArrayList<ProcVarAccess>();
for (FormProperty fp : userTask.getFormProperties()) {
boolean var = false;
String expr = fp.getValue();
if (expr.startsWith("${") && expr.endsWith("}")) {
expr = expr.substring(2, expr.length() - 1);
var = true;
}
if (var) {
// variable access
if (fp.getReadable() != null && fp.getReadable()
&& fp.getWriteable() != null && !fp.getWriteable()) {
// read only
result.add(new ProcVarAccess(expr, -1, false));
} else if (fp.getReadable() != null && !fp.getReadable()
&& fp.getWriteable() != null && fp.getWriteable()) {
// write only
result.add(new ProcVarAccess(expr, -1, true));
} else {
// read/write default assumption
result.add(new ProcVarAccess(expr, -1, false));
result.add(new ProcVarAccess(expr, -1, true));
}
}
}
return result;
}
/**
* Analyzes a ServiceTask and extracts the process variables that are
* accesses and the type of access (read, write or both). Note that only
* ServiceTasks with a Java implementation are analyzed.
*
* @param serviceTask
* The ServiceTask that should be analyzed.
* @return A List containing the process variable accesses represented as
* ProcVarAccess.
*/
public static List<ProcVarAccess> getAccessedProcessVariables(
ServiceTask serviceTask) {
List<ProcVarAccess> result = new ArrayList<ProcVarAccess>();
// check if service task has valid java impl
if (serviceTask.getImplementationType() == null
|| !(serviceTask.getImplementationType().equals("classType"))) {
return result;
}
if (serviceTask.getImplementation() == null
|| serviceTask.getImplementation().length() == 0) {
return result;
}
final String canonicalClassName = serviceTask.getImplementation();
String[] classParts = canonicalClassName.split("\\.");
String implFileName = classParts[classParts.length - 1] + ".java";
StringBuilder sb = new StringBuilder();
sb.append("/");
sb.append("src");
sb.append("/");
sb.append("main");
sb.append("/");
sb.append("java");
sb.append("/");
for (int i = 0; i < classParts.length - 1; i++) {
sb.append(classParts[i]);
sb.append("/");
}
sb.append(implFileName);
IResource resourceToRead = null;
int filesFound = 0;
IWorkspace workspace = ResourcesPlugin.getWorkspace();
IWorkspaceRoot root = workspace.getRoot();
IProject[] projects = root.getProjects();
for (IProject project : projects) {
IResource resourceInRuntimeWorkspace = root.findMember(project
.getName() + sb.toString());
if (resourceInRuntimeWorkspace != null) {
filesFound++;
if (resourceToRead == null) {
resourceToRead = resourceInRuntimeWorkspace;
}
}
}
if (filesFound == 0) {
return result;
} else if (filesFound > 1) {
System.err
.println("[ListProcVar WARNING] Found multiple source files for class: "
+ canonicalClassName);
}
// read file
StringBuffer fileData = new StringBuffer(1000);
try {
BufferedReader reader = new BufferedReader(new FileReader(new File(
resourceToRead.getLocationURI())));
char[] buf = new char[1024];
int numRead = 0;
while ((numRead = reader.read(buf)) != -1) {
String readData = String.valueOf(buf, 0, numRead);
fileData.append(readData);
buf = new char[1024];
}
reader.close();
} catch (Exception e) {
System.err
.println("[ListProcVar ERROR] Error reading source file for class \""
+ canonicalClassName + "\": " + e.getMessage());
return result;
}
// build AST for Impl
ASTParser parser = ASTParser.newParser(AST.JLS3);
parser.setKind(ASTParser.K_COMPILATION_UNIT);
parser.setSource(fileData.toString().toCharArray());
CompilationUnit node = (CompilationUnit) parser.createAST(null);
node.accept(new ProcVarListASTVisitor(result));
return result;
}
/**
* Updates the BPMN 2.0 elements that represent the process variable access
* of a given task, in particular, DataInput and DataOutput elements.
*
* @param task
* The task whose elements should be updated.
* @param diagram
* The diagram containing the task.
*/
public static void updateIOSpecification(Task task, Diagram diagram) {
if (!(task instanceof UserTask || task instanceof ServiceTask))
return;
InputOutputSpecification iospec = task.getIoSpecification();
// create InputOutputSpecification if missing
if (iospec == null) {
iospec = Bpmn2Factory.eINSTANCE.createInputOutputSpecification();
iospec.setId(ID_PREFIX_IOSPEC + task.getId());
task.setIoSpecification(iospec);
diagram.eResource().getContents().add(iospec);
}
// keep InputOutputSpecification ID consistent with Task ID
if (!iospec.getId().equals(ID_PREFIX_IOSPEC + task.getId())) {
task.getIoSpecification().setId(ID_PREFIX_IOSPEC + task.getId());
}
// search for NtK InputSet
InputSet inSet = null;
for (InputSet tmpInSet : iospec.getInputSets()) {
if (tmpInSet.getId().equals(ID_PREFIX_INSET + task.getId())) {
inSet = tmpInSet;
break;
}
}
if (inSet == null) {
inSet = Bpmn2Factory.eINSTANCE.createInputSet();
inSet.setId(ID_PREFIX_INSET + task.getId());
inSet.setName("Need-to-know DataObjects read by task "
+ task.getId());
iospec.getInputSets().add(inSet);
diagram.eResource().getContents().add(inSet);
}
// search for NtK OutputSet
OutputSet outSet = null;
for (OutputSet tmpOutSet : iospec.getOutputSets()) {
if (tmpOutSet.getId().equals(ID_PREFIX_OUTSET + task.getId())) {
outSet = tmpOutSet;
break;
}
}
if (outSet == null) {
outSet = Bpmn2Factory.eINSTANCE.createOutputSet();
outSet.setId(ID_PREFIX_OUTSET + task.getId());
outSet.setName("Need-to-know DataObjects written by task "
+ task.getId());
iospec.getOutputSets().add(outSet);
diagram.eResource().getContents().add(outSet);
}
// create DataInput/DataOutput elements
List<ProcVarAccess> varAccesses = new ArrayList<ProcVarAccess>();
if (task instanceof UserTask) {
varAccesses = getAccessedProcessVariables((UserTask) task);
} else {
varAccesses = getAccessedProcessVariables((ServiceTask) task);
}
// add new elements
List<EObject> diagramElements = diagram.eResource().getContents();
for (ProcVarAccess varAccess : varAccesses) {
if (varAccess.isWrite()) {
// check if DataOutput element exists in diagram
DataOutput output = null;
for (EObject obj : diagramElements) {
if (obj instanceof DataOutput) {
if (((DataOutput) obj).getId().equals(
ID_PREFIX_OUTPUT + varAccess.getName())) {
output = (DataOutput) obj;
break;
}
}
}
if (output == null) {
// DataOutput does not exist, create
output = Bpmn2Factory.eINSTANCE.createDataOutput();
output.setId(ID_PREFIX_OUTPUT + varAccess.getName());
outSet.getDataOutputRefs().add(output);
output.getOutputSetRefs().add(outSet);
diagram.eResource().getContents().add(output);
} else {
// check if DataOutput element exists in OutputSet
if (!outSet.getDataOutputRefs().contains(output)) {
outSet.getDataOutputRefs().add(output);
output.getOutputSetRefs().add(outSet);
}
}
} else {
// check if DataInput exists in diagram
DataInput input = null;
for (EObject obj : diagramElements) {
if (obj instanceof DataInput) {
if (((DataInput) obj).getId().equals(
ID_PREFIX_INPUT + varAccess.getName())) {
input = (DataInput) obj;
break;
}
}
}
if (input == null) {
// DataInput does not exist, create
input = Bpmn2Factory.eINSTANCE.createDataInput();
input.setId(ID_PREFIX_INPUT + varAccess.getName());
inSet.getDataInputRefs().add(input);
input.getInputSetRefs().add(inSet);
diagram.eResource().getContents().add(input);
} else {
// check if DataInput element exists in InputSet
if (!inSet.getDataInputRefs().contains(input)) {
inSet.getDataInputRefs().add(input);
input.getInputSetRefs().add(inSet);
}
}
}
}
// remove elements for missing process variables
for (DataInput in : inSet.getDataInputRefs()) {
boolean varDeleted = true;
for (ProcVarAccess pvar : varAccesses) {
if (in.getId().equals(ID_PREFIX_INPUT + pvar.getName())
&& !pvar.isWrite()) {
varDeleted = false;
break;
}
}
if (varDeleted) {
inSet.getDataInputRefs().remove(in);
in.getInputSetRefs().remove(inSet);
if (in.getInputSetRefs().size() == 0) {
diagram.eResource().getContents().remove(in);
}
for (ItemAwareElementAction iaea : in
.getItemAwareElementActions()) {
for (Permission p : iaea.getPermissions()) {
p.getActions().remove(iaea);
}
}
}
}
for (DataOutput out : outSet.getDataOutputRefs()) {
boolean varDeleted = true;
for (ProcVarAccess pvar : varAccesses) {
if (out.getId().equals(ID_PREFIX_OUTPUT + pvar.getName())
&& pvar.isWrite()) {
varDeleted = false;
break;
}
}
if (varDeleted) {
outSet.getDataOutputRefs().remove(out);
out.getOutputSetRefs().remove(outSet);
if (out.getOutputSetRefs().size() == 0) {
diagram.eResource().getContents().remove(out);
}
for (ItemAwareElementAction iaea : out
.getItemAwareElementActions()) {
for (Permission p : iaea.getPermissions()) {
p.getActions().remove(iaea);
}
}
}
}
// remove broken NtK permissions
for (EObject o : diagramElements) {
if (o instanceof NeedToKnow) {
NeedToKnow ntk = (NeedToKnow) o;
if (ntk.getActions().size() == 0) {
// delete ActivityAC
for (AuthorizationConstraint ac : ntk
.getAuthorizationConstraints()) {
diagram.eResource().getContents().remove(ac);
}
// delete NtK
diagram.eResource().getContents().remove(ntk);
}
}
}
}
}

View File

@ -0,0 +1,71 @@
/* Copyright 2012-2015 SAP SE
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package eu.aniketos.securebpmn.roles;
import java.util.ArrayList;
import java.util.List;
/**
* A definition of a role and the containing users in the user/role definition
* file.
*
*
*/
public class RoleDef implements RoleDefLine {
private String roleName;
private List<String> members;
/**
* Creates a role definition.
*
* @param roleName
* The name of the role.
*/
public RoleDef(String roleName) {
this.roleName = roleName;
members = new ArrayList<String>();
}
/**
* Adds a member to the role.
*
* @param member
* The name of a new member as a String.
*/
public void addMember(String member) {
members.add(member);
}
/**
* Returns the name of the role.
*
* @return The name of the role as a String.
*/
public String getRoleName() {
return roleName;
}
/**
* Returns the name of the members of the role.
*
* @return A List containing the names of the members.
*/
public List<String> getMembers() {
return members;
}
}

View File

@ -0,0 +1,25 @@
/* Copyright 2012-2015 SAP SE
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package eu.aniketos.securebpmn.roles;
/**
* An Interface that represents a line in the user/role definition file.
*
*
*/
public interface RoleDefLine {
}

View File

@ -0,0 +1,60 @@
/* Copyright 2012-2015 SAP SE
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package eu.aniketos.securebpmn.roles;
/**
* A definition of a relation between two roles in the role hierarchy, used in
* the user/role definition file.
*
*
*/
public class RoleRel implements RoleDefLine {
private String superRole;
private String subRole;
/**
* Creates a relation between two roles.
*
* @param superRole
* The name of the higher role.
* @param subRole
* The name of the lower role.
*/
public RoleRel(String superRole, String subRole) {
this.superRole = superRole;
this.subRole = subRole;
}
/**
* Returns the name of the higher role.
*
* @return The name of the higher role as a String.
*/
public String getSuperRole() {
return superRole;
}
/**
* Returns the name of the lower role.
*
* @return The Name of the lower role as a String.
*/
public String getSubRole() {
return subRole;
}
}

View File

@ -0,0 +1,25 @@
/* Copyright 2012-2015 SAP SE
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package eu.aniketos.securebpmn.satmc;
/**
* This Interface represents a fact in the SATMC output.
*
*
*/
public interface SatmcFact {
}

View File

@ -0,0 +1,53 @@
/* Copyright 2012-2015 SAP SE
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package eu.aniketos.securebpmn.satmc;
import java.util.List;
/**
* This Class represents a function in the SATMC output.
*
*
*/
public class SatmcFunction implements SatmcFact {
public String name;
public List<SatmcFact> args;
public SatmcFunction(String name, List<SatmcFact> args) {
this.name = name;
this.args = args;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
String res = name + "(";
boolean first = true;
for (SatmcFact sf : args) {
if (first) {
first = false;
} else {
res += ",";
}
res += sf.toString();
}
return res + ")";
}
}

View File

@ -0,0 +1,38 @@
/* Copyright 2012-2015 SAP SE
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package eu.aniketos.securebpmn.satmc;
import java.util.List;
/**
* Wrapper class for the parsed SATMC output.
*
*
*/
public class SatmcMessage {
public Summary summary;
public SatmcFunction goal;
public List<SatmcTraceStep> trace;
public List<SatmcFunction> cfs;
public SatmcMessage(Summary summary, SatmcFunction goal,
List<SatmcTraceStep> trace, List<SatmcFunction> cfs) {
this.summary = summary;
this.goal = goal;
this.trace = trace;
this.cfs = cfs;
}
}

View File

@ -0,0 +1,33 @@
/* Copyright 2012-2015 SAP SE
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package eu.aniketos.securebpmn.satmc;
import java.util.List;
/**
* This Class represents a step in the attack trace of the SATMC output.
*
*
*/
public class SatmcTraceStep {
public List<SatmcFunction> clauses;
public List<SatmcFunction> rules;
public SatmcTraceStep(List<SatmcFunction> clauses, List<SatmcFunction> rules) {
this.clauses = clauses;
this.rules = rules;
}
}

View File

@ -0,0 +1,39 @@
/* Copyright 2012-2015 SAP SE
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package eu.aniketos.securebpmn.satmc;
/**
* This Class represents a variable (text/numbers only) in the SATMC output.
*
*
*/
public class SatmcVar implements SatmcFact {
public String name;
public SatmcVar(String name) {
this.name = name;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return name;
}
}

View File

@ -0,0 +1,25 @@
/* Copyright 2012-2015 SAP SE
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package eu.aniketos.securebpmn.satmc;
/**
* The different summary types of the SATMC output.
*
*
*/
public enum Summary {
ATTACK_FOUND, NO_ATTACK_FOUND, INCONCLUSIVE, ERROR, UNKNOWN
}

View File

@ -0,0 +1,134 @@
/* Copyright 2012-2015 SAP SE
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package eu.aniketos.securebpmn.util;
import org.eclipse.jface.dialogs.IInputValidator;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;
/**
* Creates user notification/input dialogs.
*
*/
public class DialogUtil {
public static final int ERROR = 2;
public static final int WARNING = 1;
public static final int INFO = 0;
/**
* Get the currently active Shell or the first available one if none is
* active.
*
* @return The current Shell.
*/
private static Shell getShell() {
Display display = PlatformUI.getWorkbench().getDisplay();
Shell shell = display.getActiveShell();
if (shell == null) {
// eclipse window not active, get first shell
Shell[] shells = display.getShells();
shell = shells.length > 0 ? shells[0] : null;
}
return shell;
}
/**
* Opens a dialog window that contains a message and an input field. The
* input is returned as a String.
*
* @param title
* The title of the message window.
* @param message
* The message to be displayed in the window.
* @param initialValue
* The initial value of the input field.
* @param validator
* An InputValidator Class that checks the contents of the input
* field.
* @return The contents of the input field as a String.
*/
public static String openInputDialog(String title, String message,
String initialValue, IInputValidator validator) {
InputDialog id = new InputDialog(getShell(), title, message,
initialValue, validator);
id.open();
return id.getValue();
}
/**
* Opens a dialog window that contains an image and a message.
*
* @param title
* The title of the message window.
* @param message
* The message to be displayed in the window.
* @param image
* The image that should be displayed in the window.
* @param buttons
* The labels of the Buttons the window should contain.
* @param defaultButton
* The index of the Button that should be selected by default.
* @return The index of the Button that was pressed.
*/
public static int openMessageDialog(String title, String message,
int image, String[] buttons, int defaultButton) {
MessageDialog dialog;
switch (image) {
case INFO:
dialog = new MessageDialog(getShell(), title, null, message,
MessageDialog.INFORMATION, buttons, defaultButton);
break;
case WARNING:
dialog = new MessageDialog(getShell(), title, null, message,
MessageDialog.WARNING, buttons, defaultButton);
break;
case ERROR:
dialog = new MessageDialog(getShell(), title, null, message,
MessageDialog.ERROR, buttons, defaultButton);
break;
default:
dialog = new MessageDialog(getShell(), title, null, message,
MessageDialog.NONE, buttons, defaultButton);
break;
}
return dialog.open();
}
/**
* Opens a dialog window that contains an image and a message.
*
* @param title
* The title of the message window.
* @param message
* The message to be displayed in the window.
* @param image
* The image that should be displayed in the window.
* @return The index of the Button that was pressed.
*/
public static int openMessageDialog(String title, String message, int image) {
return openMessageDialog(title, message, image, new String[] { "OK" },
0);
}
}

View File

@ -0,0 +1,360 @@
/* Copyright 2012-2015 SAP SE
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package eu.aniketos.securebpmn.util;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import org.activiti.designer.util.eclipse.ActivitiUiUtil;
import org.antlr.roledef.RoleDefLexer;
import org.antlr.roledef.RoleDefParser;
import org.antlr.runtime.ANTLRStringStream;
import org.antlr.runtime.CommonTokenStream;
import org.antlr.runtime.RecognitionException;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.emf.transaction.util.TransactionUtil;
import org.eclipse.graphiti.mm.pictograms.Diagram;
import org.eclipse.securebpmn2.Action;
import org.eclipse.securebpmn2.Role;
import org.eclipse.securebpmn2.Securebpmn2Factory;
import org.eclipse.securebpmn2.Subject;
import org.eclipse.securebpmn2.User;
import eu.aniketos.securebpmn.roles.RoleDef;
import eu.aniketos.securebpmn.roles.RoleDefLine;
import eu.aniketos.securebpmn.roles.RoleRel;
/**
* This Class contains utility methods for retrieving Users, Roles and
* ActivityActions.
*
*
*/
public class SecurityUtil {
private static List<Role> roles;
private static List<User> users;
private static List<Action> activityActions;
private static String diagramName;
/**
* Retrieve the roles for a given Diagram.
*
* @param diagram
* The diagram for which the roles should be retrieved.
* @return A List of Roles that are specified for the Diagram.
*/
public static List<Role> getRoles(Diagram diagram) {
if (diagram == null || diagram.getName() == null)
return new ArrayList<Role>();
if (diagramName == null) {
diagramName = diagram.getName();
}
if (roles == null || !diagram.getName().equals(diagramName)) {
loadRolesAndUsers(diagram);
}
return roles;
}
/**
* Retrieve the users for a given Diagram.
*
* @param diagram
* The diagram for which the users should be retrieved.
* @return A List of Users that are specified for the Diagram.
*/
public static List<User> getUsers(Diagram diagram) {
if (diagramName == null) {
diagramName = diagram.getName();
}
if (users == null || !diagram.getName().equals(diagramName)) {
loadRolesAndUsers(diagram);
}
return users;
}
/**
* Retrieve the ActivityActions that are currently available.
*
* @return A List of ActivityActions that are available.
*/
public static List<Action> getActivityActions() {
if (activityActions == null) {
activityActions = new ArrayList<Action>();
Action claimActivityAction = Securebpmn2Factory.eINSTANCE
.createAtomicActivityAction();
claimActivityAction.setId(UUID.randomUUID().toString());
claimActivityAction.setActionName("Claim");
Action assignActivityAction = Securebpmn2Factory.eINSTANCE
.createAtomicActivityAction();
assignActivityAction.setId(UUID.randomUUID().toString());
assignActivityAction.setActionName("Assign");
Action completeActivityAction = Securebpmn2Factory.eINSTANCE
.createAtomicActivityAction();
completeActivityAction.setActionName("Complete");
completeActivityAction.setId(UUID.randomUUID().toString());
Action fullAccess = Securebpmn2Factory.eINSTANCE
.createCompositeActivityAction();
fullAccess.setActionName("Full Access");
activityActions.add(fullAccess);
activityActions.add(claimActivityAction);
activityActions.add(assignActivityAction);
activityActions.add(completeActivityAction);
}
return activityActions;
}
/**
* Loads the roles and users from the configuration file. The file must be
* located in the same folder as the Diagram and the filename must be the
* same name as the Diagram file with the extension .roles.
*
* @param diagram
* The Diagram for which the roles and users should be loaded.
*/
private static void loadRolesAndUsers(final Diagram diagram) {
// clear roles and users that may exist
if (roles == null) {
roles = new ArrayList<Role>();
} else {
roles.clear();
}
if (users == null) {
users = new ArrayList<User>();
} else {
users.clear();
}
// parse role file and fill lists
if (diagram != null) {
// role hierarchy
List<RoleRel> hierarchy = new ArrayList<RoleRel>();
String in = "";
// get file location
URI uri = diagram.eResource().getURI();
URI platformUri = uri.trimFragment();
platformUri = platformUri.trimFileExtension();
platformUri = platformUri.appendFileExtension("roles");
final IResource fileResource = ResourcesPlugin.getWorkspace()
.getRoot().findMember(platformUri.toPlatformString(true));
if (fileResource != null && fileResource.exists()) {
final String fileUri = fileResource.getLocation().toString();
// read file
try {
in = readFileAsString(fileUri);
} catch (IOException e) {
System.err.println("[SCVM-RBAC] Error while reading file: "
+ fileUri.toString());
e.printStackTrace();
}
}
if (in.length() > 0) {
List<RoleDefLine> lines = null;
try {
RoleDefLexer lex = new RoleDefLexer(new ANTLRStringStream(
in));
CommonTokenStream tokens = new CommonTokenStream(lex);
RoleDefParser parser = new RoleDefParser(tokens);
lines = parser.file();
} catch (RecognitionException e) {
System.err
.println("[SCVM-RBAC] Error while parsing role/user file.");
e.printStackTrace();
}
// generate roles for result
if (lines != null) {
for (RoleDefLine line : lines) {
if (line instanceof RoleDef) {
final RoleDef def = (RoleDef) line;
// create (if necessary) and add role
Role role = Securebpmn2Factory.eINSTANCE
.createRole();
role.setName(def.getRoleName());
role.setId(UUID.randomUUID().toString());
roles.add(role);
// create and add users to role
for (String userName : def.getMembers()) {
User user = Securebpmn2Factory.eINSTANCE
.createUser();
user.setUserName(userName);
user.setId(userName.toLowerCase());
users.add(user);
user.getRoles().add(role);
role.getSubjects().add(user);
}
} else if (line instanceof RoleRel) {
hierarchy.add((RoleRel) line);
}
}
}
}
// TODO order hierarchy list
// assign new roles to users
for (RoleRel rel : hierarchy) {
// find roles
Role supRole = null;
Role subRole = null;
for (Role r : roles) {
if (r.getName().equals(rel.getSuperRole())
&& supRole == null)
supRole = r;
if (r.getName().equals(rel.getSubRole()) && subRole == null)
subRole = r;
}
// assign users to subroles
for (Subject s : supRole.getSubjects()) {
if (s instanceof User) {
User u = (User) s;
if (!u.getRoles().contains(subRole)) {
u.getRoles().add(subRole);
subRole.getSubjects().add(u);
}
}
}
}
}
if (roles.size() == 0) {
System.out
.println("[SCVM-RBAC] No roles or users provided, generating dummy roles and users.");
Role manager = Securebpmn2Factory.eINSTANCE.createRole();
manager.setName("Manager");
manager.setId(UUID.randomUUID().toString());
Role supervisor = Securebpmn2Factory.eINSTANCE.createRole();
supervisor.setName("Supervisor");
supervisor.setId(UUID.randomUUID().toString());
Role clerk = Securebpmn2Factory.eINSTANCE.createRole();
clerk.setId(UUID.randomUUID().toString());
clerk.setName("Clerk");
roles.add(manager);
roles.add(supervisor);
roles.add(clerk);
}
if (users.size() == 0) {
for (Role role : roles) {
User user1 = Securebpmn2Factory.eINSTANCE.createUser();
user1.setUserName("user1_" + role.getName());
user1.setId("user1_" + role.getName().toLowerCase());
user1.getRoles().add(role);
User user2 = Securebpmn2Factory.eINSTANCE.createUser();
user2.setUserName("user2_" + role.getName());
user2.setId("user2_" + role.getName().toLowerCase());
user2.getRoles().add(role);
}
}
// save users to diagram so that the editor won't crash loading a
// diagram with roles that reference to the users.
// unfortunately, the attributes of roles and users do not get loaded
// correctly when opening a .activiti file.
final List<User> usersToAdd = new ArrayList<User>();
for (User u : users) {
boolean isInDiagram = false;
for (EObject o : diagram.eResource().getContents()) {
if (o instanceof User) {
User my_user = (User) o;
if (my_user.getId() != null
&& my_user.getId().equals(u.getId())) {
isInDiagram = true;
break;
}
}
}
if (!isInDiagram) {
usersToAdd.add(u);
}
}
TransactionalEditingDomain editingDomain = TransactionUtil
.getEditingDomain(diagram);
if (!usersToAdd.isEmpty()) { // should fix aslan generation bug with automated role generation
ActivitiUiUtil.runModelChange(new Runnable() {
public void run() {
for (User u : usersToAdd) {
diagram.eResource().getContents().add(u);
}
}
}, editingDomain, "User management");
}
}
/**
* Reads a file from disk and writes its contents to a String.
*
* @param filePath
* The path to the file.
* @return The contents of the file.
* @throws IOException
* Errors that occur accessing the file.
*/
public static String readFileAsString(String filePath) throws IOException {
byte[] buffer = new byte[(int) new File(filePath).length()];
BufferedInputStream f = null;
try {
f = new BufferedInputStream(new FileInputStream(filePath));
f.read(buffer);
} finally {
if (f != null)
try {
f.close();
} catch (IOException ignored) {
}
}
return new String(buffer);
}
}

View File

@ -0,0 +1,63 @@
/* Copyright 2012-2015 SAP SE
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package eu.aniketos.securebpmn.validation;
/**
* A class representing the access of a process variable.
*
*
*/
public class ProcVarAccess {
private String name;
private int location;
private boolean write;
public ProcVarAccess(String name, int location, boolean write) {
this.name = name;
this.location = location;
this.write = write;
}
/**
* Returns the name of the process variable.
*
* @return The name of the process variable.
*/
public String getName() {
return name;
}
/**
* Returns the location, where the access of the variable occurs. This is
* only applicable for accesses found in Java implementations.
*
* @return The location as the position in the file.
*/
public int getLocation() {
return location;
}
/**
* Returns if the access is of type read or write
*
* @return true if the type is write, false if it is read.
*/
public boolean isWrite() {
return write;
}
}

View File

@ -0,0 +1,129 @@
/* Copyright 2012-2015 SAP SE
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package eu.aniketos.securebpmn.validation;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.ImportDeclaration;
import org.eclipse.jdt.core.dom.MethodInvocation;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.StringLiteral;
/**
* Eclipse Java AST visitor class for checking if a certain process variable is
* accessed.
*
*
*/
public class ProcVarCheckASTVisitor extends ASTVisitor {
private List<String> delegateExecVars;
private List<Integer> locations;
private String procVar;
private boolean importFound;
/**
* Default constructor.
*
* @param procVar
* The name of the process variable that should be checked.
* @param locations
* A List where the locations of the accesses will be written to.
*/
public ProcVarCheckASTVisitor(String procVar, List<Integer> locations) {
this.delegateExecVars = new ArrayList<String>();
this.locations = locations;
this.procVar = procVar;
this.importFound = false;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.
* ImportDeclaration)
*/
@Override
public boolean visit(ImportDeclaration node) {
String imp = node.getName().toString();
if (imp.equals("org.activiti.engine.delegate.DelegateExecution")
|| imp.equals("org.activiti.engine.delegate.*")
|| imp.equals("org.activiti.engine.*")
|| imp.equals("org.activiti.*"))
importFound = true;
return super.visit(node);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.
* SingleVariableDeclaration)
*/
@Override
public boolean visit(SingleVariableDeclaration node) {
if (importFound
&& node.getType().toString().equals("DelegateExecution")) {
delegateExecVars.add(node.getName().toString());
}
return super.visit(node);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.
* MethodInvocation)
*/
@Override
public boolean visit(MethodInvocation node) {
String methodName = node.getName().toString();
if (methodName.equals("getVariable")
|| methodName.equals("setVariable")) {
// check if expression is of class
// org.activiti.engine.delegate.DelegateExecution
Expression expr = node.getExpression();
if (expr instanceof SimpleName) {
if (!delegateExecVars.contains(((SimpleName) expr).toString()))
return super.visit(node);
}
// check if argument matches procVar
if (node.arguments().size() > 0) {
Object arg = node.arguments().get(0);
if (arg instanceof StringLiteral) {
if (arg.toString().equals("\"" + procVar + "\"")) {
locations.add(node.getStartPosition());
return false;
}
}
}
}
return super.visit(node);
}
}

View File

@ -0,0 +1,135 @@
/* Copyright 2012-2015 SAP SE
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package eu.aniketos.securebpmn.validation;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.ImportDeclaration;
import org.eclipse.jdt.core.dom.MethodInvocation;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.StringLiteral;
/**
* Eclipse Java AST visitor class for listing all process variables that are
* being accessed and the way in which they are accessed (read or write).
*
*
*/
public class ProcVarListASTVisitor extends ASTVisitor {
private List<String> delegateExecVars;
private List<ProcVarAccess> varAccess;
private boolean importFound;
/**
* Default constructor.
*
* @param varAccess
* The list where the found variable accesses will be saved to.
*/
public ProcVarListASTVisitor(List<ProcVarAccess> varAccess) {
this.delegateExecVars = new ArrayList<String>();
this.varAccess = varAccess;
this.importFound = false;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.
* ImportDeclaration)
*/
@Override
public boolean visit(ImportDeclaration node) {
String imp = node.getName().toString();
if (imp.equals("org.activiti.engine.delegate.DelegateExecution")
|| imp.equals("org.activiti.engine.delegate.*")
|| imp.equals("org.activiti.engine.*")
|| imp.equals("org.activiti.*"))
importFound = true;
return super.visit(node);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.
* SingleVariableDeclaration)
*/
@Override
public boolean visit(SingleVariableDeclaration node) {
if (importFound
&& node.getType().toString().equals("DelegateExecution")) {
delegateExecVars.add(node.getName().toString());
}
return super.visit(node);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.
* MethodInvocation)
*/
@Override
public boolean visit(MethodInvocation node) {
boolean read = false;
boolean write = false;
String methodName = node.getName().toString();
// check if expression is of class
// org.activiti.engine.delegate.DelegateExecution
Expression expr = node.getExpression();
if (expr instanceof SimpleName) {
if (!delegateExecVars.contains(((SimpleName) expr).toString()))
return super.visit(node);
}
if (methodName.equals("getVariable"))
read = true;
else if (methodName.equals("setVariable"))
write = true;
if (read || write) {
// check if argument matches procVar
if (node.arguments().size() > 0) {
Object arg = node.arguments().get(0);
if (arg instanceof StringLiteral) {
if (arg.toString().startsWith("\"")
&& arg.toString().endsWith("\"")) {
varAccess.add(new ProcVarAccess(arg.toString()
.substring(1, arg.toString().length() - 1),
node.getStartPosition(), write));
return false;
}
}
}
}
return super.visit(node);
}
}

View File

@ -0,0 +1,53 @@
/* Copyright 2012-2015 SAP SE
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package eu.aniketos.securebpmn.validation;
/**
* Contains some values used in the attack trace visualization.
*
*
*/
public final class SCVMValidationConstants {
// ASLan rule names
public static final String HUMAN_TASK_RULE_NAME = "h_taskExecution";
public static final String AUTOMATED_TASK_RULE_NAME = "atask_execution";
public static final String TASK_AUTHORIZATION_RULE_NAME = "authorizeTaskExecution";
public static final String GOAL_SOD_PREFIX = "sod_";
public static final String GOAL_BOD_PREFIX = "bod_";
// Highlighting colors
public static final int[] COLOR_HL_EXEC_FG = { 0, 255, 255 };
public static final int[] COLOR_HL_EXEC_BG = { 0, 230, 230 };
public static final int[] COLOR_HL_VIOL_FG = { 255, 0, 0 };
public static final int[] COLOR_HL_VIOL_BG = { 230, 0, 0 };
public static final int[] COLOR_HL_CLAIM_FG = { 0, 255, 0 };
public static final int[] COLOR_HL_CLAIM_BG = { 0, 230, 0 };
public static final int[] COLOR_HL_ASSIGN_FG = { 255, 0, 255 };
public static final int[] COLOR_HL_ASSIGN_BG = { 230, 0, 230 };
public static final int[] COLOR_HL_WORK_FG = { 0, 0, 255 };
public static final int[] COLOR_HL_WORK_BG = { 0, 0, 230 };
public static final int[] COLOR_DEF_SEQFLOW = { 0, 0, 0 };
private SCVMValidationConstants() {
}
}

View File

@ -0,0 +1,322 @@
/* Copyright 2012-2015 SAP SE
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package eu.aniketos.securebpmn.validation;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import org.activiti.designer.eclipse.common.ActivitiBPMNDiagramConstants;
import org.activiti.designer.eclipse.extension.export.ExportMarshaller;
import org.activiti.designer.eclipse.preferences.PreferencesUtil;
import org.activiti.designer.eclipse.util.ExtensionPointUtil;
import org.activiti.designer.util.preferences.Preferences;
import org.antlr.runtime.ANTLRStringStream;
import org.antlr.runtime.CommonTokenStream;
import org.antlr.runtime.RecognitionException;
import org.antlr.satmc.SatmcLexer;
import org.antlr.satmc.SatmcParser;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.emf.common.util.URI;
import org.eclipse.graphiti.mm.pictograms.Diagram;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.swt.widgets.Display;
import eu.aniketos.securebpmn.satmc.SatmcMessage;
import eu.aniketos.securebpmn.util.DialogUtil;
import eu.aniketos.securebpmn.util.SecurityUtil;
import eu.avantssar.satmc.SATMCPortType;
import eu.avantssar.satmc.SATMCService;
/**
* A Runnable that generates the ASLan file and analyzes it via SATMC for a
* given Diagram.
*
*
*/
public class ValidateAslanRunnable implements IRunnableWithProgress {
private Diagram diagram;
private boolean localValidation;
private SatmcMessage result;
/**
* Default constructor.
*
* @param diagram
* The diagram that should be validated.
* @param result
* The variable where the result is saved to.
* @param localValidation
* true if the local SATMC binary should be used, false for the
* SATMC web service.
*/
public ValidateAslanRunnable(Diagram diagram, SatmcMessage result,
boolean localValidation) {
this.diagram = diagram;
this.localValidation = localValidation;
this.result = result;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.jface.operation.IRunnableWithProgress#run(org.eclipse.core
* .runtime.IProgressMonitor)
*/
@Override
public void run(IProgressMonitor monitor) throws InvocationTargetException,
InterruptedException {
try {
monitor.beginTask("Validating security properties", 10);
// get uri
URI uri = diagram.eResource().getURI();
URI platformUri = uri.trimFragment();
platformUri = platformUri.trimFileExtension();
platformUri = platformUri.appendFileExtension("aslan");
monitor.worked(1);
// generate file
monitor.subTask("Generating ASLan");
final ExportMarshaller marshaller = ExtensionPointUtil
.getExportMarshaller(ActivitiBPMNDiagramConstants.ASLAN_MARSHALLER_NAME);
if (marshaller == null) {
throw new IllegalArgumentException(
"Unable to invoke ExportMarshaller with name "
+ ActivitiBPMNDiagramConstants.ASLAN_MARSHALLER_NAME);
}
final IProgressMonitor subMonitor = new SubProgressMonitor(monitor,
2);
try {
marshaller.marshallDiagram(diagram, subMonitor);
} finally {
subMonitor.done();
}
// check for problem markers
final IWorkspace workspace = ResourcesPlugin.getWorkspace();
final IFile diagramFile = workspace.getRoot().getFile(
new Path(diagram.eResource().getURI()
.toPlatformString(true)));
try {
if (diagramFile
.findMarkers(ExportMarshaller.MARKER_ID, true, 3).length > 0) {
Display.getDefault().syncExec(new Runnable() {
public void run() {
DialogUtil
.openMessageDialog(
"Export problems present",
"The diagram contains export problems! This might result in an outdated analysis result, you should fix the problems and run the analysis again.",
DialogUtil.WARNING);
}
});
}
} catch (CoreException e1) {
e1.printStackTrace();
}
// file validation
String res = "";
final String fileUri = getResource(platformUri).getLocation()
.toString();
if (localValidation) {
// call local binary and pass file path
monitor.subTask("Executing local SATMC binary");
try {
String pathToBinary = PreferencesUtil
.getStringPreference(Preferences.PATH_TO_SATMC_BINARY);
File workingDir = null;
if (pathToBinary.length() == 0) {
pathToBinary = "satmc";
} else {
int lastIndex = pathToBinary.lastIndexOf(System
.getProperty("file.separator"));
if (lastIndex > 0) {
workingDir = new File(pathToBinary.substring(0,
lastIndex));
}
}
String[] cmd = { pathToBinary, fileUri, "--max=80",
"--mutex=0"
};
res = cmdExec(cmd, workingDir);
} catch (IOException e) {
Display.getDefault().syncExec(new Runnable() {
public void run() {
DialogUtil
.openMessageDialog(
"SATMC Execution Error",
"Could not run SATMC. Try providing the full path to the executable file in the Activiti preferences.",
DialogUtil.ERROR);
}
});
e.printStackTrace();
monitor.worked(7);
monitor.done();
return;
}
} else {
// read file as string and call web service
monitor.subTask("Calling SATMC web service");
try {
final SATMCService service = new SATMCService();
final SATMCPortType port = service.getSATMCSOAPPort();
res = port.validate(SecurityUtil.readFileAsString(fileUri),
80, false, true, false, "aslan", "");
} catch (Exception e) {
Display.getDefault().syncExec(new Runnable() {
public void run() {
DialogUtil
.openMessageDialog(
"SATMC Execution Error",
"Could not reach SATMC web service. Check your internet connection and, if you are behind a firewall, try setting the proxy in Eclipse to \"manual\".",
DialogUtil.ERROR);
}
});
e.printStackTrace();
monitor.worked(7);
monitor.done();
return;
}
}
monitor.worked(4);
// save result to file
monitor.subTask("Saving results");
InputStream content = new ByteArrayInputStream(res.getBytes());
URI platformResultUri = uri.trimFragment();
platformResultUri = platformResultUri.trimFileExtension();
platformResultUri = platformResultUri.appendFileExtension("result");
final IFile newfile = workspace.getRoot().getFile(
new Path(platformResultUri.toPlatformString(true)));
try {
if (newfile.exists()) {
newfile.setContents(content, true, true,
new NullProgressMonitor());
} else {
newfile.create(content, true, new NullProgressMonitor());
}
newfile.refreshLocal(IResource.DEPTH_INFINITE, null);
} catch (CoreException e) {
e.printStackTrace();
}
monitor.worked(1);
// parse results
monitor.subTask("Parsing results");
try {
SatmcLexer lex = new SatmcLexer(new ANTLRStringStream(res));
CommonTokenStream tokens = new CommonTokenStream(lex);
SatmcParser parser = new SatmcParser(tokens);
SatmcMessage parserResult = parser.output();
// copy result to result variable
result.summary = parserResult.summary;
result.goal = parserResult.goal;
result.trace = parserResult.trace;
result.cfs = parserResult.cfs;
} catch (RecognitionException e) {
e.printStackTrace();
}
monitor.worked(2);
} finally {
monitor.done();
}
}
/**
* Retrieves the Resource for a given URI.
*
* @param resourceURI
* The URI for the Resource.
* @return The found Resource.
*/
private IResource getResource(URI resourceURI) {
final IResource fileResource = ResourcesPlugin.getWorkspace().getRoot()
.findMember(resourceURI.toPlatformString(true));
IResource result = null;
if (fileResource != null && fileResource.exists()) {
result = ResourcesPlugin.getWorkspace().getRoot()
.findMember(resourceURI.toPlatformString(true));
}
return result;
}
/**
* Executes a command on the local machine.
*
* @param cmdLine
* The command that should be executed.
* @param dir
* The working directory in which the command should be executed.
* @return The standard output of the command.
* @throws IOException
* Errors that occur during the execution.
*/
private String cmdExec(String[] cmdLine, File dir) throws IOException {
String line;
String output = "";
Process p = Runtime.getRuntime().exec(cmdLine, null, dir);
BufferedReader input = new BufferedReader(new InputStreamReader(
p.getInputStream()));
while ((line = input.readLine()) != null) {
output += (line + '\n');
}
input.close();
return output;
}
}

View File

@ -0,0 +1,64 @@
/* Copyright 2012-2015 SAP SE
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package eu.aniketos.securebpmn.validation.view;
import org.eclipse.swt.widgets.Display;
import eu.aniketos.securebpmn.visualization.rbac.RbacVisualization;
/**
* Controls the automated playback of the attack trace visualization.
*
*
*/
public class PlayerControlRunnable implements Runnable {
private ValidationView view;
/**
* Default constructor.
*
* @param view
* The view that is used.
*/
public PlayerControlRunnable(ValidationView view) {
this.view = view;
}
/*
* (non-Javadoc)
*
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
try {
while (RbacVisualization.getInstance().getPlayer().hasNextStep()) {
RbacVisualization.getInstance().getPlayer().nextStep();
// set status text
Display.getDefault().syncExec(new Runnable() {
public void run() {
view.setStatusText(RbacVisualization.getInstance()
.getPlayer().getStepInfo());
}
});
Thread.sleep(2000);
}
} catch (InterruptedException e) {
}
}
}

View File

@ -0,0 +1,233 @@
/* Copyright 2012-2015 SAP SE
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package eu.aniketos.securebpmn.validation.view;
import java.lang.Thread.State;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.part.ViewPart;
import eu.aniketos.securebpmn.visualization.rbac.RbacVisualization;
/**
* The Eclipse view controlling the attack trace visualization.
*
*
*/
public class ValidationView extends ViewPart {
private Text statusText;
private Thread playerThread;
/**
* Default constructor.
*/
public ValidationView() {
// beware: gets called before full ui is loaded if view was left open on
// exit!
statusText = null;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets
* .Composite)
*/
@Override
public void createPartControl(Composite parent) {
// check for validation result
if (!RbacVisualization.getInstance().isResultSet()) {
Label error = new Label(parent, SWT.NONE);
error.setText("No validation result present. Please close this view and run the validation via your preferred method.");
return;
}
GridLayout gridLayout = new GridLayout();
gridLayout.numColumns = 2;
parent.setLayout(gridLayout);
RowLayout buttonLayout = new RowLayout();
buttonLayout.marginLeft = 5;
buttonLayout.marginTop = 5;
buttonLayout.marginRight = 5;
buttonLayout.marginBottom = 5;
Group buttonGroup = new Group(parent, SWT.SHADOW_IN);
buttonGroup.setLayout(buttonLayout);
buttonGroup.setText("visualization controls");
buttonGroup.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false,
false, 1, 1));
Button first = new Button(buttonGroup, SWT.PUSH);
first.setText("first step");
first.addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent event) {
RbacVisualization.getInstance().getPlayer().firstStep();
statusText.setText(RbacVisualization.getInstance().getPlayer()
.getStepInfo());
if (playerThread != null) {
playerThread.interrupt();
playerThread = null;
}
}
public void widgetDefaultSelected(SelectionEvent event) {
}
});
Button previous = new Button(buttonGroup, SWT.PUSH);
previous.setText("previous step");
previous.addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent event) {
RbacVisualization.getInstance().getPlayer().previousStep();
statusText.setText(RbacVisualization.getInstance().getPlayer()
.getStepInfo());
if (playerThread != null) {
playerThread.interrupt();
playerThread = null;
}
}
public void widgetDefaultSelected(SelectionEvent event) {
}
});
Button playPause = new Button(buttonGroup, SWT.PUSH);
playPause.setText("play/pause trace");
playPause.addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent event) {
if (playerThread == null
|| playerThread.getState() == State.TERMINATED) {
playerThread = new Thread(new PlayerControlRunnable(
ValidationView.this));
playerThread.start();
} else {
playerThread.interrupt();
playerThread = null;
}
}
public void widgetDefaultSelected(SelectionEvent event) {
}
});
Button next = new Button(buttonGroup, SWT.PUSH);
next.setText("next step");
next.addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent event) {
RbacVisualization.getInstance().getPlayer().nextStep();
statusText.setText(RbacVisualization.getInstance().getPlayer()
.getStepInfo());
if (playerThread != null) {
playerThread.interrupt();
playerThread = null;
}
}
public void widgetDefaultSelected(SelectionEvent event) {
}
});
Button last = new Button(buttonGroup, SWT.PUSH);
last.setText("last step");
last.addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent event) {
RbacVisualization.getInstance().getPlayer().lastStep();
statusText.setText(RbacVisualization.getInstance().getPlayer()
.getStepInfo());
if (playerThread != null) {
playerThread.interrupt();
playerThread = null;
}
}
public void widgetDefaultSelected(SelectionEvent event) {
}
});
Group attackGroup = new Group(parent, SWT.SHADOW_IN);
attackGroup.setLayout(new FillLayout());
attackGroup.setText("attack trace");
attackGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true,
1, 2));
Text attackText = new Text(attackGroup, SWT.MULTI | SWT.V_SCROLL
| SWT.H_SCROLL);
// attackText.setText(SatmcVisualization.getInstance().getFilteredAttackTrace());
attackText.setText(RbacVisualization.getInstance().getAttackTrace());
attackText.setEditable(false);
Group statusGroup = new Group(parent, SWT.SHADOW_IN);
statusGroup.setLayout(new FillLayout());
statusGroup.setText("step information");
statusGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, true,
1, 1));
statusText = new Text(statusGroup, SWT.MULTI | SWT.V_SCROLL
| SWT.H_SCROLL);
statusText.setText(RbacVisualization.getInstance().getPlayer()
.getStepInfo());
statusText.setEditable(false);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.part.WorkbenchPart#setFocus()
*/
@Override
public void setFocus() {
if(statusText != null){
statusText.setFocus();
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.ui.part.WorkbenchPart#dispose()
*/
@Override
public void dispose() {
RbacVisualization.getInstance().reset();
super.dispose();
}
/**
* Sets the text of the status text field. Note, that you must use
* Display.getDefault().syncExec if you are calling this method from a
* different thread.
*
* @param text
*/
public void setStatusText(String text) {
if (statusText != null)
statusText.setText(text);
}
}

View File

@ -0,0 +1,28 @@
/* Copyright 2012-2015 SAP SE
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package eu.aniketos.securebpmn.visualization;
/**
* The Different types of actions that can are represented in the attack trace
* visualization.
*
*
*/
public enum ActionType {
ASSIGN, CLAIM, EXECUTE, VIOLATION, WORKFLOW
}

View File

@ -0,0 +1,474 @@
/* Copyright 2012-2015 SAP SE
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package eu.aniketos.securebpmn.visualization;
import java.util.List;
import org.eclipse.bpmn2.Event;
import org.eclipse.bpmn2.Gateway;
import org.eclipse.bpmn2.SequenceFlow;
import org.eclipse.bpmn2.Task;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.graphiti.mm.algorithms.Ellipse;
import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm;
import org.eclipse.graphiti.mm.algorithms.Polygon;
import org.eclipse.graphiti.mm.algorithms.Rectangle;
import org.eclipse.graphiti.mm.algorithms.RoundedRectangle;
import org.eclipse.graphiti.mm.pictograms.Anchor;
import org.eclipse.graphiti.mm.pictograms.Connection;
import org.eclipse.graphiti.mm.pictograms.ContainerShape;
import org.eclipse.graphiti.mm.pictograms.Diagram;
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
import org.eclipse.graphiti.mm.pictograms.Shape;
import org.eclipse.graphiti.services.Graphiti;
import org.eclipse.graphiti.services.IGaService;
import org.eclipse.graphiti.services.ILinkService;
import org.eclipse.securebpmn2.BindingOfDuty;
import org.eclipse.securebpmn2.SeparationOfDuty;
import eu.aniketos.securebpmn.validation.SCVMValidationConstants;
/**
* A runnable for highlighting the elements in on step of the attack trace.
*
*
*/
public class HighlightVisualizationElementsRunnable implements Runnable {
private Diagram diagram;
private List<VisualizationElement> elements;
private boolean revert;
private IGaService gaService;
/**
* Default constructor.
*
* @param diagram
* The diagram in which the visualization takes place.
* @param elements
* The List of elements that should be highlighted.
* @param revert
* true if the reverse visualization should be applied, false if
* not.
*/
public HighlightVisualizationElementsRunnable(Diagram diagram,
List<VisualizationElement> elements, boolean revert) {
this.diagram = diagram;
this.elements = elements;
this.revert = revert;
this.gaService = Graphiti.getGaService();
}
/*
* (non-Javadoc)
*
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
for (VisualizationElement element : elements) {
if (element.getbObject() instanceof Task) {
highlightTask(element.getpElement(), element.getAction());
} else if (element.getbObject() instanceof Gateway) {
highlightGateway(element.getpElement(), element.getAction());
} else if (element.getbObject() instanceof Event) {
highlightEvent(element.getpElement(), element.getAction());
} else if (element.getbObject() instanceof SeparationOfDuty
|| element.getbObject() instanceof BindingOfDuty) {
highlightTaskLikeElement(element.getpElement(),
element.getAction(), false);
}
}
}
/**
* Performs the highlighting for a Task.
*
* @param pElement
* The corresponding PictogramElement.
* @param action
* The action that defines the highlighting.
*/
private void highlightTask(PictogramElement pElement, ActionType action) {
highlightTaskLikeElement(pElement, action, true);
}
/**
* Performs the highlighting for a Task and the incoming SequenceFlow.
*
* @param pElement
* The corresponding PictogramElement.
* @param action
* The action that defines the highlighting.
* @param withSequenceFlow
* true if the incoming SequenceFlow should be highlighted, false
* if not.
*/
private void highlightTaskLikeElement(PictogramElement pElement,
ActionType action, boolean withSequenceFlow) {
// highlighting for tasks
ContainerShape cs = (ContainerShape) pElement;
Shape removeShape = null;
int overlayWidth = 105;
int overlayHeight = 55;
if (cs.getGraphicsAlgorithm() instanceof Rectangle) {
Rectangle rect = (Rectangle) cs.getGraphicsAlgorithm();
overlayWidth = rect.getWidth();
overlayHeight = rect.getHeight();
}
for (Shape shape : cs.getChildren()) {
final GraphicsAlgorithm ga = shape.getGraphicsAlgorithm();
if (ga instanceof RoundedRectangle) {
// overlay already exists, remove it
removeShape = shape;
}
}
if (removeShape != null)
// finally remove overlay
cs.getChildren().remove(removeShape);
if (!revert) {
// create overlay
final Shape s = Graphiti.getPeCreateService()
.createShape(cs, false);
final RoundedRectangle rr = gaService.createRoundedRectangle(s, 20,
20);
rr.setLineVisible(true);
rr.setFilled(true);
rr.setLineWidth(2);
rr.setTransparency(0.7);
if (action == ActionType.VIOLATION) {
rr.setForeground(gaService.manageColor(diagram,
SCVMValidationConstants.COLOR_HL_VIOL_FG[0],
SCVMValidationConstants.COLOR_HL_VIOL_FG[1],
SCVMValidationConstants.COLOR_HL_VIOL_FG[2]));
rr.setBackground(gaService.manageColor(diagram,
SCVMValidationConstants.COLOR_HL_VIOL_BG[0],
SCVMValidationConstants.COLOR_HL_VIOL_BG[1],
SCVMValidationConstants.COLOR_HL_VIOL_BG[2]));
} else if (action == ActionType.EXECUTE) {
rr.setForeground(gaService.manageColor(diagram,
SCVMValidationConstants.COLOR_HL_EXEC_FG[0],
SCVMValidationConstants.COLOR_HL_EXEC_FG[1],
SCVMValidationConstants.COLOR_HL_EXEC_FG[2]));
rr.setBackground(gaService.manageColor(diagram,
SCVMValidationConstants.COLOR_HL_EXEC_BG[0],
SCVMValidationConstants.COLOR_HL_EXEC_BG[1],
SCVMValidationConstants.COLOR_HL_EXEC_BG[2]));
} else if (action == ActionType.CLAIM) {
rr.setForeground(gaService.manageColor(diagram,
SCVMValidationConstants.COLOR_HL_CLAIM_FG[0],
SCVMValidationConstants.COLOR_HL_CLAIM_FG[1],
SCVMValidationConstants.COLOR_HL_CLAIM_FG[2]));
rr.setBackground(gaService.manageColor(diagram,
SCVMValidationConstants.COLOR_HL_CLAIM_BG[0],
SCVMValidationConstants.COLOR_HL_CLAIM_BG[1],
SCVMValidationConstants.COLOR_HL_CLAIM_BG[2]));
} else if (action == ActionType.ASSIGN) {
rr.setForeground(gaService.manageColor(diagram,
SCVMValidationConstants.COLOR_HL_ASSIGN_FG[0],
SCVMValidationConstants.COLOR_HL_ASSIGN_FG[1],
SCVMValidationConstants.COLOR_HL_ASSIGN_FG[2]));
rr.setBackground(gaService.manageColor(diagram,
SCVMValidationConstants.COLOR_HL_ASSIGN_BG[0],
SCVMValidationConstants.COLOR_HL_ASSIGN_BG[1],
SCVMValidationConstants.COLOR_HL_ASSIGN_BG[2]));
} else if (action == ActionType.WORKFLOW) {
rr.setForeground(gaService.manageColor(diagram,
SCVMValidationConstants.COLOR_HL_WORK_FG[0],
SCVMValidationConstants.COLOR_HL_WORK_FG[1],
SCVMValidationConstants.COLOR_HL_WORK_FG[2]));
rr.setBackground(gaService.manageColor(diagram,
SCVMValidationConstants.COLOR_HL_WORK_BG[0],
SCVMValidationConstants.COLOR_HL_WORK_BG[1],
SCVMValidationConstants.COLOR_HL_WORK_BG[2]));
}
gaService.setLocationAndSize(rr, 0, 0, overlayWidth, overlayHeight);
}
if (withSequenceFlow)
highlightIncomingSequenceFlow(cs);
}
/**
* Performs the highlighting for a Gateway.
*
* @param pElement
* The corresponding PictogramElement.
* @param action
* The action that defines the highlighting.
*/
private void highlightGateway(PictogramElement pElement, ActionType action) {
// highlighting for gateways
ContainerShape cs = (ContainerShape) pElement;
Shape removeShape = null;
for (Shape shape : cs.getChildren()) {
final GraphicsAlgorithm ga = shape.getGraphicsAlgorithm();
if (ga instanceof Polygon) {
// overlay already exists, remove it
removeShape = shape;
}
}
if (removeShape != null)
// finally remove overlay
cs.getChildren().remove(removeShape);
if (!revert) {
// create overlay
final Shape s = Graphiti.getPeCreateService()
.createShape(cs, false);
int xy[] = new int[] { 0, 20, 20, 0, 40, 20, 20, 40, 0, 20 };
final Polygon p = gaService.createPolygon(s, xy);
p.setLineVisible(true);
p.setFilled(true);
p.setLineWidth(2);
p.setTransparency(0.7);
if (action == ActionType.VIOLATION) {
p.setForeground(gaService.manageColor(diagram,
SCVMValidationConstants.COLOR_HL_VIOL_FG[0],
SCVMValidationConstants.COLOR_HL_VIOL_FG[1],
SCVMValidationConstants.COLOR_HL_VIOL_FG[2]));
p.setBackground(gaService.manageColor(diagram,
SCVMValidationConstants.COLOR_HL_VIOL_BG[0],
SCVMValidationConstants.COLOR_HL_VIOL_BG[1],
SCVMValidationConstants.COLOR_HL_VIOL_BG[2]));
} else if (action == ActionType.EXECUTE) {
p.setForeground(gaService.manageColor(diagram,
SCVMValidationConstants.COLOR_HL_EXEC_FG[0],
SCVMValidationConstants.COLOR_HL_EXEC_FG[1],
SCVMValidationConstants.COLOR_HL_EXEC_FG[2]));
p.setBackground(gaService.manageColor(diagram,
SCVMValidationConstants.COLOR_HL_EXEC_BG[0],
SCVMValidationConstants.COLOR_HL_EXEC_BG[1],
SCVMValidationConstants.COLOR_HL_EXEC_BG[2]));
} else if (action == ActionType.CLAIM) {
p.setForeground(gaService.manageColor(diagram,
SCVMValidationConstants.COLOR_HL_CLAIM_FG[0],
SCVMValidationConstants.COLOR_HL_CLAIM_FG[1],
SCVMValidationConstants.COLOR_HL_CLAIM_FG[2]));
p.setBackground(gaService.manageColor(diagram,
SCVMValidationConstants.COLOR_HL_CLAIM_BG[0],
SCVMValidationConstants.COLOR_HL_CLAIM_BG[1],
SCVMValidationConstants.COLOR_HL_CLAIM_BG[2]));
} else if (action == ActionType.ASSIGN) {
p.setForeground(gaService.manageColor(diagram,
SCVMValidationConstants.COLOR_HL_ASSIGN_FG[0],
SCVMValidationConstants.COLOR_HL_ASSIGN_FG[1],
SCVMValidationConstants.COLOR_HL_ASSIGN_FG[2]));
p.setBackground(gaService.manageColor(diagram,
SCVMValidationConstants.COLOR_HL_ASSIGN_BG[0],
SCVMValidationConstants.COLOR_HL_ASSIGN_BG[1],
SCVMValidationConstants.COLOR_HL_ASSIGN_BG[2]));
} else if (action == ActionType.WORKFLOW) {
p.setForeground(gaService.manageColor(diagram,
SCVMValidationConstants.COLOR_HL_WORK_FG[0],
SCVMValidationConstants.COLOR_HL_WORK_FG[1],
SCVMValidationConstants.COLOR_HL_WORK_FG[2]));
p.setBackground(gaService.manageColor(diagram,
SCVMValidationConstants.COLOR_HL_WORK_BG[0],
SCVMValidationConstants.COLOR_HL_WORK_BG[1],
SCVMValidationConstants.COLOR_HL_WORK_BG[2]));
}
gaService.setLocationAndSize(p, 0, 0, 40, 40);
}
highlightIncomingSequenceFlow(cs);
}
/**
* Performs the highlighting for an Event.
*
* @param pElement
* The corresponding PictogramElement.
* @param action
* The action that defines the highlighting.
*/
private void highlightEvent(PictogramElement pElement, ActionType action) {
// highlighting for events
ContainerShape cs = (ContainerShape) pElement;
Shape removeShape = null;
for (Shape shape : cs.getChildren()) {
final GraphicsAlgorithm ga = shape.getGraphicsAlgorithm();
if (ga instanceof Ellipse) {
// overlay already exists, remove it
removeShape = shape;
}
}
if (removeShape != null)
// finally remove overlay
cs.getChildren().remove(removeShape);
if (!revert) {
// create overlay
final Shape s = Graphiti.getPeCreateService()
.createShape(cs, false);
final Ellipse e = gaService.createEllipse(s);
e.setLineVisible(true);
e.setFilled(true);
e.setLineWidth(4);
e.setTransparency(0.7);
if (action == ActionType.VIOLATION) {
e.setForeground(gaService.manageColor(diagram,
SCVMValidationConstants.COLOR_HL_VIOL_FG[0],
SCVMValidationConstants.COLOR_HL_VIOL_FG[1],
SCVMValidationConstants.COLOR_HL_VIOL_FG[2]));
e.setBackground(gaService.manageColor(diagram,
SCVMValidationConstants.COLOR_HL_VIOL_BG[0],
SCVMValidationConstants.COLOR_HL_VIOL_BG[1],
SCVMValidationConstants.COLOR_HL_VIOL_BG[2]));
} else if (action == ActionType.EXECUTE) {
e.setForeground(gaService.manageColor(diagram,
SCVMValidationConstants.COLOR_HL_EXEC_FG[0],
SCVMValidationConstants.COLOR_HL_EXEC_FG[1],
SCVMValidationConstants.COLOR_HL_EXEC_FG[2]));
e.setBackground(gaService.manageColor(diagram,
SCVMValidationConstants.COLOR_HL_EXEC_BG[0],
SCVMValidationConstants.COLOR_HL_EXEC_BG[1],
SCVMValidationConstants.COLOR_HL_EXEC_BG[2]));
} else if (action == ActionType.CLAIM) {
e.setForeground(gaService.manageColor(diagram,
SCVMValidationConstants.COLOR_HL_CLAIM_FG[0],
SCVMValidationConstants.COLOR_HL_CLAIM_FG[1],
SCVMValidationConstants.COLOR_HL_CLAIM_FG[2]));
e.setBackground(gaService.manageColor(diagram,
SCVMValidationConstants.COLOR_HL_CLAIM_BG[0],
SCVMValidationConstants.COLOR_HL_CLAIM_BG[1],
SCVMValidationConstants.COLOR_HL_CLAIM_BG[2]));
} else if (action == ActionType.ASSIGN) {
e.setForeground(gaService.manageColor(diagram,
SCVMValidationConstants.COLOR_HL_ASSIGN_FG[0],
SCVMValidationConstants.COLOR_HL_ASSIGN_FG[1],
SCVMValidationConstants.COLOR_HL_ASSIGN_FG[2]));
e.setBackground(gaService.manageColor(diagram,
SCVMValidationConstants.COLOR_HL_ASSIGN_BG[0],
SCVMValidationConstants.COLOR_HL_ASSIGN_BG[1],
SCVMValidationConstants.COLOR_HL_ASSIGN_BG[2]));
} else if (action == ActionType.WORKFLOW) {
e.setForeground(gaService.manageColor(diagram,
SCVMValidationConstants.COLOR_HL_WORK_FG[0],
SCVMValidationConstants.COLOR_HL_WORK_FG[1],
SCVMValidationConstants.COLOR_HL_WORK_FG[2]));
e.setBackground(gaService.manageColor(diagram,
SCVMValidationConstants.COLOR_HL_WORK_BG[0],
SCVMValidationConstants.COLOR_HL_WORK_BG[1],
SCVMValidationConstants.COLOR_HL_WORK_BG[2]));
}
gaService.setLocationAndSize(e, 0, 0, 35, 35);
}
highlightIncomingSequenceFlow(cs);
}
/**
* Performs the highlighting for a SequenceFlow.
*
* @param cs
* The corresponding ContainerShape.
*/
private void highlightIncomingSequenceFlow(ContainerShape cs) {
// highlighting of incoming sequence flow
ILinkService linkService = Graphiti.getLinkService();
// loop over incoming connections
for (Anchor anchor : cs.getAnchors()) {
for (Connection connection : anchor.getIncomingConnections()) {
EObject linkedObject = linkService
.getBusinessObjectForLinkedPictogramElement(connection);
if (!(linkedObject instanceof SequenceFlow)) {
continue;
}
// determine if connection comes from highlighted element
boolean sourceIsHighlighted = false;
PictogramElement sourcePictogramElement = connection.getStart()
.getParent().getGraphicsAlgorithm()
.getPictogramElement();
if (sourcePictogramElement instanceof ContainerShape) {
for (Shape shape : ((ContainerShape) sourcePictogramElement)
.getChildren()) {
final GraphicsAlgorithm ga = shape
.getGraphicsAlgorithm();
if (ga instanceof RoundedRectangle
|| ga instanceof Ellipse
|| ga instanceof Polygon) {
sourceIsHighlighted = true;
break;
}
}
}
if (sourceIsHighlighted) {
GraphicsAlgorithm connectionGA = connection
.getGraphicsAlgorithm();
if (revert) {
// remove highlighting of sequenceFlow
connectionGA.setLineWidth(1);
connectionGA.setForeground(gaService.manageColor(
diagram,
SCVMValidationConstants.COLOR_DEF_SEQFLOW[0],
SCVMValidationConstants.COLOR_DEF_SEQFLOW[1],
SCVMValidationConstants.COLOR_DEF_SEQFLOW[2]));
} else {
// highlight sequenceFlow
// TODO make highlighting more beautiful (overlay?)
connectionGA.setLineWidth(2);
connectionGA.setForeground(gaService.manageColor(
diagram,
SCVMValidationConstants.COLOR_HL_WORK_FG[0],
SCVMValidationConstants.COLOR_HL_WORK_FG[1],
SCVMValidationConstants.COLOR_HL_WORK_FG[2]));
}
}
}
}
}
}

View File

@ -0,0 +1,126 @@
/* Copyright 2012-2015 SAP SE
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package eu.aniketos.securebpmn.visualization;
import org.eclipse.bpmn2.FlowElement;
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
/**
* A Class representing an element for visualization.
*
*
*/
public class VisualizationElement {
private String id;
private FlowElement bObject;
private PictogramElement pElement;
private ActionType action;
/**
* Default constructor.
*
* @param id
* The ID of the element.
* @param action
* The type of action the element is involved in. Used for
* determining the type of highlighting.
*/
public VisualizationElement(String id, ActionType action) {
this.id = id;
this.action = action;
this.bObject = null;
this.pElement = null;
}
/**
* Default constructor.
*
* @param id
* The ID of the element.
* @param bObject
* The BO of the element.
* @param pElement
* The PE of the element.
* @param action
* The type of action the element is involved in. Used for
* determining the type of highlighting.
*/
public VisualizationElement(String id, FlowElement bObject,
PictogramElement pElement, ActionType action) {
this.id = id;
this.bObject = bObject;
this.pElement = pElement;
this.action = action;
}
/**
* Retrieves the BusinessObject of the element.
*
* @return The corresponding BO.
*/
public FlowElement getbObject() {
return bObject;
}
/**
* Sets the BusinessObject of the element.
*
* @param bObject
* The BO to be set.
*/
public void setbObject(FlowElement bObject) {
this.bObject = bObject;
}
/**
* Retrieves the PictogramElement of the element.
*
* @return The corresponding PE.
*/
public PictogramElement getpElement() {
return pElement;
}
/**
* Sets the PictogramElement of the element.
*
* @param pElement
* The PE to be set.
*/
public void setpElement(PictogramElement pElement) {
this.pElement = pElement;
}
/**
* Retrieves the ID of the element.
*
* @return The corresponding ID.
*/
public String getId() {
return id;
}
/**
* Retrieves the type of action the element is involved in.
*
* @return The corresponding ActionType.
*/
public ActionType getAction() {
return action;
}
}

View File

@ -0,0 +1,199 @@
/* Copyright 2012-2015 SAP SE
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package eu.aniketos.securebpmn.visualization.rbac;
import java.util.ArrayList;
import java.util.List;
import org.activiti.designer.util.eclipse.ActivitiUiUtil;
import org.eclipse.bpmn2.Task;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.emf.transaction.util.TransactionUtil;
import org.eclipse.graphiti.mm.pictograms.Diagram;
import eu.aniketos.securebpmn.visualization.ActionType;
import eu.aniketos.securebpmn.visualization.HighlightVisualizationElementsRunnable;
import eu.aniketos.securebpmn.visualization.VisualizationElement;
/**
* Player class that controls the attack trace visualization.
*
*
*/
public class AttackTracePlayer {
private Diagram diagram;
private TransactionalEditingDomain domain;
private List<AttackTraceStep> traceList;
private int pos;
/**
* Default constructor.
*
* @param diagram
* The diagram in which the visualization takes place.
* @param traceList
* The conditioned List of steps in the attack trace.
*/
public AttackTracePlayer(Diagram diagram, List<AttackTraceStep> traceList) {
this.diagram = diagram;
this.traceList = traceList;
pos = 0;
domain = TransactionUtil.getEditingDomain(diagram);
highlightShapes(traceList.get(0).getInvolvedElements(), false);
}
/**
* Returns if the attack trace has a previous step.
*
* @return true if it has a previous step, false if not.
*/
public boolean hasPreviousStep() {
return pos > 0;
}
/**
* Returns if the attack trace has a next step.
*
* @return true if it has a next step, false if not.
*/
public boolean hasNextStep() {
return pos < traceList.size() - 1;
}
/**
* Advances the visualization to the first step in the attack trace.
*/
public void firstStep() {
// revert all shapes from current to first element
while (hasPreviousStep()) {
previousStep();
}
}
/**
* Rewinds the visualization to the last step in the attack trace.
*/
public void lastStep() {
// change all shapes from current to last element
while (hasNextStep()) {
nextStep();
}
}
/**
* Advances the visualization to the next step.
*
* @return The new position in the attack trace.
*/
public int nextStep() {
// highlight shapes in next step
if (hasNextStep()) {
pos++;
highlightShapes(traceList.get(pos).getInvolvedElements(), false);
}
return pos;
}
/**
* Rewinds the visualization to the previous step. Notice that this
* implementation does not support the visualization of assign/claim attacks
* at the moment.
*
* @return The new position in the attack trace.
*/
public int previousStep() {
// revert shapes of current step
if (hasPreviousStep()) {
// revert changes done in current step
final List<VisualizationElement> currentElements = traceList.get(
pos).getInvolvedElements();
highlightShapes(currentElements, true);
pos--;
// check if previous step was violation & highlight again
final List<VisualizationElement> previousElements = traceList.get(
pos).getInvolvedElements();
List<VisualizationElement> tasksToHighlight = new ArrayList<VisualizationElement>();
for (VisualizationElement element : currentElements) {
// no violation
if (!(element.getAction() == ActionType.VIOLATION))
continue;
if (element.getbObject() instanceof Task) {
tasksToHighlight.add(new VisualizationElement(element
.getId(), element.getbObject(), element
.getpElement(), ActionType.EXECUTE));
}
}
// check if previos step was claim & highlight again
boolean previousClaim = false;
for (VisualizationElement element : previousElements) {
if (element.getAction() == ActionType.CLAIM) {
previousClaim = true;
break;
}
}
if (previousClaim) {
highlightShapes(previousElements, false);
}
if (tasksToHighlight.size() > 0) {
highlightShapes(tasksToHighlight, false);
}
}
return pos;
}
/**
* Retrieves the information text of the current step in the attack trace.
*
* @return The information text of the current step.
*/
public String getStepInfo() {
return traceList.get(pos).getDescription();
}
/**
* Performs the highlighting of the elements provided.
*
* @param elements
* The elements to be highlighted.
* @param revert
* true if the highlighting should be reversed, false if not.
*/
private void highlightShapes(List<VisualizationElement> elements,
boolean revert) {
ActivitiUiUtil.runModelChange(
new HighlightVisualizationElementsRunnable(diagram, elements,
revert), domain, "SCVM RBAC Visualization");
}
/**
* Method that must be called before the visualization view is disposed.
* Resets the Diagram colors.
*/
public void prepareDisposal() {
firstStep();
highlightShapes(traceList.get(0).getInvolvedElements(), true);
}
}

View File

@ -0,0 +1,79 @@
/* Copyright 2012-2015 SAP SE
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package eu.aniketos.securebpmn.visualization.rbac;
import java.util.ArrayList;
import java.util.List;
import eu.aniketos.securebpmn.visualization.VisualizationElement;
/**
* Represents a step in the attack trace visualization.
*
*
*/
public class AttackTraceStep {
private List<VisualizationElement> involvedElements;
private String description;
/**
* Default constructor.
*/
public AttackTraceStep() {
this.involvedElements = new ArrayList<VisualizationElement>();
this.description = "";
}
/**
* Retrieves the description text of the step.
*
* @return The description text.
*/
public String getDescription() {
return description;
}
/**
* Sets the description text of the step.
*
* @param description
* The new description to be set.
*/
public void setDescription(String description) {
this.description = description;
}
/**
* Retrieves the VisualizationElements involved in the step.
*
* @return The List of involved VisualizationElements.
*/
public List<VisualizationElement> getInvolvedElements() {
return involvedElements;
}
/**
* Adds a new VisualizationElement to the involved elements in the step.
*
* @param element
* The new VisualizationElement to be added.
*/
public void addInvolvedElement(VisualizationElement element) {
this.involvedElements.add(element);
}
}

View File

@ -0,0 +1,199 @@
/* Copyright 2012-2015 SAP SE
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package eu.aniketos.securebpmn.visualization.rbac;
import eu.aniketos.securebpmn.satmc.SatmcFunction;
import eu.aniketos.securebpmn.satmc.SatmcMessage;
import eu.aniketos.securebpmn.satmc.SatmcTraceStep;
import eu.aniketos.securebpmn.satmc.Summary;
import eu.aniketos.securebpmn.validation.SCVMValidationConstants;
/**
* Singleton Class that holds the parsed SATMC result and the player class for
* automated attack trace visualization playback.
*
*
*/
public class RbacVisualization {
private static RbacVisualization _instance;
private SatmcMessage parsedResult;
private AttackTracePlayer player;
/**
* Default constructor.
*/
private RbacVisualization() {
parsedResult = null;
player = null;
}
/**
* Retrieves the singleton instance.
*
* @return The class instance.
*/
public static synchronized RbacVisualization getInstance() {
if (_instance == null) {
_instance = new RbacVisualization();
}
return _instance;
}
/**
* Returns if the parsed result is set.
*
* @return true if it is set, false if not.
*/
public boolean isResultSet() {
return parsedResult == null ? false : true;
}
/**
* Sets the parsed result.
*
* @param result
* The new result to be set.
*/
public void setResult(SatmcMessage result) {
parsedResult = result;
}
/**
* Returns if the visualization is currently running.
*
* @return true if it is running, false if not.
*/
public boolean isVisualizationRunning() {
return player == null ? false : true;
}
/**
* Sets the player for automated playback.
*
* @param player
* The new player to be set.
*/
public void setPlayer(AttackTracePlayer player) {
this.player = player;
}
/**
* Retrieves the current player.
*
* @return The current player.
*/
public AttackTracePlayer getPlayer() {
return this.player;
}
/**
* Retrieves the rules of the attack trace as a String.
*
* @return The attack trace as a String.
*/
public String getAttackTrace() {
if (parsedResult == null)
return "No result present!";
String result = "";
int stepCount = 1;
for (SatmcTraceStep sts : parsedResult.trace) {
if (sts.rules.toString().length() < 3)
continue;
result += stepCount + ": " + sts.rules.toString() + "\n";
stepCount++;
}
return result;
}
/**
* Retrieves a filtered attack trace of the parsed result as a String. Only
* rules for taks claiming and execution are included.
*
* @return The filtered attack trace as a String.
*/
public String getFilteredAttackTrace() {
if (parsedResult == null)
return "No result present!";
String result = "";
int stepCount = 1;
for (SatmcTraceStep sts : parsedResult.trace) {
boolean first = true;
String resultLine = "";
for (SatmcFunction rule : sts.rules) {
if (rule.name
.equals(SCVMValidationConstants.HUMAN_TASK_RULE_NAME)
|| rule.name
.equals(SCVMValidationConstants.AUTOMATED_TASK_RULE_NAME)
|| rule.name
.equals(SCVMValidationConstants.TASK_AUTHORIZATION_RULE_NAME)) {
if (first) {
resultLine += stepCount + ": ";
first = false;
} else {
resultLine += ", ";
}
resultLine += rule.toString();
}
}
if (resultLine.length() > 0) {
result += resultLine + "\n";
stepCount++;
}
}
return result;
}
/**
* Retrieves the violated goal as a String.
*
* @return The violated goal as a string.
*/
public String getViolatedGoal() {
if (parsedResult == null
|| parsedResult.summary != Summary.ATTACK_FOUND) {
return "";
} else {
return parsedResult.goal.toString();
}
}
/**
* Resets the class: Disposes the player and deletes the result.
*/
public void reset() {
if (player != null)
player.prepareDisposal();
player = null;
parsedResult = null;
}
}

View File

@ -0,0 +1,64 @@
package eu.avantssar.satmc;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
/**
* This class was generated by the JAX-WS RI.
* JAX-WS RI 2.1.6 in JDK 6
* Generated source version: 2.1
*
*/
@WebService(name = "SATMCPortType", targetNamespace = "http://avantssar.eu/satmc/")
@SOAPBinding(style = SOAPBinding.Style.RPC)
public interface SATMCPortType {
/**
*
* @param stepCompression
* @param mutex
* @param asLanSpec
* @param max
* @param outputFormat
* @param otherOptions
* @param exec
* @return
* returns java.lang.String
*/
@WebMethod(action = "http://avantssar.eu/satmc/validate")
@WebResult(name = "counterexample", partName = "counterexample")
public String validate(
@WebParam(name = "ASLanSpec", partName = "ASLanSpec")
String asLanSpec,
@WebParam(name = "max", partName = "max")
int max,
@WebParam(name = "mutex", partName = "mutex")
boolean mutex,
@WebParam(name = "stepCompression", partName = "stepCompression")
boolean stepCompression,
@WebParam(name = "exec", partName = "exec")
boolean exec,
@WebParam(name = "outputFormat", partName = "outputFormat")
String outputFormat,
@WebParam(name = "otherOptions", partName = "otherOptions")
String otherOptions);
/**
*
* @param request
* @return
* returns java.lang.String
*/
@WebMethod(action = "http://avantssar.eu/satmc/version")
@WebResult(name = "info", partName = "info")
public String version(
@WebParam(name = "request", partName = "request")
String request);
}

View File

@ -0,0 +1,71 @@
package eu.avantssar.satmc;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.logging.Logger;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import javax.xml.ws.WebEndpoint;
import javax.xml.ws.WebServiceClient;
import javax.xml.ws.WebServiceFeature;
/**
* This class was generated by the JAX-WS RI.
* JAX-WS RI 2.1.6 in JDK 6
* Generated source version: 2.1
*
*/
@WebServiceClient(name = "SATMCService", targetNamespace = "http://avantssar.eu/satmc/", wsdlLocation = "http://satmc.ai.dist.unige.it/avantssar/service/satmc/?wsdl")
public class SATMCService
extends Service
{
private final static URL SATMCSERVICE_WSDL_LOCATION;
private final static Logger logger = Logger.getLogger(eu.avantssar.satmc.SATMCService.class.getName());
static {
URL url = null;
try {
URL baseUrl;
baseUrl = eu.avantssar.satmc.SATMCService.class.getResource(".");
url = new URL(baseUrl, "http://satmc.ai.dist.unige.it/avantssar/service/satmc/?wsdl");
} catch (MalformedURLException e) {
logger.warning("Failed to create URL for the wsdl Location: 'http://satmc.ai.dist.unige.it/avantssar/service/satmc/?wsdl', retrying as a local file");
logger.warning(e.getMessage());
}
SATMCSERVICE_WSDL_LOCATION = url;
}
public SATMCService(URL wsdlLocation, QName serviceName) {
super(wsdlLocation, serviceName);
}
public SATMCService() {
super(SATMCSERVICE_WSDL_LOCATION, new QName("http://avantssar.eu/satmc/", "SATMCService"));
}
/**
*
* @return
* returns SATMCPortType
*/
@WebEndpoint(name = "SATMCSOAPPort")
public SATMCPortType getSATMCSOAPPort() {
return super.getPort(new QName("http://avantssar.eu/satmc/", "SATMCSOAPPort"), SATMCPortType.class);
}
/**
*
* @param features
* A list of {@link javax.xml.ws.WebServiceFeature} to configure on the proxy. Supported features not in the <code>features</code> parameter will have their default values.
* @return
* returns SATMCPortType
*/
@WebEndpoint(name = "SATMCSOAPPort")
public SATMCPortType getSATMCSOAPPort(WebServiceFeature... features) {
return super.getPort(new QName("http://avantssar.eu/satmc/", "SATMCSOAPPort"), SATMCPortType.class, features);
}
}

View File

@ -0,0 +1,64 @@
/* Copyright 2012-2015 SAP SE
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
grammar RoleDef;
tokens {
COLON=':';
COMMA=',';
GEQ='>';
}
@header {
package org.antlr.roledef;
import com.sap.research.st.aniketos.securebpmn.roles.*;
}
@lexer::header {package org.antlr.roledef;}
file returns [List<RoleDefLine> lines]
: {$lines = new ArrayList<RoleDefLine>();}
(ldef=line_def {$lines.add($ldef.def);} | lrel=line_rel {$lines.add($lrel.rel);} )* EOF
;
line_def returns [RoleDef def]
: name=string {$def = new RoleDef($name.text);} COLON fm=string {$def.addMember($fm.text);} (COMMA mm=string {$def.addMember($mm.text);} )*
;
line_rel returns [RoleRel rel]
: sup=string GEQ sub=string {$rel = new RoleRel($sup.text, $sub.text);}
;
string
: STR
;
STR
: ( 'a'..'z' | 'A'..'Z' | '0'..'9' | '_' | '-' )+
;
COMMENT
: '//' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;}
| '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;}
;
WS : ( ' '
| '\t'
| '\r'
| '\n'
) {$channel=HIDDEN;}
;

View File

@ -0,0 +1,214 @@
/* Copyright 2012-2015 SAP SE
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
grammar Satmc;
// This grammar supports only SATMC output of version 3.2.8 or higher.
tokens {
WARNING='% WARNING:';
ERROR='% ERROR:';
INPUT='INPUT';
SUMMARY='SUMMARY';
GOAL='GOAL:';
DETAILS='DETAILS';
VERSION='BACKEND SATMC VERSION';
COMMENTS='COMMENTS';
STAT='STATISTICS';
TRACE='TRACE:';
CLAUSES='CLAUSES:';
RULES='RULES:';
CFS='CLOSED_FINAL_STATE:';
O_PARENTHESIS='(';
C_PARENTHESIS=')';
O_BRACKET='[';
C_BRACKET=']';
O_BRACES='{';
C_BRACES='}';
COMMA=',';
PERCENT='% ';
}
@header {
package org.antlr.satmc;
import com.sap.research.st.aniketos.securebpmn.satmc.*;
}
@lexer::header {package org.antlr.satmc;}
output returns [SatmcMessage message]
: NEWLINE* ( NEWLINE section_warning )* ( error {$message = new SatmcMessage(Summary.ERROR, null, null, null);}
| s=result {$message = $s.message;}
) NEWLINE* EOF
|
;
error
: NEWLINE section_error
;
result returns [SatmcMessage message]
: line_input NEWLINE ls=line_summary NEWLINE NEWLINE? ( lg=line_goal NEWLINE NEWLINE )? section_details NEWLINE NEWLINE line_version NEWLINE NEWLINE section_comments? section_stat st=section_trace? lc=line_cfs?
{$message = new SatmcMessage($ls.res, $lg.res, $st.res, $lc.res);}
;
section_warning
: WARNING ( ( ~NEWLINE )+ NEWLINE )* NEWLINE
;
section_error
: ERROR ( ( ~NEWLINE )+ NEWLINE )* NEWLINE NEWLINE ( PERCENT ( ( ~NEWLINE )+ NEWLINE )* NEWLINE )?
;
line_input
: INPUT WS target WS?
;
line_summary returns [Summary res]
: SUMMARY WS sr=summary_result WS? {if ("ATTACK_FOUND".equals($sr.text)) {
$res = Summary.ATTACK_FOUND;
} else if ("NO_ATTACK_FOUND".equals($sr.text)) {
$res = Summary.NO_ATTACK_FOUND;
} else if ("INCONCLUSIVE".equals($sr.text)) {
$res = Summary.INCONCLUSIVE;
} else {
$res = Summary.UNKNOWN;
}
}
;
line_goal returns [SatmcFunction res]
: WS? GOAL WS f=function {$res = $f.res;} WS?
;
section_details
: line_details ( NEWLINE line_detail )*
;
line_details
: DETAILS WS?
;
line_detail
: WS? CONSTANT WS?
;
line_version
: VERSION WS VERSION_NR
;
section_comments
: COMMENTS WS? NEWLINE ( ( ~NEWLINE )+ NEWLINE )* NEWLINE
;
section_stat
: STAT WS ( ( ~NEWLINE )+ NEWLINE )* NEWLINE
;
section_trace returns [List<SatmcTraceStep> res]
: TRACE { $res = new ArrayList<SatmcTraceStep>(); } NEWLINE
( NUMBER {boolean rulesPresent = false;}
NEWLINE lc=line_clauses NEWLINE ( lr=line_rules {rulesPresent=true;}
NEWLINE )?
{if (rulesPresent)
$res.add(new SatmcTraceStep($lc.res, $lr.res));
else
$res.add(new SatmcTraceStep($lc.res, new ArrayList<SatmcFunction>()));}
)+
;
line_clauses returns [List<SatmcFunction> res]
: WS? CLAUSES fs=function_set { $res = $fs.res; }
;
line_rules returns [List<SatmcFunction> res]
: WS? RULES WS ( f=function { $res = new ArrayList<SatmcFunction>(); $res.add($f.res);}
| fs=function_set { $res = $fs.res; }
| fn=fname { $res = new ArrayList<SatmcFunction>();
$res.add(new SatmcFunction($fn.text, new ArrayList<SatmcFact>()));})
;
line_cfs returns [List<SatmcFunction> res]
: CFS NEWLINE fs=function_set { $res = $fs.res; }
;
target
: FILE
;
summary_result
: CONSTANT
;
function_set returns [List<SatmcFunction> res]
: O_BRACES WS { $res = new ArrayList<SatmcFunction>();
}
( f1=function { $res.add($f1.res);
}
( COMMA fn=function { $res.add($fn.res); } )* )? WS? C_BRACES
;
function returns [SatmcFunction res]
: fn=fname { $res = new SatmcFunction($fn.text, new ArrayList<SatmcFact>());
}
O_PARENTHESIS fv=fvar { $res.args.add($fv.res);
}
( COMMA fvl=fvar { $res.args.add($fvl.res);
}
)* C_PARENTHESIS
;
var
: FTEXT
| NUMBER
;
fname
: FTEXT
;
fvar returns [SatmcFact res]
: r1=var {$res = new SatmcVar($r1.text);}
| r2=function {$res = $r2.res;}
;
VERSION_NR
: '0'..'9' '.' '0'..'9' '.' '0'..'9' ( 'a'..'z' | 'A'..'Z' | '0'..'9' | '_' | O_PARENTHESIS | C_PARENTHESIS )*
;
CONSTANT
: ( 'A'..'Z' | '_' )+
;
NUMBER
: ( '0'..'9' )+
;
FTEXT
: ( 'a'..'z' | 'A'..'Z' | NUMBER |'_' )+
;
FILE
: ( 'a'..'z' | 'A'..'Z' | NUMBER | '.' )+
;
NEWLINE
: '\r'? '\n'
;
WS
: ( ' ' | '\t' )+
;

View File

@ -0,0 +1,515 @@
// $ANTLR 3.4 RoleDef.g 2012-03-27 12:55:40
package org.antlr.roledef;
import org.antlr.runtime.*;
import java.util.Stack;
import java.util.List;
import java.util.ArrayList;
@SuppressWarnings({"all", "warnings", "unchecked"})
public class RoleDefLexer extends Lexer {
public static final int EOF=-1;
public static final int COLON=4;
public static final int COMMA=5;
public static final int COMMENT=6;
public static final int GEQ=7;
public static final int STR=8;
public static final int WS=9;
// delegates
// delegators
public Lexer[] getDelegates() {
return new Lexer[] {};
}
public RoleDefLexer() {}
public RoleDefLexer(CharStream input) {
this(input, new RecognizerSharedState());
}
public RoleDefLexer(CharStream input, RecognizerSharedState state) {
super(input,state);
}
public String getGrammarFileName() { return "RoleDef.g"; }
// $ANTLR start "COLON"
public final void mCOLON() throws RecognitionException {
try {
int _type = COLON;
int _channel = DEFAULT_TOKEN_CHANNEL;
// RoleDef.g:4:7: ( ':' )
// RoleDef.g:4:9: ':'
{
match(':');
}
state.type = _type;
state.channel = _channel;
}
finally {
// do for sure before leaving
}
}
// $ANTLR end "COLON"
// $ANTLR start "COMMA"
public final void mCOMMA() throws RecognitionException {
try {
int _type = COMMA;
int _channel = DEFAULT_TOKEN_CHANNEL;
// RoleDef.g:5:7: ( ',' )
// RoleDef.g:5:9: ','
{
match(',');
}
state.type = _type;
state.channel = _channel;
}
finally {
// do for sure before leaving
}
}
// $ANTLR end "COMMA"
// $ANTLR start "GEQ"
public final void mGEQ() throws RecognitionException {
try {
int _type = GEQ;
int _channel = DEFAULT_TOKEN_CHANNEL;
// RoleDef.g:6:5: ( '>' )
// RoleDef.g:6:7: '>'
{
match('>');
}
state.type = _type;
state.channel = _channel;
}
finally {
// do for sure before leaving
}
}
// $ANTLR end "GEQ"
// $ANTLR start "STR"
public final void mSTR() throws RecognitionException {
try {
int _type = STR;
int _channel = DEFAULT_TOKEN_CHANNEL;
// RoleDef.g:35:5: ( ( 'a' .. 'z' | 'A' .. 'Z' | '0' .. '9' | '_' | '-' )+ )
// RoleDef.g:35:7: ( 'a' .. 'z' | 'A' .. 'Z' | '0' .. '9' | '_' | '-' )+
{
// RoleDef.g:35:7: ( 'a' .. 'z' | 'A' .. 'Z' | '0' .. '9' | '_' | '-' )+
int cnt1=0;
loop1:
do {
int alt1=2;
int LA1_0 = input.LA(1);
if ( (LA1_0=='-'||(LA1_0 >= '0' && LA1_0 <= '9')||(LA1_0 >= 'A' && LA1_0 <= 'Z')||LA1_0=='_'||(LA1_0 >= 'a' && LA1_0 <= 'z')) ) {
alt1=1;
}
switch (alt1) {
case 1 :
// RoleDef.g:
{
if ( input.LA(1)=='-'||(input.LA(1) >= '0' && input.LA(1) <= '9')||(input.LA(1) >= 'A' && input.LA(1) <= 'Z')||input.LA(1)=='_'||(input.LA(1) >= 'a' && input.LA(1) <= 'z') ) {
input.consume();
}
else {
MismatchedSetException mse = new MismatchedSetException(null,input);
recover(mse);
throw mse;
}
}
break;
default :
if ( cnt1 >= 1 ) break loop1;
EarlyExitException eee =
new EarlyExitException(1, input);
throw eee;
}
cnt1++;
} while (true);
}
state.type = _type;
state.channel = _channel;
}
finally {
// do for sure before leaving
}
}
// $ANTLR end "STR"
// $ANTLR start "COMMENT"
public final void mCOMMENT() throws RecognitionException {
try {
int _type = COMMENT;
int _channel = DEFAULT_TOKEN_CHANNEL;
// RoleDef.g:39:5: ( '//' (~ ( '\\n' | '\\r' ) )* ( '\\r' )? '\\n' | '/*' ( options {greedy=false; } : . )* '*/' )
int alt5=2;
int LA5_0 = input.LA(1);
if ( (LA5_0=='/') ) {
int LA5_1 = input.LA(2);
if ( (LA5_1=='/') ) {
alt5=1;
}
else if ( (LA5_1=='*') ) {
alt5=2;
}
else {
NoViableAltException nvae =
new NoViableAltException("", 5, 1, input);
throw nvae;
}
}
else {
NoViableAltException nvae =
new NoViableAltException("", 5, 0, input);
throw nvae;
}
switch (alt5) {
case 1 :
// RoleDef.g:39:9: '//' (~ ( '\\n' | '\\r' ) )* ( '\\r' )? '\\n'
{
match("//");
// RoleDef.g:39:14: (~ ( '\\n' | '\\r' ) )*
loop2:
do {
int alt2=2;
int LA2_0 = input.LA(1);
if ( ((LA2_0 >= '\u0000' && LA2_0 <= '\t')||(LA2_0 >= '\u000B' && LA2_0 <= '\f')||(LA2_0 >= '\u000E' && LA2_0 <= '\uFFFF')) ) {
alt2=1;
}
switch (alt2) {
case 1 :
// RoleDef.g:
{
if ( (input.LA(1) >= '\u0000' && input.LA(1) <= '\t')||(input.LA(1) >= '\u000B' && input.LA(1) <= '\f')||(input.LA(1) >= '\u000E' && input.LA(1) <= '\uFFFF') ) {
input.consume();
}
else {
MismatchedSetException mse = new MismatchedSetException(null,input);
recover(mse);
throw mse;
}
}
break;
default :
break loop2;
}
} while (true);
// RoleDef.g:39:28: ( '\\r' )?
int alt3=2;
int LA3_0 = input.LA(1);
if ( (LA3_0=='\r') ) {
alt3=1;
}
switch (alt3) {
case 1 :
// RoleDef.g:39:28: '\\r'
{
match('\r');
}
break;
}
match('\n');
_channel=HIDDEN;
}
break;
case 2 :
// RoleDef.g:40:9: '/*' ( options {greedy=false; } : . )* '*/'
{
match("/*");
// RoleDef.g:40:14: ( options {greedy=false; } : . )*
loop4:
do {
int alt4=2;
int LA4_0 = input.LA(1);
if ( (LA4_0=='*') ) {
int LA4_1 = input.LA(2);
if ( (LA4_1=='/') ) {
alt4=2;
}
else if ( ((LA4_1 >= '\u0000' && LA4_1 <= '.')||(LA4_1 >= '0' && LA4_1 <= '\uFFFF')) ) {
alt4=1;
}
}
else if ( ((LA4_0 >= '\u0000' && LA4_0 <= ')')||(LA4_0 >= '+' && LA4_0 <= '\uFFFF')) ) {
alt4=1;
}
switch (alt4) {
case 1 :
// RoleDef.g:40:42: .
{
matchAny();
}
break;
default :
break loop4;
}
} while (true);
match("*/");
_channel=HIDDEN;
}
break;
}
state.type = _type;
state.channel = _channel;
}
finally {
// do for sure before leaving
}
}
// $ANTLR end "COMMENT"
// $ANTLR start "WS"
public final void mWS() throws RecognitionException {
try {
int _type = WS;
int _channel = DEFAULT_TOKEN_CHANNEL;
// RoleDef.g:43:5: ( ( ' ' | '\\t' | '\\r' | '\\n' ) )
// RoleDef.g:43:9: ( ' ' | '\\t' | '\\r' | '\\n' )
{
if ( (input.LA(1) >= '\t' && input.LA(1) <= '\n')||input.LA(1)=='\r'||input.LA(1)==' ' ) {
input.consume();
}
else {
MismatchedSetException mse = new MismatchedSetException(null,input);
recover(mse);
throw mse;
}
_channel=HIDDEN;
}
state.type = _type;
state.channel = _channel;
}
finally {
// do for sure before leaving
}
}
// $ANTLR end "WS"
public void mTokens() throws RecognitionException {
// RoleDef.g:1:8: ( COLON | COMMA | GEQ | STR | COMMENT | WS )
int alt6=6;
switch ( input.LA(1) ) {
case ':':
{
alt6=1;
}
break;
case ',':
{
alt6=2;
}
break;
case '>':
{
alt6=3;
}
break;
case '-':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
case 'G':
case 'H':
case 'I':
case 'J':
case 'K':
case 'L':
case 'M':
case 'N':
case 'O':
case 'P':
case 'Q':
case 'R':
case 'S':
case 'T':
case 'U':
case 'V':
case 'W':
case 'X':
case 'Y':
case 'Z':
case '_':
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
case 'g':
case 'h':
case 'i':
case 'j':
case 'k':
case 'l':
case 'm':
case 'n':
case 'o':
case 'p':
case 'q':
case 'r':
case 's':
case 't':
case 'u':
case 'v':
case 'w':
case 'x':
case 'y':
case 'z':
{
alt6=4;
}
break;
case '/':
{
alt6=5;
}
break;
case '\t':
case '\n':
case '\r':
case ' ':
{
alt6=6;
}
break;
default:
NoViableAltException nvae =
new NoViableAltException("", 6, 0, input);
throw nvae;
}
switch (alt6) {
case 1 :
// RoleDef.g:1:10: COLON
{
mCOLON();
}
break;
case 2 :
// RoleDef.g:1:16: COMMA
{
mCOMMA();
}
break;
case 3 :
// RoleDef.g:1:22: GEQ
{
mGEQ();
}
break;
case 4 :
// RoleDef.g:1:26: STR
{
mSTR();
}
break;
case 5 :
// RoleDef.g:1:30: COMMENT
{
mCOMMENT();
}
break;
case 6 :
// RoleDef.g:1:38: WS
{
mWS();
}
break;
}
}
}

View File

@ -0,0 +1,323 @@
// $ANTLR 3.4 RoleDef.g 2012-03-27 12:55:40
package org.antlr.roledef;
import eu.aniketos.securebpmn.roles.*;
import org.antlr.runtime.*;
import java.util.Stack;
import java.util.List;
import java.util.ArrayList;
@SuppressWarnings({"all", "warnings", "unchecked"})
public class RoleDefParser extends Parser {
public static final String[] tokenNames = new String[] {
"<invalid>", "<EOR>", "<DOWN>", "<UP>", "COLON", "COMMA", "COMMENT", "GEQ", "STR", "WS"
};
public static final int EOF=-1;
public static final int COLON=4;
public static final int COMMA=5;
public static final int COMMENT=6;
public static final int GEQ=7;
public static final int STR=8;
public static final int WS=9;
// delegates
public Parser[] getDelegates() {
return new Parser[] {};
}
// delegators
public RoleDefParser(TokenStream input) {
this(input, new RecognizerSharedState());
}
public RoleDefParser(TokenStream input, RecognizerSharedState state) {
super(input, state);
}
public String[] getTokenNames() { return RoleDefParser.tokenNames; }
public String getGrammarFileName() { return "RoleDef.g"; }
// $ANTLR start "file"
// RoleDef.g:17:1: file returns [List<RoleDefLine> lines] : (ldef= line_def |lrel= line_rel )* EOF ;
public final List<RoleDefLine> file() throws RecognitionException {
List<RoleDefLine> lines = null;
RoleDef ldef =null;
RoleRel lrel =null;
try {
// RoleDef.g:18:5: ( (ldef= line_def |lrel= line_rel )* EOF )
// RoleDef.g:18:7: (ldef= line_def |lrel= line_rel )* EOF
{
lines = new ArrayList<RoleDefLine>();
// RoleDef.g:19:7: (ldef= line_def |lrel= line_rel )*
loop1:
do {
int alt1=3;
int LA1_0 = input.LA(1);
if ( (LA1_0==STR) ) {
int LA1_2 = input.LA(2);
if ( (LA1_2==COLON) ) {
alt1=1;
}
else if ( (LA1_2==GEQ) ) {
alt1=2;
}
}
switch (alt1) {
case 1 :
// RoleDef.g:19:8: ldef= line_def
{
pushFollow(FOLLOW_line_def_in_file68);
ldef=line_def();
state._fsp--;
lines.add(ldef);
}
break;
case 2 :
// RoleDef.g:19:49: lrel= line_rel
{
pushFollow(FOLLOW_line_rel_in_file76);
lrel=line_rel();
state._fsp--;
lines.add(lrel);
}
break;
default :
break loop1;
}
} while (true);
match(input,EOF,FOLLOW_EOF_in_file83);
}
}
catch (RecognitionException re) {
reportError(re);
recover(input,re);
}
finally {
// do for sure before leaving
}
return lines;
}
// $ANTLR end "file"
// $ANTLR start "line_def"
// RoleDef.g:22:1: line_def returns [RoleDef def] : name= string COLON fm= string ( COMMA mm= string )* ;
public final RoleDef line_def() throws RecognitionException {
RoleDef def = null;
RoleDefParser.string_return name =null;
RoleDefParser.string_return fm =null;
RoleDefParser.string_return mm =null;
try {
// RoleDef.g:23:5: (name= string COLON fm= string ( COMMA mm= string )* )
// RoleDef.g:23:7: name= string COLON fm= string ( COMMA mm= string )*
{
pushFollow(FOLLOW_string_in_line_def106);
name=string();
state._fsp--;
def = new RoleDef((name!=null?input.toString(name.start,name.stop):null));
match(input,COLON,FOLLOW_COLON_in_line_def110);
pushFollow(FOLLOW_string_in_line_def114);
fm=string();
state._fsp--;
def.addMember((fm!=null?input.toString(fm.start,fm.stop):null));
// RoleDef.g:23:97: ( COMMA mm= string )*
loop2:
do {
int alt2=2;
int LA2_0 = input.LA(1);
if ( (LA2_0==COMMA) ) {
alt2=1;
}
switch (alt2) {
case 1 :
// RoleDef.g:23:98: COMMA mm= string
{
match(input,COMMA,FOLLOW_COMMA_in_line_def119);
pushFollow(FOLLOW_string_in_line_def123);
mm=string();
state._fsp--;
def.addMember((mm!=null?input.toString(mm.start,mm.stop):null));
}
break;
default :
break loop2;
}
} while (true);
}
}
catch (RecognitionException re) {
reportError(re);
recover(input,re);
}
finally {
// do for sure before leaving
}
return def;
}
// $ANTLR end "line_def"
// $ANTLR start "line_rel"
// RoleDef.g:26:1: line_rel returns [RoleRel rel] : sup= string GEQ sub= string ;
public final RoleRel line_rel() throws RecognitionException {
RoleRel rel = null;
RoleDefParser.string_return sup =null;
RoleDefParser.string_return sub =null;
try {
// RoleDef.g:27:5: (sup= string GEQ sub= string )
// RoleDef.g:27:7: sup= string GEQ sub= string
{
pushFollow(FOLLOW_string_in_line_rel152);
sup=string();
state._fsp--;
match(input,GEQ,FOLLOW_GEQ_in_line_rel154);
pushFollow(FOLLOW_string_in_line_rel158);
sub=string();
state._fsp--;
rel = new RoleRel((sup!=null?input.toString(sup.start,sup.stop):null), (sub!=null?input.toString(sub.start,sub.stop):null));
}
}
catch (RecognitionException re) {
reportError(re);
recover(input,re);
}
finally {
// do for sure before leaving
}
return rel;
}
// $ANTLR end "line_rel"
public static class string_return extends ParserRuleReturnScope {
};
// $ANTLR start "string"
// RoleDef.g:30:1: string : STR ;
public final RoleDefParser.string_return string() throws RecognitionException {
RoleDefParser.string_return retval = new RoleDefParser.string_return();
retval.start = input.LT(1);
try {
// RoleDef.g:31:5: ( STR )
// RoleDef.g:31:7: STR
{
match(input,STR,FOLLOW_STR_in_string181);
}
retval.stop = input.LT(-1);
}
catch (RecognitionException re) {
reportError(re);
recover(input,re);
}
finally {
// do for sure before leaving
}
return retval;
}
// $ANTLR end "string"
// Delegated rules
public static final BitSet FOLLOW_line_def_in_file68 = new BitSet(new long[]{0x0000000000000100L});
public static final BitSet FOLLOW_line_rel_in_file76 = new BitSet(new long[]{0x0000000000000100L});
public static final BitSet FOLLOW_EOF_in_file83 = new BitSet(new long[]{0x0000000000000002L});
public static final BitSet FOLLOW_string_in_line_def106 = new BitSet(new long[]{0x0000000000000010L});
public static final BitSet FOLLOW_COLON_in_line_def110 = new BitSet(new long[]{0x0000000000000100L});
public static final BitSet FOLLOW_string_in_line_def114 = new BitSet(new long[]{0x0000000000000022L});
public static final BitSet FOLLOW_COMMA_in_line_def119 = new BitSet(new long[]{0x0000000000000100L});
public static final BitSet FOLLOW_string_in_line_def123 = new BitSet(new long[]{0x0000000000000022L});
public static final BitSet FOLLOW_string_in_line_rel152 = new BitSet(new long[]{0x0000000000000080L});
public static final BitSet FOLLOW_GEQ_in_line_rel154 = new BitSet(new long[]{0x0000000000000100L});
public static final BitSet FOLLOW_string_in_line_rel158 = new BitSet(new long[]{0x0000000000000002L});
public static final BitSet FOLLOW_STR_in_string181 = new BitSet(new long[]{0x0000000000000002L});
}

File diff suppressed because it is too large Load Diff