diff options
author | Eike Stepper | 2013-09-18 12:37:43 +0000 |
---|---|---|
committer | Eike Stepper | 2013-09-18 12:37:43 +0000 |
commit | 0a166de53ef098b48cf3a173de3342acfd8112ce (patch) | |
tree | f8e2872e3a8fc949236c5f52818156349c7d478f | |
parent | 81c63c354ef149525a864c386c6da3ae7d8ee5b0 (diff) | |
download | cdo-0a166de53ef098b48cf3a173de3342acfd8112ce.tar.gz cdo-0a166de53ef098b48cf3a173de3342acfd8112ce.tar.xz cdo-0a166de53ef098b48cf3a173de3342acfd8112ce.zip |
[417507] [Security] Bypass READ permission checks for the
CDOResourceNode.name attribute
https://bugs.eclipse.org/bugs/show_bug.cgi?id=417507
16 files changed, 178 insertions, 24 deletions
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/CDOModelUtil.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/CDOModelUtil.java index 1363eb3054..d8c3acd472 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/CDOModelUtil.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/model/CDOModelUtil.java @@ -209,6 +209,33 @@ public final class CDOModelUtil implements CDOModelConstants } /** + * @since 4.3 + */ + public static boolean isResourcePathFeature(EStructuralFeature eStructuralFeature) + { + if (CDOPackageRegistryImpl.SYSTEM_ELEMENTS[8] == eStructuralFeature) + { + return true; + } + + if (CDOPackageRegistryImpl.SYSTEM_ELEMENTS[9] == eStructuralFeature) + { + return true; + } + + if (isResourceNode(eStructuralFeature.eClass())) + { + String name = eStructuralFeature.getName(); + if (RESOURCE_NODE_FOLDER_REFERENCE.equals(name) || RESOURCE_NODE_NAME_ATTRIBUTE.equals(name)) + { + return true; + } + } + + return false; + } + + /** * @since 4.0 */ public static boolean isTypesPackage(EPackage ePackage) diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/security/NoPermissionException.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/security/NoPermissionException.java index 6a84531e4f..a6e074d4a6 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/security/NoPermissionException.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/security/NoPermissionException.java @@ -10,6 +10,10 @@ */ package org.eclipse.emf.cdo.common.security; +import org.eclipse.emf.cdo.common.revision.CDORevisionProvider; +import org.eclipse.emf.cdo.common.revision.CDORevisionUtil; +import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevision; + /** * A {@link SecurityException security exception} indicating the lack of permission required to do something. * @@ -22,9 +26,17 @@ public class NoPermissionException extends SecurityException private Object protectableObject; + /** + * @since 4.3 + */ + public NoPermissionException(Object protectableObject, CDORevisionProvider revisionProvider) + { + this(protectableObject, "No permission to access " + format(protectableObject, revisionProvider)); + } + public NoPermissionException(Object protectableObject) { - this(protectableObject, "No permission to access " + protectableObject); + this(protectableObject, (CDORevisionProvider)null); } public NoPermissionException(Object protectableObject, String message) @@ -37,4 +49,27 @@ public class NoPermissionException extends SecurityException { return protectableObject; } + + private static String format(Object object, CDORevisionProvider revisionProvider) + { + String result = object.toString(); + + if (object instanceof InternalCDORevision) + { + InternalCDORevision revision = (InternalCDORevision)object; + if (revision.isResourceNode()) + { + if (revisionProvider != null) + { + result += "(" + CDORevisionUtil.getResourceNodePath(revision, revisionProvider) + ")"; + } + else + { + result += "(" + revision.getResourceNodeName() + ")"; + } + } + } + + return result; + } } diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOPackageRegistryImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOPackageRegistryImpl.java index 0ec82d8828..223304e107 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOPackageRegistryImpl.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/model/CDOPackageRegistryImpl.java @@ -55,7 +55,7 @@ import java.util.Set; */ public class CDOPackageRegistryImpl extends EPackageRegistryImpl implements InternalCDOPackageRegistry { - public static final EModelElement[] SYSTEM_ELEMENTS = new EModelElement[8]; + public static final EModelElement[] SYSTEM_ELEMENTS = new EModelElement[10]; private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG, CDOPackageRegistryImpl.class); diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/BaseCDORevision.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/BaseCDORevision.java index e24c87c551..d9404f405a 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/BaseCDORevision.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/BaseCDORevision.java @@ -73,6 +73,8 @@ public abstract class BaseCDORevision extends AbstractCDORevision private static final PerfTracer WRITING = new PerfTracer(OM.PERF_REVISION_WRITING, BaseCDORevision.class); + private static final int RESOURCE_NODE_NAME_INDEX = 1; + private static final byte UNSET_OPCODE = 0; private static final byte SET_NULL_OPCODE = 1; @@ -156,7 +158,17 @@ public abstract class BaseCDORevision extends AbstractCDORevision byte flagBits = in.readByte(); // Don't set permissions into this.falgs before readValues() flagBits |= UNCHUNKED_FLAG; // First assume all lists are unchunked; may be revised below - if ((flagBits & PERMISSION_MASK) != CDOPermission.NONE.ordinal()) + if ((flagBits & PERMISSION_MASK) == CDOPermission.NONE.ordinal()) + { + if (getClassInfo().isResourceNode()) + { + clearValues(); + + String name = in.readString(); + doSetValue(RESOURCE_NODE_NAME_INDEX, name); + } + } + else { if (!readValues(in)) { @@ -225,7 +237,15 @@ public abstract class BaseCDORevision extends AbstractCDORevision CDOPermission permission = permissionProvider.getPermission(this, securityContext); out.writeByte(permission.getBits()); - if (permission != CDOPermission.NONE) + if (permission == CDOPermission.NONE) + { + if (getClassInfo().isResourceNode()) + { + String name = getResourceNodeName(); + out.writeString(name); + } + } + else { if (!isUnchunked() && referenceChunk != 0) { @@ -655,6 +675,8 @@ public abstract class BaseCDORevision extends AbstractCDORevision public Object getValue(EStructuralFeature feature) { + checkReadable(feature); + int featureIndex = getFeatureIndex(feature); return getValue(featureIndex); } @@ -683,6 +705,8 @@ public abstract class BaseCDORevision extends AbstractCDORevision public CDOList getList(EStructuralFeature feature, int size) { + checkReadable(feature); + int featureIndex = getFeatureIndex(feature); InternalCDOList list = (InternalCDOList)getValue(featureIndex); if (list == null && size != -1) @@ -735,6 +759,14 @@ public abstract class BaseCDORevision extends AbstractCDORevision } /** + * @since 4.3 + */ + public String getResourceNodeName() + { + return (String)doGetValue(RESOURCE_NODE_NAME_INDEX); + } + + /** * @since 4.1 */ public CDOPermission getPermission() @@ -801,7 +833,6 @@ public abstract class BaseCDORevision extends AbstractCDORevision protected Object getValue(int featureIndex) { - checkReadable(); return doGetValue(featureIndex); } @@ -856,8 +887,13 @@ public abstract class BaseCDORevision extends AbstractCDORevision } } - private void checkReadable() + private void checkReadable(EStructuralFeature feature) { + if (CDOModelUtil.isResourcePathFeature(feature)) + { + return; + } + if (!isReadable()) { throw new NoPermissionException(this); diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/DelegatingCDORevision.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/DelegatingCDORevision.java index 61c6325f4d..39ffd031db 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/DelegatingCDORevision.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/DelegatingCDORevision.java @@ -360,6 +360,14 @@ public abstract class DelegatingCDORevision implements InternalCDORevision } /** + * @since 4.3 + */ + public String getResourceNodeName() + { + return getDelegate().getResourceNodeName(); + } + + /** * @since 4.1 */ public CDOPermission getPermission() diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/InternalCDORevision.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/InternalCDORevision.java index 4f7e4bc341..727bcde0f0 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/InternalCDORevision.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/InternalCDORevision.java @@ -146,6 +146,11 @@ public interface InternalCDORevision extends CDORevision, CDORevisionData, CDORe public EStructuralFeature[] clearValues(); /** + * @since 4.3 + */ + public String getResourceNodeName(); + + /** * @since 4.1 */ public void setPermission(CDOPermission permission); diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/StubCDORevision.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/StubCDORevision.java index 8d864c8216..a0e1379aa5 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/StubCDORevision.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/spi/common/revision/StubCDORevision.java @@ -286,6 +286,14 @@ public class StubCDORevision extends AbstractCDORevision } /** + * @since 4.3 + */ + public String getResourceNodeName() + { + throw new UnsupportedOperationException(getExceptionMessage()); + } + + /** * @since 4.1 */ public CDOPermission getPermission() diff --git a/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/ResourceFilterImpl.java b/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/ResourceFilterImpl.java index ea4c3ca5e0..14822b3e95 100644 --- a/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/ResourceFilterImpl.java +++ b/plugins/org.eclipse.emf.cdo.security/src/org/eclipse/emf/cdo/security/impl/ResourceFilterImpl.java @@ -163,14 +163,14 @@ public class ResourceFilterImpl extends PermissionFilterImpl implements Resource String revisionPath = CDORevisionUtil.getResourceNodePath(revision, revisionProvider); String path = getPath(); - int length = revisionPath.length(); - if (length < path.length()) + int length = path.length(); + if (length > revisionPath.length()) { return false; } revisionPath = revisionPath.substring(0, length); - return revisionPath.equals(path); + return path.equals(revisionPath); } private boolean includesRegex(CDORevision revision, CDORevisionProvider revisionProvider) diff --git a/plugins/org.eclipse.emf.cdo.server.security/src/org/eclipse/emf/cdo/server/internal/security/SecurityManager.java b/plugins/org.eclipse.emf.cdo.server.security/src/org/eclipse/emf/cdo/server/internal/security/SecurityManager.java index 56a34600f3..39854b30a4 100644 --- a/plugins/org.eclipse.emf.cdo.server.security/src/org/eclipse/emf/cdo/server/internal/security/SecurityManager.java +++ b/plugins/org.eclipse.emf.cdo.server.security/src/org/eclipse/emf/cdo/server/internal/security/SecurityManager.java @@ -447,11 +447,13 @@ public class SecurityManager extends Lifecycle implements InternalSecurityManage CDOResource resource = transaction.createResource(realmPath); realm = createRealm(); resource.getContents().add(realm); + OM.LOG.info("Security realm created in " + realmPath); } else { CDOResource resource = transaction.getResource(realmPath); realm = (Realm)resource.getContents().get(0); + OM.LOG.info("Security realm loaded from " + realmPath); } initCommitHandlers(firstTime); @@ -527,7 +529,6 @@ public class SecurityManager extends Lifecycle implements InternalSecurityManage User adminUser = realm.addUser("Administrator", "0000"); adminUser.getGroups().add(adminsGroup); - OM.LOG.info("Security realm " + realmPath + " created"); return realm; } diff --git a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/TransactionCommitContext.java b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/TransactionCommitContext.java index efac9096a8..b209c09829 100644 --- a/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/TransactionCommitContext.java +++ b/plugins/org.eclipse.emf.cdo.server/src/org/eclipse/emf/cdo/internal/server/TransactionCommitContext.java @@ -1055,7 +1055,7 @@ public class TransactionCommitContext implements InternalCommitContext if (!dirtyObjects[i].isWritable()) { - throw new NoPermissionException(dirtyObjects[i]); + throw new NoPermissionException(dirtyObjects[i], this); } monitor.worked(); diff --git a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/ui/CDOItemProvider.java b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/ui/CDOItemProvider.java index a487670ea2..8b5d50d155 100644 --- a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/ui/CDOItemProvider.java +++ b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/ui/CDOItemProvider.java @@ -58,6 +58,7 @@ import org.eclipse.net4j.util.event.IListener; import org.eclipse.net4j.util.ui.views.ContainerItemProvider; import org.eclipse.net4j.util.ui.views.IElementFilter; +import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EPackage; import org.eclipse.jface.action.IMenuManager; @@ -176,7 +177,8 @@ public class CDOItemProvider extends ContainerItemProvider<IContainer<Object>> if (element instanceof CDOResourceFolder) { - return ((CDOResourceFolder)element).getNodes().toArray(); + EList<CDOResourceNode> result = CDOUtil.filterReadables(((CDOResourceFolder)element).getNodes()); + return result.toArray(); } return super.getChildren(element); diff --git a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/ui/widgets/SessionComposite.java b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/ui/widgets/SessionComposite.java index 9ffdcd061d..839c608ba7 100644 --- a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/ui/widgets/SessionComposite.java +++ b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/ui/widgets/SessionComposite.java @@ -176,16 +176,20 @@ public class SessionComposite extends Composite { StringBuilder builder = new StringBuilder(); builder.append(connectorDescription); - builder.append("?repositoryName="); //$NON-NLS-1$ - builder.append(repositoryName); - if (automaticRegistry) + if (connectorDescription.contains("?")) //$NON-NLS-1$ { - builder.append("&automaticPackageRegistry=true"); //$NON-NLS-1$ + builder.append("&"); //$NON-NLS-1$ + } + else + { + builder.append("?"); //$NON-NLS-1$ } + builder.append("repositoryName="); //$NON-NLS-1$ + builder.append(repositoryName); if (automaticRegistry) { - builder.append("&legacyModeDefault=true"); //$NON-NLS-1$ + builder.append("&automaticPackageRegistry=true"); //$NON-NLS-1$ } return builder.toString(); diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/CDOUtil.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/CDOUtil.java index 21a7141534..8405c00a42 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/CDOUtil.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/util/CDOUtil.java @@ -73,6 +73,7 @@ import org.eclipse.emf.spi.cdo.FSMUtil; import org.eclipse.emf.spi.cdo.InternalCDOObject; import org.eclipse.emf.spi.cdo.InternalCDOView; +import java.util.Collection; import java.util.Iterator; import java.util.Map; @@ -91,6 +92,8 @@ public final class CDOUtil CDOPackageRegistryImpl.SYSTEM_ELEMENTS[2] = EresourcePackage.eINSTANCE; CDOPackageRegistryImpl.SYSTEM_ELEMENTS[3] = EresourcePackage.eINSTANCE.getCDOResource(); CDOPackageRegistryImpl.SYSTEM_ELEMENTS[4] = EresourcePackage.eINSTANCE.getCDOResourceFolder(); + CDOPackageRegistryImpl.SYSTEM_ELEMENTS[8] = EresourcePackage.eINSTANCE.getCDOResourceNode_Folder(); + CDOPackageRegistryImpl.SYSTEM_ELEMENTS[9] = EresourcePackage.eINSTANCE.getCDOResourceNode_Name(); CDOPackageRegistryImpl.SYSTEM_ELEMENTS[5] = EtypesPackage.eINSTANCE; CDOPackageRegistryImpl.SYSTEM_ELEMENTS[6] = EtypesPackage.eINSTANCE.getBlob(); @@ -470,6 +473,24 @@ public final class CDOUtil } /** + * @since 4.3 + */ + public static <T extends EObject> EList<T> filterReadables(Collection<T> collection) + { + EList<T> result = new BasicEList<T>(); + for (T element : collection) + { + CDOObject object = getCDOObject(element); + if (object.cdoRevision().isReadable()) + { + result.add(element); + } + } + + return result; + } + + /** * @since 2.0 */ public static CDORevision getRevisionByVersion(CDOObject object, int version) diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java index 1385fabeae..143036a52d 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/session/CDOSessionImpl.java @@ -1082,6 +1082,11 @@ public abstract class CDOSessionImpl extends CDOTransactionContainerImpl impleme public String toString() { String name = repositoryInfo == null ? "?" : repositoryInfo.getName(); //$NON-NLS-1$ + if (userID != null && userID.length() != 0) + { + name = userID + "@" + name; + } + return MessageFormat.format("Session{0} [{1}]", sessionID, name); //$NON-NLS-1$ } diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/AbstractCDOView.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/AbstractCDOView.java index 4c114278ad..a58a571f29 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/AbstractCDOView.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/AbstractCDOView.java @@ -343,7 +343,7 @@ public abstract class AbstractCDOView extends CDOCommitHistoryProviderImpl<CDOOb public synchronized CDOResourceNode[] getElements() { CDOResource rootResource = getRootResource(); - EList<EObject> contents = rootResource.getContents(); + EList<EObject> contents = CDOUtil.filterReadables(rootResource.getContents()); List<CDOResourceNode> elements = new ArrayList<CDOResourceNode>(contents.size()); for (EObject object : contents) diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOStateMachine.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOStateMachine.java index 22d87db5e2..f99fd07ef2 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOStateMachine.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOStateMachine.java @@ -906,7 +906,7 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent InternalCDORevision cleanRevision = object.cdoRevision(); if (!cleanRevision.isWritable()) { - throw new NoPermissionException(cleanRevision); + throw new NoPermissionException(cleanRevision, transaction); } transaction.getCleanRevisions().put(object, cleanRevision); @@ -927,13 +927,14 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent { public void execute(InternalCDOObject object, CDOState state, CDOEvent event, Object featureDelta) { + InternalCDOTransaction transaction = object.cdoView().toTransaction(); + InternalCDORevision revision = object.cdoRevision(); if (!revision.isWritable()) { - throw new NoPermissionException(revision); + throw new NoPermissionException(revision, transaction); } - InternalCDOTransaction transaction = object.cdoView().toTransaction(); transaction.registerFeatureDelta(object, (CDOFeatureDelta)featureDelta); } } @@ -945,13 +946,14 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent { public void execute(InternalCDOObject object, CDOState state, CDOEvent event, Object featureDelta) { + InternalCDOTransaction transaction = object.cdoView().toTransaction(); + InternalCDORevision revision = object.cdoRevision(); if (!revision.isWritable()) { - throw new NoPermissionException(revision); + throw new NoPermissionException(revision, transaction); } - InternalCDOTransaction transaction = object.cdoView().toTransaction(); transaction.registerFeatureDelta(object, (CDOFeatureDelta)featureDelta); } } @@ -1114,7 +1116,7 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent if (forWrite && !revision.isWritable()) { - throw new NoPermissionException(revision); + throw new NoPermissionException(revision, view); } object.cdoInternalSetRevision(revision); |