Skip to content
Browse files

Merge branch 'team/storage/EUCA-2031' of git.eucalyptus-systems.com:e…

…ucalyptus into maint/3.2/security
  • Loading branch information...
2 parents 6b51882 + 41f1276 commit e958e60baf3e7ddd2b611d975fc80a05d5a36cae Neil Soman committed Mar 9, 2013
View
231 clc/modules/cluster-manager/src/main/java/com/eucalyptus/blockstorage/WalrusUtil.java
@@ -65,13 +65,11 @@
import java.io.ByteArrayInputStream;
import java.security.cert.X509Certificate;
-import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
import org.apache.log4j.Logger;
import org.w3c.dom.Document;
+
import com.eucalyptus.auth.Accounts;
import com.eucalyptus.auth.AuthException;
import com.eucalyptus.auth.principal.Certificate;
@@ -83,134 +81,129 @@
import com.eucalyptus.component.id.Eucalyptus;
import com.eucalyptus.component.id.Walrus;
import com.eucalyptus.context.Contexts;
-import com.eucalyptus.images.ImageInfo;
import com.eucalyptus.images.ImageUtil;
import com.eucalyptus.records.Logs;
import com.eucalyptus.util.EucalyptusCloudException;
import com.eucalyptus.util.FullName;
+import com.eucalyptus.util.XMLParser;
import com.eucalyptus.ws.client.ServiceDispatcher;
+
import edu.ucsb.eucalyptus.msgs.CacheImageType;
import edu.ucsb.eucalyptus.msgs.FlushCachedImageType;
import edu.ucsb.eucalyptus.msgs.GetBucketAccessControlPolicyResponseType;
import edu.ucsb.eucalyptus.msgs.GetBucketAccessControlPolicyType;
import edu.ucsb.eucalyptus.msgs.GetObjectResponseType;
import edu.ucsb.eucalyptus.msgs.GetObjectType;
import edu.ucsb.eucalyptus.msgs.RegisterImageType;
-import edu.ucsb.eucalyptus.util.XMLParser;
public class WalrusUtil {
- private static Logger LOG = Logger.getLogger( WalrusUtil.class );
-
- public static void triggerCaching( ImageMetadata.StaticDiskImage imgInfo ) {
- String[] parts = imgInfo.getManifestLocation( ).split( "/" );
- CacheImageType cache = new CacheImageType( ).regarding( Contexts.lookup( ).getRequest( ) );
- cache.setBucket( parts[0] );
- cache.setKey( parts[1] );
- ServiceDispatcher.lookupSingle( Components.lookup( Walrus.class ) ).dispatch( cache );
- }
-
- public static void invalidate( ImageMetadata.StaticDiskImage imgInfo ) {
- String[] parts = imgInfo.getManifestLocation( ).split( "/" );
- try {
- ServiceDispatcher.lookupSingle( Components.lookup( Walrus.class ) ).dispatch( new FlushCachedImageType( parts[0], parts[1] ) );
- } catch ( Exception e ) {}
- }
-
- public static Document getManifestData( FullName userName, String bucketName, String objectName ) throws EucalyptusCloudException {
- GetObjectResponseType reply = null;
- try {
- GetObjectType msg = new GetObjectType( bucketName, objectName, true, false, true );
-//TODO:GRZE:WTF.
-// User user = Accounts.lookupUserById( userName.getNamespace( ) );
-// msg.setUserId( user.getName( ) );
- msg.regarding( );
-// msg.setCorrelationId( Contexts.lookup( ).getRequest( ).getCorrelationId( ) );
-
- reply = ( GetObjectResponseType ) ServiceDispatcher.lookupSingle( Components.lookup( Walrus.class ) ).send( msg );
- } catch ( Exception e ) {
- throw new EucalyptusCloudException( "Failed to read manifest file: " + bucketName + "/" + objectName, e );
- }
-
- Document inputSource = null;
- try {
- DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance( );
- docFactory.setExpandEntityReferences(false);
- try {
- docFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
- } catch(ParserConfigurationException ex) {
- LOG.error(ex, ex);
- }
- DocumentBuilder builder = docFactory.newDocumentBuilder( );
- inputSource = builder.parse( new ByteArrayInputStream( Hashes.base64decode( reply.getBase64Data( ) ).getBytes( ) ) );//OMG:WTF:GRZE:what am i doing.
- } catch ( Exception e ) {
- throw new EucalyptusCloudException( "Failed to read manifest file: " + bucketName + "/" + objectName, e );
- }
- return inputSource;
- }
-
- public static GetBucketAccessControlPolicyResponseType getBucketAcl( RegisterImageType request, String[] imagePathParts ) throws EucalyptusCloudException {
- GetBucketAccessControlPolicyType getBukkitInfo = new GetBucketAccessControlPolicyType( ).regarding( request );
- if ( getBukkitInfo != null ) {
- getBukkitInfo.setBucket( imagePathParts[0] );
- GetBucketAccessControlPolicyResponseType reply = ( GetBucketAccessControlPolicyResponseType ) ServiceDispatcher.lookupSingle( Components.lookup( Walrus.class ) ).send( getBukkitInfo );
- return reply;
- }
- return null;
- }
-
- public static void verifyManifestIntegrity( User user, String imageLocation ) throws EucalyptusCloudException {
- if( true ) return;//TODO:GRZE:BUG:BUG
- String[] imagePathParts = imageLocation.split( "/" );
- GetObjectResponseType reply = null;
- GetObjectType msg = new GetObjectType( imagePathParts[0], imagePathParts[1], true, false, true ).regarding( );
- try {
- reply = ( GetObjectResponseType ) ServiceDispatcher.lookupSingle( Components.lookup( Walrus.class ) ).send( msg );
- if ( reply == null || reply.getBase64Data( ) == null ) {
- throw new EucalyptusCloudException( "No data: " + imageLocation );
- } else {
- Logs.exhaust( ).debug( "Got the manifest to verify: " );
- Logs.exhaust( ).debug( Hashes.base64decode( reply.getBase64Data( ) ) );
- if( checkManifest( user, reply.getBase64Data( ) ) ) {
- return;
- } else {
- throw new EucalyptusCloudException( "Failed to verify signature." );
- }
- }
- } catch ( EucalyptusCloudException e ) {
- LOG.error( e, e );
- LOG.debug( e );
- throw new EucalyptusCloudException( "Invalid manifest reference: " + imageLocation + " because of " + e.getMessage( ), e );
- }
- }
-
- private static boolean checkManifest( User user, String manifest ) throws EucalyptusCloudException {
- XMLParser parser = new XMLParser( Hashes.base64decode( manifest ) );
- String encryptedKey = parser.getValue( "//ec2_encrypted_key" );
- String encryptedIV = parser.getValue( "//ec2_encrypted_iv" );
- String signature = parser.getValue( "//signature" );
- String image = parser.getXML( "image" );
- String machineConfiguration = parser.getXML( "machine_configuration" );
- String pad = (machineConfiguration + image);
- try {
- for ( Certificate cert : user.getCertificates( ) ) {
- if ( cert != null && cert instanceof X509Certificate && ImageUtil.verifyManifestSignature( (X509Certificate) cert, signature, pad )) {
- return true;
- }
- }
- if ( ImageUtil.verifyManifestSignature( SystemCredentials.lookup(Eucalyptus.class).getCertificate(), signature, pad )) {
- return true;
- }
- for ( User u : Accounts.listAllUsers( ) ) {
- for ( Certificate cert : u.getCertificates( ) ) {
- if ( cert != null && cert instanceof X509Certificate && ImageUtil.verifyManifestSignature( (X509Certificate) cert, signature, pad )) {
- return true;
- }
- }
- }
- return false;
- } catch ( AuthException e ) {
- throw new EucalyptusCloudException( "Invalid Manifest: Failed to verify signature because of missing (deleted?) user certificate.", e );
- }
- }
-
+ private static Logger LOG = Logger.getLogger( WalrusUtil.class );
+
+ public static void triggerCaching( ImageMetadata.StaticDiskImage imgInfo ) {
+ String[] parts = imgInfo.getManifestLocation( ).split( "/" );
+ CacheImageType cache = new CacheImageType( ).regarding( Contexts.lookup( ).getRequest( ) );
+ cache.setBucket( parts[0] );
+ cache.setKey( parts[1] );
+ ServiceDispatcher.lookupSingle( Components.lookup( Walrus.class ) ).dispatch( cache );
+ }
+
+ public static void invalidate( ImageMetadata.StaticDiskImage imgInfo ) {
+ String[] parts = imgInfo.getManifestLocation( ).split( "/" );
+ try {
+ ServiceDispatcher.lookupSingle( Components.lookup( Walrus.class ) ).dispatch( new FlushCachedImageType( parts[0], parts[1] ) );
+ } catch ( Exception e ) {}
+ }
+
+ public static Document getManifestData( FullName userName, String bucketName, String objectName ) throws EucalyptusCloudException {
+ GetObjectResponseType reply = null;
+ try {
+ GetObjectType msg = new GetObjectType( bucketName, objectName, true, false, true );
+ //TODO:GRZE:WTF.
+ // User user = Accounts.lookupUserById( userName.getNamespace( ) );
+ // msg.setUserId( user.getName( ) );
+ msg.regarding( );
+ // msg.setCorrelationId( Contexts.lookup( ).getRequest( ).getCorrelationId( ) );
+
+ reply = ( GetObjectResponseType ) ServiceDispatcher.lookupSingle( Components.lookup( Walrus.class ) ).send( msg );
+ } catch ( Exception e ) {
+ throw new EucalyptusCloudException( "Failed to read manifest file: " + bucketName + "/" + objectName, e );
+ }
+
+ Document inputSource = null;
+ try {
+ DocumentBuilder builder = XMLParser.getDocBuilder();
+ if(builder != null) {
+ inputSource = builder.parse( new ByteArrayInputStream( Hashes.base64decode( reply.getBase64Data( ) ).getBytes( ) ) );//OMG:WTF:GRZE:what am i doing.
+ }
+ } catch ( Exception e ) {
+ throw new EucalyptusCloudException( "Failed to read manifest file: " + bucketName + "/" + objectName, e );
+ }
+ return inputSource;
+ }
+
+ public static GetBucketAccessControlPolicyResponseType getBucketAcl( RegisterImageType request, String[] imagePathParts ) throws EucalyptusCloudException {
+ GetBucketAccessControlPolicyType getBukkitInfo = new GetBucketAccessControlPolicyType( ).regarding( request );
+ if ( getBukkitInfo != null ) {
+ getBukkitInfo.setBucket( imagePathParts[0] );
+ GetBucketAccessControlPolicyResponseType reply = ( GetBucketAccessControlPolicyResponseType ) ServiceDispatcher.lookupSingle( Components.lookup( Walrus.class ) ).send( getBukkitInfo );
+ return reply;
+ }
+ return null;
+ }
+
+ public static void verifyManifestIntegrity( User user, String imageLocation ) throws EucalyptusCloudException {
+ if( true ) return;//TODO:GRZE:BUG:BUG
+ String[] imagePathParts = imageLocation.split( "/" );
+ GetObjectResponseType reply = null;
+ GetObjectType msg = new GetObjectType( imagePathParts[0], imagePathParts[1], true, false, true ).regarding( );
+ try {
+ reply = ( GetObjectResponseType ) ServiceDispatcher.lookupSingle( Components.lookup( Walrus.class ) ).send( msg );
+ if ( reply == null || reply.getBase64Data( ) == null ) {
+ throw new EucalyptusCloudException( "No data: " + imageLocation );
+ } else {
+ Logs.exhaust( ).debug( "Got the manifest to verify: " );
+ Logs.exhaust( ).debug( Hashes.base64decode( reply.getBase64Data( ) ) );
+ if( checkManifest( user, reply.getBase64Data( ) ) ) {
+ return;
+ } else {
+ throw new EucalyptusCloudException( "Failed to verify signature." );
+ }
+ }
+ } catch ( EucalyptusCloudException e ) {
+ LOG.error( e, e );
+ LOG.debug( e );
+ throw new EucalyptusCloudException( "Invalid manifest reference: " + imageLocation + " because of " + e.getMessage( ), e );
+ }
+ }
+
+ private static boolean checkManifest( User user, String manifest ) throws EucalyptusCloudException {
+ XMLParser parser = new XMLParser( Hashes.base64decode( manifest ) );
+ String encryptedKey = parser.getValue( "//ec2_encrypted_key" );
+ String encryptedIV = parser.getValue( "//ec2_encrypted_iv" );
+ String signature = parser.getValue( "//signature" );
+ String image = parser.getXML( "image" );
+ String machineConfiguration = parser.getXML( "machine_configuration" );
+ String pad = (machineConfiguration + image);
+ try {
+ for ( Certificate cert : user.getCertificates( ) ) {
+ if ( cert != null && cert instanceof X509Certificate && ImageUtil.verifyManifestSignature( (X509Certificate) cert, signature, pad )) {
+ return true;
+ }
+ }
+ if ( ImageUtil.verifyManifestSignature( SystemCredentials.lookup(Eucalyptus.class).getCertificate(), signature, pad )) {
+ return true;
+ }
+ for ( User u : Accounts.listAllUsers( ) ) {
+ for ( Certificate cert : u.getCertificates( ) ) {
+ if ( cert != null && cert instanceof X509Certificate && ImageUtil.verifyManifestSignature( (X509Certificate) cert, signature, pad )) {
+ return true;
+ }
+ }
+ }
+ return false;
+ } catch ( AuthException e ) {
+ throw new EucalyptusCloudException( "Invalid Manifest: Failed to verify signature because of missing (deleted?) user certificate.", e );
+ }
+ }
+
}
View
765 clc/modules/cluster-manager/src/main/java/com/eucalyptus/images/ImageManifests.java
@@ -70,21 +70,19 @@
import java.util.List;
import java.util.NoSuchElementException;
-import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
+
import org.apache.log4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
+
import com.eucalyptus.auth.Accounts;
import com.eucalyptus.auth.AuthException;
-import com.eucalyptus.auth.policy.PolicySpec;
import com.eucalyptus.auth.principal.User;
import com.eucalyptus.cloud.ImageMetadata;
import com.eucalyptus.cloud.ImageMetadata.DeviceMappingType;
@@ -98,399 +96,394 @@
import com.eucalyptus.util.EucalyptusCloudException;
import com.eucalyptus.util.FullName;
import com.eucalyptus.util.RestrictedTypes;
+import com.eucalyptus.util.XMLParser;
import com.eucalyptus.ws.client.ServiceDispatcher;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
+
import edu.ucsb.eucalyptus.msgs.GetBucketAccessControlPolicyResponseType;
import edu.ucsb.eucalyptus.msgs.GetBucketAccessControlPolicyType;
import edu.ucsb.eucalyptus.msgs.GetObjectResponseType;
import edu.ucsb.eucalyptus.msgs.GetObjectType;
public class ImageManifests {
- private static Logger LOG = Logger.getLogger( ImageManifests.class );
-
- static boolean verifyBucketAcl( String bucketName ) {
- Context ctx = Contexts.lookup( );
- GetBucketAccessControlPolicyType getBukkitInfo = new GetBucketAccessControlPolicyType( );
- getBukkitInfo.setBucket( bucketName );
- try {
- GetBucketAccessControlPolicyResponseType reply = ( GetBucketAccessControlPolicyResponseType ) ServiceDispatcher.lookupSingle( Components.lookup( Walrus.class ) ).send( getBukkitInfo );
- String ownerName = reply.getAccessControlPolicy( ).getOwner( ).getDisplayName( );
- String ownerId = reply.getAccessControlPolicy( ).getOwner( ).getID();
- return ctx.getUserFullName( ).getAccountNumber( ).equals( ownerId ) || ctx.getUserFullName( ).getUserId( ).equals( ownerId );
- } catch ( EucalyptusCloudException ex ) {
- LOG.error( ex, ex );
- } catch ( NoSuchElementException ex ) {
- LOG.error( ex, ex );
- }
- return false;
- }
-
- private static boolean verifyManifestSignature( final X509Certificate cert, final String signature, String pad ) {
- Signature sigVerifier;
- try {
- sigVerifier = Signature.getInstance( "SHA1withRSA" );
- PublicKey publicKey = cert.getPublicKey( );
- sigVerifier.initVerify( publicKey );
- sigVerifier.update( ( pad ).getBytes( ) );
- return sigVerifier.verify( hexToBytes( signature ) );
- } catch ( Exception ex ) {
- LOG.error( ex, ex );
- return false;
- }
- }
-
- private static byte[] hexToBytes( String data ) {
- int k = 0;
- byte[] results = new byte[data.length( ) / 2];
- for ( int i = 0; i < data.length( ); ) {
- results[k] = ( byte ) ( Character.digit( data.charAt( i++ ), 16 ) << 4 );
- results[k] += ( byte ) ( Character.digit( data.charAt( i++ ), 16 ) );
- k++;
- }
-
- return results;
- }
-
- static String requestManifestData( FullName userName, String bucketName, String objectName ) throws EucalyptusCloudException {
- GetObjectResponseType reply = null;
- try {
- GetObjectType msg = new GetObjectType( bucketName, objectName, true, false, true );
-//TODO:GRZE:WTF.
-// User user = Accounts.lookupUserById( userName.getNamespace( ) );
-// msg.setUserId( user.getName( ) );
- msg.regarding( );
- msg.setCorrelationId( Contexts.lookup( ).getRequest( ).getCorrelationId( ) );
- reply = ( GetObjectResponseType ) ServiceDispatcher.lookupSingle( Components.lookup( Walrus.class ) ).send( msg );
- } catch ( Exception e ) {
- throw new EucalyptusCloudException( "Failed to read manifest file: " + bucketName + "/" + objectName, e );
- }
- return B64.url.decString( reply.getBase64Data( ).getBytes( ) );
- }
-
- public static class ManifestDeviceMapping {
- ManifestDeviceMapping( DeviceMappingType type, String virtualName, String deviceName ) {
- super( );
- this.type = type;
- this.virtualName = virtualName;
- this.deviceName = deviceName;
- }
-
- DeviceMappingType type;
- String virtualName;
- String deviceName;
-
- public DeviceMapping generateRealMapping( ImageInfo parent ) {
- if ( DeviceMappingType.ephemeral.equals( type ) ) {
- return new EphemeralDeviceMapping( parent, deviceName, virtualName );
- } else {//if( DeviceMappingType.root.equals( type ) || DeviceMappingType.swap.equals( type ) ) {
- return new DeviceMapping( parent, type, deviceName, virtualName );
- }
- }
- }
-
- public static class ImageManifest {
- private final String imageLocation;
- private final ImageMetadata.Architecture architecture;
- private final String kernelId;
- private final String ramdiskId;
- private final ImageMetadata.Type imageType;
- private final ImageMetadata.Platform platform;
- private final String signature;
- private final String checksum;
- private final String checksumType;
- private final String manifest;
- private final Document inputSource;
- private final String name;
- private final Long size;
- private final Long bundledSize;
- private XPath xpath;
- private Function<String, String> xpathHelper;
- private String encryptedKey;
- private String encryptedIV;
- private List<ManifestDeviceMapping> deviceMappings = Lists.newArrayList( );
-
- ImageManifest( String imageLocation ) throws EucalyptusCloudException {
- Context ctx = Contexts.lookup( );
- String cleanLocation = imageLocation.replaceAll( "^/*", "" );
- this.imageLocation = cleanLocation;
- int index = cleanLocation.indexOf( '/' );
- if ( index < 2 || index + 1 >= cleanLocation.length( ) ) {
- throw new EucalyptusCloudException( "Image registration failed: Invalid image location: " + imageLocation );
- }
- String bucketName = cleanLocation.substring( 0, index );
- String manifestKey = cleanLocation.substring( index + 1 );
- final String manifestName = manifestKey.replaceAll( ".*/", "" );
- if ( !ImageManifests.verifyBucketAcl( bucketName ) ) {
- throw new EucalyptusCloudException( "Image registration failed: you must own the bucket containing the image." );
- }
- this.manifest = ImageManifests.requestManifestData( ctx.getUserFullName( ), bucketName, manifestKey );
- try {
- DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
- dbFactory.setExpandEntityReferences(false);
+ private static Logger LOG = Logger.getLogger( ImageManifests.class );
+
+ static boolean verifyBucketAcl( String bucketName ) {
+ Context ctx = Contexts.lookup( );
+ GetBucketAccessControlPolicyType getBukkitInfo = new GetBucketAccessControlPolicyType( );
+ getBukkitInfo.setBucket( bucketName );
+ try {
+ GetBucketAccessControlPolicyResponseType reply = ( GetBucketAccessControlPolicyResponseType ) ServiceDispatcher.lookupSingle( Components.lookup( Walrus.class ) ).send( getBukkitInfo );
+ String ownerName = reply.getAccessControlPolicy( ).getOwner( ).getDisplayName( );
+ String ownerId = reply.getAccessControlPolicy( ).getOwner( ).getID();
+ return ctx.getUserFullName( ).getAccountNumber( ).equals( ownerId ) || ctx.getUserFullName( ).getUserId( ).equals( ownerId );
+ } catch ( EucalyptusCloudException ex ) {
+ LOG.error( ex, ex );
+ } catch ( NoSuchElementException ex ) {
+ LOG.error( ex, ex );
+ }
+ return false;
+ }
+
+ private static boolean verifyManifestSignature( final X509Certificate cert, final String signature, String pad ) {
+ Signature sigVerifier;
+ try {
+ sigVerifier = Signature.getInstance( "SHA1withRSA" );
+ PublicKey publicKey = cert.getPublicKey( );
+ sigVerifier.initVerify( publicKey );
+ sigVerifier.update( ( pad ).getBytes( ) );
+ return sigVerifier.verify( hexToBytes( signature ) );
+ } catch ( Exception ex ) {
+ LOG.error( ex, ex );
+ return false;
+ }
+ }
+
+ private static byte[] hexToBytes( String data ) {
+ int k = 0;
+ byte[] results = new byte[data.length( ) / 2];
+ for ( int i = 0; i < data.length( ); ) {
+ results[k] = ( byte ) ( Character.digit( data.charAt( i++ ), 16 ) << 4 );
+ results[k] += ( byte ) ( Character.digit( data.charAt( i++ ), 16 ) );
+ k++;
+ }
+
+ return results;
+ }
+
+ static String requestManifestData( FullName userName, String bucketName, String objectName ) throws EucalyptusCloudException {
+ GetObjectResponseType reply = null;
try {
- dbFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
- } catch(ParserConfigurationException ex) {
- LOG.error(ex, ex);
+ GetObjectType msg = new GetObjectType( bucketName, objectName, true, false, true );
+ //TODO:GRZE:WTF.
+ // User user = Accounts.lookupUserById( userName.getNamespace( ) );
+ // msg.setUserId( user.getName( ) );
+ msg.regarding( );
+ msg.setCorrelationId( Contexts.lookup( ).getRequest( ).getCorrelationId( ) );
+ reply = ( GetObjectResponseType ) ServiceDispatcher.lookupSingle( Components.lookup( Walrus.class ) ).send( msg );
+ } catch ( Exception e ) {
+ throw new EucalyptusCloudException( "Failed to read manifest file: " + bucketName + "/" + objectName, e );
+ }
+ return B64.url.decString( reply.getBase64Data( ).getBytes( ) );
+ }
+
+ public static class ManifestDeviceMapping {
+ ManifestDeviceMapping( DeviceMappingType type, String virtualName, String deviceName ) {
+ super( );
+ this.type = type;
+ this.virtualName = virtualName;
+ this.deviceName = deviceName;
+ }
+
+ DeviceMappingType type;
+ String virtualName;
+ String deviceName;
+
+ public DeviceMapping generateRealMapping( ImageInfo parent ) {
+ if ( DeviceMappingType.ephemeral.equals( type ) ) {
+ return new EphemeralDeviceMapping( parent, deviceName, virtualName );
+ } else {//if( DeviceMappingType.root.equals( type ) || DeviceMappingType.swap.equals( type ) ) {
+ return new DeviceMapping( parent, type, deviceName, virtualName );
+ }
+ }
+ }
+
+ public static class ImageManifest {
+ private final String imageLocation;
+ private final ImageMetadata.Architecture architecture;
+ private final String kernelId;
+ private final String ramdiskId;
+ private final ImageMetadata.Type imageType;
+ private final ImageMetadata.Platform platform;
+ private final String signature;
+ private final String checksum;
+ private final String checksumType;
+ private final String manifest;
+ private final Document inputSource;
+ private final String name;
+ private final Long size;
+ private final Long bundledSize;
+ private XPath xpath;
+ private Function<String, String> xpathHelper;
+ private String encryptedKey;
+ private String encryptedIV;
+ private List<ManifestDeviceMapping> deviceMappings = Lists.newArrayList( );
+
+ ImageManifest( String imageLocation ) throws EucalyptusCloudException {
+ Context ctx = Contexts.lookup( );
+ String cleanLocation = imageLocation.replaceAll( "^/*", "" );
+ this.imageLocation = cleanLocation;
+ int index = cleanLocation.indexOf( '/' );
+ if ( index < 2 || index + 1 >= cleanLocation.length( ) ) {
+ throw new EucalyptusCloudException( "Image registration failed: Invalid image location: " + imageLocation );
+ }
+ String bucketName = cleanLocation.substring( 0, index );
+ String manifestKey = cleanLocation.substring( index + 1 );
+ final String manifestName = manifestKey.replaceAll( ".*/", "" );
+ if ( !ImageManifests.verifyBucketAcl( bucketName ) ) {
+ throw new EucalyptusCloudException( "Image registration failed: you must own the bucket containing the image." );
+ }
+ this.manifest = ImageManifests.requestManifestData( ctx.getUserFullName( ), bucketName, manifestKey );
+ try {
+ DocumentBuilder builder = XMLParser.getDocBuilder();
+ this.inputSource = builder.parse( new ByteArrayInputStream( this.manifest.getBytes( ) ) );
+ } catch ( Exception e ) {
+ throw new EucalyptusCloudException( "Failed to read manifest file: " + bucketName + "/" + manifestKey, e );
+ }
+ this.xpath = XPathFactory.newInstance( ).newXPath( );
+ this.xpathHelper = new Function<String, String>( ) {
+
+ @Override
+ public String apply( String input ) {
+ try {
+ return ( String ) ImageManifest.this.xpath.evaluate( input, ImageManifest.this.inputSource, XPathConstants.STRING );
+ } catch ( XPathExpressionException ex ) {
+ return null;
+ }
+ }
+ };
+
+ String temp;
+ this.name = ( ( temp = this.xpathHelper.apply( "/manifest/image/name/text()" ) ) != null )
+ ? temp
+ : manifestName.replace( ".manifest.xml", "" );
+ this.checksum = ( ( temp = this.xpathHelper.apply( "/manifest/image/digest/text()" ) ) != null )
+ ? temp
+ : "0000000000000000000000000000000000000000";
+ this.checksumType = ( ( temp = this.xpathHelper.apply( "/manifest/image/digest/@algorithm" ) ) != null )
+ ? temp
+ : "SHA1";
+ this.signature = ( ( temp = this.xpathHelper.apply( "//signature" ) ) != null )
+ ? temp
+ : null;
+ this.encryptedKey = this.xpathHelper.apply( "//ec2_encrypted_key" );
+ this.encryptedIV = this.xpathHelper.apply( "//ec2_encrypted_iv" );
+ Predicate<ImageMetadata.Type> checkIdType = new Predicate<ImageMetadata.Type>( ) {
+
+ @Override
+ public boolean apply( ImageMetadata.Type input ) {
+ String value = ImageManifest.this.xpathHelper.apply( input.getManifestPath( ) );
+ if ( "yes".equals( value ) || "true".equals( value ) || manifestName.startsWith( input.getNamePrefix( ) ) ) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ };
+ String typeInManifest = this.xpathHelper.apply( ImageMetadata.TYPE_MANIFEST_XPATH );
+
+ this.size = ( ( temp = this.xpathHelper.apply( "/manifest/image/size/text()" ) ) != null )
+ ? Long.parseLong( temp )
+ : -1l;
+ this.bundledSize = ( ( temp = this.xpathHelper.apply( "/manifest/image/bundled_size/text()" ) ) != null )
+ ? Long.parseLong( temp )
+ : -1l;
+
+ String arch = this.xpathHelper.apply( "/manifest/machine_configuration/architecture/text()" );
+ this.architecture = ImageMetadata.Architecture.valueOf( ( ( arch == null )
+ ? "i386"
+ : arch ) );
+ try {
+ NodeList devMapList = ( NodeList ) this.xpath.evaluate( "/manifest/machine_configuration/block_device_mapping/mapping", inputSource,
+ XPathConstants.NODESET );
+ for ( int i = 0; i < devMapList.getLength( ); i++ ) {
+ Node node = devMapList.item( i );
+ NodeList children = node.getChildNodes( );
+ String virtualName = null;
+ String device = null;
+ for ( int j = 0; j < children.getLength( ); j++ ) {
+ Node childNode = children.item( j );
+ String nodeType = childNode.getNodeName( );
+ if ( "virtual".equals( nodeType ) && childNode.getTextContent( ) != null ) {
+ virtualName = childNode.getTextContent( );
+ } else if ( "device".equals( nodeType ) && childNode.getTextContent( ) != null ) {
+ device = childNode.getTextContent( );
+ }
+ }
+ if ( virtualName != null && device != null ) {
+ if ( "ami".equals( virtualName ) ) {
+ continue;
+ } else if ( "root".equals( virtualName ) ) {
+ this.deviceMappings.add( new ManifestDeviceMapping( DeviceMappingType.root, virtualName, device ) );
+ } else if ( "swap".equals( virtualName ) ) {
+ this.deviceMappings.add( new ManifestDeviceMapping( DeviceMappingType.swap, virtualName, device ) );
+ } else if ( virtualName.startsWith( "ephemeral" ) ) {
+ this.deviceMappings.add( new ManifestDeviceMapping( DeviceMappingType.ephemeral, virtualName, device ) );
+ }
+ }
+ }
+ } catch ( XPathExpressionException ex ) {
+ LOG.error( ex, ex );
+ }
+
+ if ( ( checkIdType.apply( ImageMetadata.Type.kernel ) || checkIdType.apply( ImageMetadata.Type.ramdisk ) ) && !ctx.hasAdministrativePrivileges( ) ) {
+ throw new EucalyptusCloudException( "Only administrators can register kernel images." );
+ } else {
+ if ( checkIdType.apply( ImageMetadata.Type.kernel ) ) {
+ this.imageType = ImageMetadata.Type.kernel;
+ this.platform = ImageMetadata.Platform.linux;
+ this.kernelId = null;
+ this.ramdiskId = null;
+ } else if ( checkIdType.apply( ImageMetadata.Type.ramdisk ) ) {
+ this.imageType = ImageMetadata.Type.ramdisk;
+ this.platform = ImageMetadata.Platform.linux;
+ this.kernelId = null;
+ this.ramdiskId = null;
+ } else {
+ String kId = this.xpathHelper.apply( ImageMetadata.Type.kernel.getManifestPath( ) );
+ String rId = this.xpathHelper.apply( ImageMetadata.Type.ramdisk.getManifestPath( ) );
+ this.imageType = ImageMetadata.Type.machine;
+ if ( !manifestName.startsWith( ImageMetadata.Platform.windows.toString( ) )
+ && !( kId != null && ImageMetadata.Platform.windows.name( ).equals( kId ) ) ) {
+ this.platform = ImageMetadata.Platform.linux;
+ if ( kId != null && kId.startsWith( ImageMetadata.Type.kernel.getTypePrefix( ) ) ) {
+ ImageManifests.checkPrivileges( this.kernelId );
+ this.kernelId = kId;
+ } else {
+ this.kernelId = null;
+ }
+ if ( kId != null && kId.startsWith( ImageMetadata.Type.kernel.getTypePrefix( ) ) ) {
+ ImageManifests.checkPrivileges( this.ramdiskId );
+ this.ramdiskId = rId;
+ } else {
+ this.ramdiskId = null;
+ }
+ } else {
+ this.platform = ImageMetadata.Platform.windows;
+ this.kernelId = null;
+ this.ramdiskId = null;
+ }
+ }
+ }
+ }
+
+ private boolean checkManifest( User user ) throws EucalyptusCloudException {
+ String image = this.manifest.replaceAll( ".*<image>", "<image>" ).replaceAll( "</image>.*", "</image>" );
+ String machineConfiguration = this.manifest.replaceAll( ".*<machine_configuration>", "<machine_configuration>" ).replaceAll( "</machine_configuration>.*",
+ "</machine_configuration>" );
+ final String pad = ( machineConfiguration + image );
+ Predicate<Certificate> tryVerifyWithCert = new Predicate<Certificate>( ) {
+
+ @Override
+ public boolean apply( Certificate checkCert ) {
+ if ( checkCert instanceof X509Certificate ) {
+ X509Certificate cert = ( X509Certificate ) checkCert;
+ Signature sigVerifier;
+ try {
+ sigVerifier = Signature.getInstance( "SHA1withRSA" );
+ PublicKey publicKey = cert.getPublicKey( );
+ sigVerifier.initVerify( publicKey );
+ sigVerifier.update( ( pad ).getBytes( ) );
+ return sigVerifier.verify( hexToBytes( ImageManifest.this.signature ) );
+ } catch ( Exception ex ) {
+ LOG.error( ex, ex );
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+ };
+ Function<com.eucalyptus.auth.principal.Certificate, X509Certificate> euareToX509 = new Function<com.eucalyptus.auth.principal.Certificate, X509Certificate>( ) {
+
+ @Override
+ public X509Certificate apply( com.eucalyptus.auth.principal.Certificate input ) {
+ return input.getX509Certificate( );
+ }
+ };
+
+ try {
+ if ( Iterables.any( Lists.transform( user.getCertificates( ), euareToX509 ), tryVerifyWithCert ) ) {
+ return true;
+ } else if ( tryVerifyWithCert.apply( SystemCredentials.lookup( Eucalyptus.class ).getCertificate( ) ) ) {
+ return true;
+ } else {
+ for ( User u : Accounts.listAllUsers( ) ) {
+ if ( Iterables.any( Lists.transform( u.getCertificates( ), euareToX509 ), tryVerifyWithCert ) ) {
+ return true;
+ }
+ }
+ }
+ } catch ( AuthException e ) {
+ throw new EucalyptusCloudException( "Invalid Manifest: Failed to verify signature because of missing (deleted?) user certificate.", e );
+ }
+ return false;
+ }
+
+ public String getSignature( ) {
+ return this.signature;
+ }
+
+ public ImageMetadata.Platform getPlatform( ) {
+ return this.platform;
+ }
+
+ public ImageMetadata.Architecture getArchitecture( ) {
+ return this.architecture;
+ }
+
+ public String getKernelId( ) {
+ return this.kernelId;
+ }
+
+ public String getRamdiskId( ) {
+ return this.ramdiskId;
+ }
+
+ public ImageMetadata.Type getImageType( ) {
+ return this.imageType;
+ }
+
+ public String getImageLocation( ) {
+ return this.imageLocation;
+ }
+
+ public String getManifest( ) {
+ return this.manifest;
+ }
+
+ public String getName( ) {
+ return this.name;
+ }
+
+ public Long getSize( ) {
+ return this.size;
+ }
+
+ public Long getBundledSize( ) {
+ return this.bundledSize;
+ }
+
+ public String getChecksum( ) {
+ return this.checksum;
+ }
+
+ public String getChecksumType( ) {
+ return this.checksumType;
+ }
+
+ }
+
+ public static ImageManifest lookup( String imageLocation ) throws EucalyptusCloudException {
+ return new ImageManifest( imageLocation );
+ }
+
+ static void checkPrivileges( String diskId ) throws EucalyptusCloudException {
+ Context ctx = Contexts.lookup( );
+ if ( diskId != null ) {
+ ImageInfo disk = null;
+ try {
+ disk = Images.lookupImage( diskId );
+ } catch ( Exception ex ) {
+ LOG.error( ex, ex );
+ throw new EucalyptusCloudException( "Referenced image id is invalid: " + diskId, ex );
+ }
+ if ( !RestrictedTypes.filterPrivileged( ).apply( disk ) ) {
+ throw new EucalyptusCloudException( "Access to " + disk.getImageType( ).toString( ) + " image " + diskId + " is denied for " + ctx.getUser( ).getName( ) );
+ }
}
- DocumentBuilder builder = dbFactory.newDocumentBuilder( );
- this.inputSource = builder.parse( new ByteArrayInputStream( this.manifest.getBytes( ) ) );
- } catch ( Exception e ) {
- throw new EucalyptusCloudException( "Failed to read manifest file: " + bucketName + "/" + manifestKey, e );
- }
- this.xpath = XPathFactory.newInstance( ).newXPath( );
- this.xpathHelper = new Function<String, String>( ) {
-
- @Override
- public String apply( String input ) {
- try {
- return ( String ) ImageManifest.this.xpath.evaluate( input, ImageManifest.this.inputSource, XPathConstants.STRING );
- } catch ( XPathExpressionException ex ) {
- return null;
- }
- }
- };
-
- String temp;
- this.name = ( ( temp = this.xpathHelper.apply( "/manifest/image/name/text()" ) ) != null )
- ? temp
- : manifestName.replace( ".manifest.xml", "" );
- this.checksum = ( ( temp = this.xpathHelper.apply( "/manifest/image/digest/text()" ) ) != null )
- ? temp
- : "0000000000000000000000000000000000000000";
- this.checksumType = ( ( temp = this.xpathHelper.apply( "/manifest/image/digest/@algorithm" ) ) != null )
- ? temp
- : "SHA1";
- this.signature = ( ( temp = this.xpathHelper.apply( "//signature" ) ) != null )
- ? temp
- : null;
- this.encryptedKey = this.xpathHelper.apply( "//ec2_encrypted_key" );
- this.encryptedIV = this.xpathHelper.apply( "//ec2_encrypted_iv" );
- Predicate<ImageMetadata.Type> checkIdType = new Predicate<ImageMetadata.Type>( ) {
-
- @Override
- public boolean apply( ImageMetadata.Type input ) {
- String value = ImageManifest.this.xpathHelper.apply( input.getManifestPath( ) );
- if ( "yes".equals( value ) || "true".equals( value ) || manifestName.startsWith( input.getNamePrefix( ) ) ) {
- return true;
- } else {
- return false;
- }
- }
- };
- String typeInManifest = this.xpathHelper.apply( ImageMetadata.TYPE_MANIFEST_XPATH );
-
- this.size = ( ( temp = this.xpathHelper.apply( "/manifest/image/size/text()" ) ) != null )
- ? Long.parseLong( temp )
- : -1l;
- this.bundledSize = ( ( temp = this.xpathHelper.apply( "/manifest/image/bundled_size/text()" ) ) != null )
- ? Long.parseLong( temp )
- : -1l;
-
- String arch = this.xpathHelper.apply( "/manifest/machine_configuration/architecture/text()" );
- this.architecture = ImageMetadata.Architecture.valueOf( ( ( arch == null )
- ? "i386"
- : arch ) );
- try {
- NodeList devMapList = ( NodeList ) this.xpath.evaluate( "/manifest/machine_configuration/block_device_mapping/mapping", inputSource,
- XPathConstants.NODESET );
- for ( int i = 0; i < devMapList.getLength( ); i++ ) {
- Node node = devMapList.item( i );
- NodeList children = node.getChildNodes( );
- String virtualName = null;
- String device = null;
- for ( int j = 0; j < children.getLength( ); j++ ) {
- Node childNode = children.item( j );
- String nodeType = childNode.getNodeName( );
- if ( "virtual".equals( nodeType ) && childNode.getTextContent( ) != null ) {
- virtualName = childNode.getTextContent( );
- } else if ( "device".equals( nodeType ) && childNode.getTextContent( ) != null ) {
- device = childNode.getTextContent( );
- }
- }
- if ( virtualName != null && device != null ) {
- if ( "ami".equals( virtualName ) ) {
- continue;
- } else if ( "root".equals( virtualName ) ) {
- this.deviceMappings.add( new ManifestDeviceMapping( DeviceMappingType.root, virtualName, device ) );
- } else if ( "swap".equals( virtualName ) ) {
- this.deviceMappings.add( new ManifestDeviceMapping( DeviceMappingType.swap, virtualName, device ) );
- } else if ( virtualName.startsWith( "ephemeral" ) ) {
- this.deviceMappings.add( new ManifestDeviceMapping( DeviceMappingType.ephemeral, virtualName, device ) );
- }
- }
- }
- } catch ( XPathExpressionException ex ) {
- LOG.error( ex, ex );
- }
-
- if ( ( checkIdType.apply( ImageMetadata.Type.kernel ) || checkIdType.apply( ImageMetadata.Type.ramdisk ) ) && !ctx.hasAdministrativePrivileges( ) ) {
- throw new EucalyptusCloudException( "Only administrators can register kernel images." );
- } else {
- if ( checkIdType.apply( ImageMetadata.Type.kernel ) ) {
- this.imageType = ImageMetadata.Type.kernel;
- this.platform = ImageMetadata.Platform.linux;
- this.kernelId = null;
- this.ramdiskId = null;
- } else if ( checkIdType.apply( ImageMetadata.Type.ramdisk ) ) {
- this.imageType = ImageMetadata.Type.ramdisk;
- this.platform = ImageMetadata.Platform.linux;
- this.kernelId = null;
- this.ramdiskId = null;
- } else {
- String kId = this.xpathHelper.apply( ImageMetadata.Type.kernel.getManifestPath( ) );
- String rId = this.xpathHelper.apply( ImageMetadata.Type.ramdisk.getManifestPath( ) );
- this.imageType = ImageMetadata.Type.machine;
- if ( !manifestName.startsWith( ImageMetadata.Platform.windows.toString( ) )
- && !( kId != null && ImageMetadata.Platform.windows.name( ).equals( kId ) ) ) {
- this.platform = ImageMetadata.Platform.linux;
- if ( kId != null && kId.startsWith( ImageMetadata.Type.kernel.getTypePrefix( ) ) ) {
- ImageManifests.checkPrivileges( this.kernelId );
- this.kernelId = kId;
- } else {
- this.kernelId = null;
- }
- if ( kId != null && kId.startsWith( ImageMetadata.Type.kernel.getTypePrefix( ) ) ) {
- ImageManifests.checkPrivileges( this.ramdiskId );
- this.ramdiskId = rId;
- } else {
- this.ramdiskId = null;
- }
- } else {
- this.platform = ImageMetadata.Platform.windows;
- this.kernelId = null;
- this.ramdiskId = null;
- }
- }
- }
- }
-
- private boolean checkManifest( User user ) throws EucalyptusCloudException {
- String image = this.manifest.replaceAll( ".*<image>", "<image>" ).replaceAll( "</image>.*", "</image>" );
- String machineConfiguration = this.manifest.replaceAll( ".*<machine_configuration>", "<machine_configuration>" ).replaceAll( "</machine_configuration>.*",
- "</machine_configuration>" );
- final String pad = ( machineConfiguration + image );
- Predicate<Certificate> tryVerifyWithCert = new Predicate<Certificate>( ) {
-
- @Override
- public boolean apply( Certificate checkCert ) {
- if ( checkCert instanceof X509Certificate ) {
- X509Certificate cert = ( X509Certificate ) checkCert;
- Signature sigVerifier;
- try {
- sigVerifier = Signature.getInstance( "SHA1withRSA" );
- PublicKey publicKey = cert.getPublicKey( );
- sigVerifier.initVerify( publicKey );
- sigVerifier.update( ( pad ).getBytes( ) );
- return sigVerifier.verify( hexToBytes( ImageManifest.this.signature ) );
- } catch ( Exception ex ) {
- LOG.error( ex, ex );
- return false;
- }
- } else {
- return false;
- }
- }
- };
- Function<com.eucalyptus.auth.principal.Certificate, X509Certificate> euareToX509 = new Function<com.eucalyptus.auth.principal.Certificate, X509Certificate>( ) {
-
- @Override
- public X509Certificate apply( com.eucalyptus.auth.principal.Certificate input ) {
- return input.getX509Certificate( );
- }
- };
-
- try {
- if ( Iterables.any( Lists.transform( user.getCertificates( ), euareToX509 ), tryVerifyWithCert ) ) {
- return true;
- } else if ( tryVerifyWithCert.apply( SystemCredentials.lookup( Eucalyptus.class ).getCertificate( ) ) ) {
- return true;
- } else {
- for ( User u : Accounts.listAllUsers( ) ) {
- if ( Iterables.any( Lists.transform( u.getCertificates( ), euareToX509 ), tryVerifyWithCert ) ) {
- return true;
- }
- }
- }
- } catch ( AuthException e ) {
- throw new EucalyptusCloudException( "Invalid Manifest: Failed to verify signature because of missing (deleted?) user certificate.", e );
- }
- return false;
- }
-
- public String getSignature( ) {
- return this.signature;
- }
-
- public ImageMetadata.Platform getPlatform( ) {
- return this.platform;
- }
-
- public ImageMetadata.Architecture getArchitecture( ) {
- return this.architecture;
- }
-
- public String getKernelId( ) {
- return this.kernelId;
- }
-
- public String getRamdiskId( ) {
- return this.ramdiskId;
- }
-
- public ImageMetadata.Type getImageType( ) {
- return this.imageType;
- }
-
- public String getImageLocation( ) {
- return this.imageLocation;
- }
-
- public String getManifest( ) {
- return this.manifest;
- }
-
- public String getName( ) {
- return this.name;
- }
-
- public Long getSize( ) {
- return this.size;
- }
-
- public Long getBundledSize( ) {
- return this.bundledSize;
- }
-
- public String getChecksum( ) {
- return this.checksum;
- }
-
- public String getChecksumType( ) {
- return this.checksumType;
- }
-
- }
-
- public static ImageManifest lookup( String imageLocation ) throws EucalyptusCloudException {
- return new ImageManifest( imageLocation );
- }
-
- static void checkPrivileges( String diskId ) throws EucalyptusCloudException {
- Context ctx = Contexts.lookup( );
- if ( diskId != null ) {
- ImageInfo disk = null;
- try {
- disk = Images.lookupImage( diskId );
- } catch ( Exception ex ) {
- LOG.error( ex, ex );
- throw new EucalyptusCloudException( "Referenced image id is invalid: " + diskId, ex );
- }
- if ( !RestrictedTypes.filterPrivileged( ).apply( disk ) ) {
- throw new EucalyptusCloudException( "Access to " + disk.getImageType( ).toString( ) + " image " + diskId + " is denied for " + ctx.getUser( ).getName( ) );
- }
- }
- }
+ }
}
View
237 clc/modules/core/src/main/java/edu/ucsb/eucalyptus/util/XMLParser.java
@@ -1,237 +0,0 @@
-/*************************************************************************
- * Copyright 2009-2012 Eucalyptus Systems, Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/.
- *
- * Please contact Eucalyptus Systems, Inc., 6755 Hollister Ave., Goleta
- * CA 93117, USA or visit http://www.eucalyptus.com/licenses/ if you need
- * additional information or have any questions.
- *
- * This file may incorporate work covered under the following copyright
- * and permission notice:
- *
- * Software License Agreement (BSD License)
- *
- * Copyright (c) 2008, Regents of the University of California
- * All rights reserved.
- *
- * Redistribution and use of this software in source and binary forms,
- * with or without modification, are permitted provided that the
- * following conditions are met:
- *
- * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE. USERS OF THIS SOFTWARE ACKNOWLEDGE
- * THE POSSIBLE PRESENCE OF OTHER OPEN SOURCE LICENSED MATERIAL,
- * COPYRIGHTED MATERIAL OR PATENTED MATERIAL IN THIS SOFTWARE,
- * AND IF ANY SUCH MATERIAL IS DISCOVERED THE PARTY DISCOVERING
- * IT MAY INFORM DR. RICH WOLSKI AT THE UNIVERSITY OF CALIFORNIA,
- * SANTA BARBARA WHO WILL THEN ASCERTAIN THE MOST APPROPRIATE REMEDY,
- * WHICH IN THE REGENTS' DISCRETION MAY INCLUDE, WITHOUT LIMITATION,
- * REPLACEMENT OF THE CODE SO IDENTIFIED, LICENSING OF THE CODE SO
- * IDENTIFIED, OR WITHDRAWAL OF THE CODE CAPABILITY TO THE EXTENT
- * NEEDED TO COMPLY WITH ANY SUCH LICENSES OR RIGHTS.
- ************************************************************************/
-
-package edu.ucsb.eucalyptus.util;
-
-import org.apache.log4j.Logger;
-import org.apache.xml.dtm.ref.DTMNodeList;
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-
-import com.eucalyptus.binding.HoldMe;
-
-import javax.xml.XMLConstants;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.xpath.XPath;
-import javax.xml.xpath.XPathConstants;
-import javax.xml.xpath.XPathExpressionException;
-import javax.xml.xpath.XPathFactory;
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.List;
-
-
-public class XMLParser {
-
- private DocumentBuilderFactory docFactory;
- private DocumentBuilder docBuilder;
- private Document docRoot;
- private XPath xpath;
- private File file;
- private String rawData;
- private static Logger LOG = Logger.getLogger(XMLParser.class);
-
- public XMLParser( ) {
- HoldMe.canHas.lock( );
- try {
- xpath = XPathFactory.newInstance( ).newXPath( );
- docFactory = DocumentBuilderFactory.newInstance( );
- docFactory.setExpandEntityReferences(false);
- try {
- docFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
- } catch(ParserConfigurationException ex) {
- LOG.error(ex, ex);
- }
- try {
- docBuilder = docFactory.newDocumentBuilder( );
- } catch ( ParserConfigurationException ex ) {
- ex.printStackTrace( );
- }
- } finally {
- HoldMe.canHas.unlock( );
- }
- }
-
- public XMLParser( File file ) {
- this( );
- HoldMe.canHas.lock( );
- try {
- this.file = file;
- FileInputStream fileInputStream = null;
- try {
- fileInputStream = new FileInputStream( file );
- docRoot = docBuilder.parse( fileInputStream );
- fileInputStream.close();
- } catch ( Exception ex ) {
- ex.printStackTrace( );
- } finally {
- if(fileInputStream != null)
- try {
- fileInputStream.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- } finally {
- HoldMe.canHas.unlock( );
- }
- }
-
- public XMLParser( String xmlData ) {
- this( );
- HoldMe.canHas.lock( );
- try {
- this.rawData = xmlData;
- InputStream in = new ByteArrayInputStream( xmlData.getBytes( ) );
- try {
- docRoot = docBuilder.parse( in );
- } catch ( Exception ex ) {
- ex.printStackTrace( );
- }
- } finally {
- HoldMe.canHas.unlock( );
- }
- }
-
- public String getValue(String name) {
- try {
- return (String) xpath.evaluate(name, docRoot, XPathConstants.STRING);
- } catch(XPathExpressionException ex) {
- ex.printStackTrace();
- }
- return null;
- }
-
- public String getValue(Node node, String name) {
- try {
- return (String) xpath.evaluate(name, node, XPathConstants.STRING);
- } catch(XPathExpressionException ex) {
- ex.printStackTrace();
- }
- return null;
- }
-
- public List<String> getValues(String name) {
- try {
- DTMNodeList nodes = (DTMNodeList) xpath.evaluate(name, docRoot, XPathConstants.NODESET);
- ArrayList<String> values = new ArrayList<String>();
- for (int i = 0; i < nodes.getLength(); ++i) {
- values.add(nodes.item(i).getFirstChild().getNodeValue());
- }
- return values;
- } catch(XPathExpressionException ex) {
- ex.printStackTrace();
- }
- return null;
- }
-
- public DTMNodeList getNodes(String name) {
- try {
- DTMNodeList nodes = (DTMNodeList) xpath.evaluate(name, docRoot, XPathConstants.NODESET);
- return nodes;
- } catch(XPathExpressionException ex) {
- ex.printStackTrace();
- }
- return null;
- }
-
-
- public String getXML(String name) {
- if(rawData == null) {
- FileInputStream in = null;
- try {
- in = new FileInputStream(file);
- rawData = "";
- byte[] bytes = new byte[1024];
- int bytesRead = 0;
- while ((bytesRead = in.read(bytes)) > 0) {
- rawData += new String(bytes, 0, bytesRead);
- }
- } catch (Exception ex) {
- ex.printStackTrace();
- } finally {
- if(in != null)
- try {
- in.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
-
- String startString = new String("<" + name + ">");
- String endString = new String("</" + name + ">");
- int start = rawData.indexOf(startString);
- int end = rawData.indexOf(endString);
- if(end > start) {
- end += endString.length();
- return rawData.substring(start, end);
- }
- return null;
- }
-}
View
89 clc/modules/core/src/main/java/edu/ucsb/eucalyptus/util/XMLParserTest.java
@@ -1,89 +0,0 @@
-/*************************************************************************
- * Copyright 2009-2012 Eucalyptus Systems, Inc.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/.
- *
- * Please contact Eucalyptus Systems, Inc., 6755 Hollister Ave., Goleta
- * CA 93117, USA or visit http://www.eucalyptus.com/licenses/ if you need
- * additional information or have any questions.
- *
- * This file may incorporate work covered under the following copyright
- * and permission notice:
- *
- * Software License Agreement (BSD License)
- *
- * Copyright (c) 2008, Regents of the University of California
- * All rights reserved.
- *
- * Redistribution and use of this software in source and binary forms,
- * with or without modification, are permitted provided that the
- * following conditions are met:
- *
- * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE. USERS OF THIS SOFTWARE ACKNOWLEDGE
- * THE POSSIBLE PRESENCE OF OTHER OPEN SOURCE LICENSED MATERIAL,
- * COPYRIGHTED MATERIAL OR PATENTED MATERIAL IN THIS SOFTWARE,
- * AND IF ANY SUCH MATERIAL IS DISCOVERED THE PARTY DISCOVERING
- * IT MAY INFORM DR. RICH WOLSKI AT THE UNIVERSITY OF CALIFORNIA,
- * SANTA BARBARA WHO WILL THEN ASCERTAIN THE MOST APPROPRIATE REMEDY,
- * WHICH IN THE REGENTS' DISCRETION MAY INCLUDE, WITHOUT LIMITATION,
- * REPLACEMENT OF THE CODE SO IDENTIFIED, LICENSING OF THE CODE SO
- * IDENTIFIED, OR WITHDRAWAL OF THE CODE CAPABILITY TO THE EXTENT
- * NEEDED TO COMPLY WITH ANY SUCH LICENSES OR RIGHTS.
- ************************************************************************/
-
-package edu.ucsb.eucalyptus.util;
-
-import edu.ucsb.eucalyptus.util.XMLParser;
-import junit.framework.TestCase;
-
-import java.util.List;
-
-public class XMLParserTest extends TestCase {
-
-
- public void testParse() throws Exception {
- String parseTestString = "<AccessControlPolicy> <AccessControlList> <Grant> <Grantee> <DisplayName>nekro</DisplayName> </Grantee> <Permission>FULL_CONTROL</Permission> </Grant> <Grant> <Grantee> <DisplayName>lolwho</DisplayName> </Grantee> <Permission>NO_U</Permission> </Grant></AccessControlList> </AccessControlPolicy>";
-
- XMLParser xmlParser = new XMLParser(parseTestString);
-
- String ownerDisplayName = xmlParser.getValue("//Owner/DisplayName");
-
- List<String> displayNames = xmlParser.getValues("//AccessControlList/Grant/Grantee/DisplayName");
-
- System.out.println(ownerDisplayName);
- }
-
- public XMLParserTest() {
- super();
- }
-
-}
View
66 clc/modules/msgs/src/main/java/com/eucalyptus/component/fault/FaultRegistry.java
@@ -69,10 +69,7 @@
import java.util.Map;
import java.util.Set;
-import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
import org.apache.log4j.Logger;
import org.w3c.dom.Document;
@@ -82,6 +79,8 @@
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
+import com.eucalyptus.util.XMLParser;
+
public class FaultRegistry {
private static final Logger LOG = Logger.getLogger(FaultRegistry.class);
private static final String EUCAFAULTS = "eucafaults";
@@ -126,36 +125,28 @@ private void parseCommonXMLFile(File commonXMLFile,
Map<String, Common> commonMap) {
try {
LOG.warn("Parsing common file " + commonXMLFile);
- DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
- dbFactory.setExpandEntityReferences(false);
- try {
- dbFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
- } catch(ParserConfigurationException ex) {
- LOG.error(ex, ex);
+ DocumentBuilder dBuilder = XMLParser.getDocBuilder();
+ if (dBuilder != null) {
+ Document doc = dBuilder.parse(commonXMLFile);
+ Element docElement = doc.getDocumentElement();
+ docElement.normalize();
+ if (!EUCAFAULTS.equalsIgnoreCase(docElement.getTagName())) {
+ LOG.warn("File " + commonXMLFile + " contains the wrong outer XML tag, will not be parsed.");
+ } else {
+ NodeList children = docElement.getChildNodes();
+ final int length = children.getLength();
+ for (int i=0;i < length; i++) {
+ Node currentNode = children.item(i);
+ if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
+ Element currentElement = (Element) currentNode;
+ if (COMMON.equalsIgnoreCase(currentElement.getTagName())) {
+ parseCommonElement(currentElement, commonMap);
+ }
+ }
+ }
+ }
+ LOG.debug("Successfully parsed " + commonXMLFile);
}
- DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
- Document doc = dBuilder.parse(commonXMLFile);
- Element docElement = doc.getDocumentElement();
- docElement.normalize();
- if (!EUCAFAULTS.equalsIgnoreCase(docElement.getTagName())) {
- LOG.warn("File " + commonXMLFile + " contains the wrong outer XML tag, will not be parsed.");
- } else {
- NodeList children = docElement.getChildNodes();
- final int length = children.getLength();
- for (int i=0;i < length; i++) {
- Node currentNode = children.item(i);
- if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
- Element currentElement = (Element) currentNode;
- if (COMMON.equalsIgnoreCase(currentElement.getTagName())) {
- parseCommonElement(currentElement, commonMap);
- }
- }
- }
- }
- LOG.debug("Successfully parsed " + commonXMLFile);
- } catch (ParserConfigurationException ex) {
- ex.printStackTrace();
- LOG.error(ex);
} catch (SAXException ex) {
ex.printStackTrace();
LOG.error(ex);
@@ -181,14 +172,7 @@ private void parseFaultXMLFile(File faultXMLFile,
suppressedFaults.add(faultId);
return;
}
- DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
- dbFactory.setExpandEntityReferences(false);
- try {
- dbFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
- } catch(ParserConfigurationException ex) {
- LOG.error(ex, ex);
- }
- DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
+ DocumentBuilder dBuilder = XMLParser.getDocBuilder();
Document doc = dBuilder.parse(faultXMLFile);
Element docElement = doc.getDocumentElement();
docElement.normalize();
@@ -222,8 +206,6 @@ private void parseFaultXMLFile(File faultXMLFile,
}
}
}
- } catch (ParserConfigurationException ex) {
- LOG.error(ex);
} catch (SAXException ex) {
LOG.error(ex);
} catch (IOException ex) {
View
16 clc/modules/msgs/src/main/java/com/eucalyptus/system/log/LoggingResetter.java
@@ -69,10 +69,7 @@
import java.util.HashMap;
import java.util.Map;
-import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
import org.apache.log4j.Appender;
import org.apache.log4j.AppenderSkeleton;
@@ -89,6 +86,7 @@
import org.xml.sax.SAXException;
import com.eucalyptus.records.Logs;
+import com.eucalyptus.util.XMLParser;
@@ -123,14 +121,7 @@ public static synchronized void resetLoggingWithXML() {
SmallLoggingConfiguration smallLoggingConfiguration = null;
InputStream in = null;
try {
- DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
- dbFactory.setExpandEntityReferences(false);
- try {
- dbFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
- } catch(ParserConfigurationException ex) {
- LOG.error(ex, ex);
- }
- DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
+ DocumentBuilder dBuilder = XMLParser.getDocBuilder();
dBuilder.setEntityResolver(new Log4jEntityResolver());
URL url = Thread.currentThread().getContextClassLoader().getResource("log4j.xml");
if (url != null) {
@@ -150,9 +141,6 @@ public static synchronized void resetLoggingWithXML() {
} catch (IOException ex) { // nothing we can really do here...
LOG.error(ex);
LOG.warn("Unable to reset log levels");
- } catch (ParserConfigurationException ex) { // nothing we can really do here...
- LOG.error(ex);
- LOG.warn("Unable to reset log levels");
} catch (SAXException ex) { // nothing we can really do here...
LOG.error(ex);
LOG.warn("Unable to reset log levels");
View
62 ...ava/com/eucalyptus/ws/util/XMLParser.java → ...n/java/com/eucalyptus/util/XMLParser.java
@@ -60,12 +60,15 @@
* NEEDED TO COMPLY WITH ANY SUCH LICENSES OR RIGHTS.
************************************************************************/
-package com.eucalyptus.ws.util;
+package com.eucalyptus.util;
import org.apache.log4j.Logger;
import org.apache.xml.dtm.ref.DTMNodeList;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
@@ -80,6 +83,7 @@
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
@@ -88,7 +92,6 @@
private static Logger LOG = Logger.getLogger(XMLParser.class);
- private DocumentBuilderFactory docFactory;
private DocumentBuilder docBuilder;
private Document docRoot;
private XPath xpath;
@@ -97,18 +100,7 @@
public XMLParser() {
xpath = XPathFactory.newInstance().newXPath();
- docFactory = DocumentBuilderFactory.newInstance();
- docFactory.setExpandEntityReferences(false);
- try {
- docFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
- } catch(ParserConfigurationException ex) {
- LOG.error(ex, ex);
- }
- try {
- docBuilder = docFactory.newDocumentBuilder();
- } catch (ParserConfigurationException ex) {
- LOG.error(ex, ex);
- }
+ docBuilder = getDocBuilder();
}
public XMLParser(File file) {
@@ -143,6 +135,48 @@ public XMLParser(String xmlData) {
}
}
+ public static DocumentBuilderFactory getDocBuilderFactory() {
+ DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
+ dFactory.setExpandEntityReferences(false);
+
+ try {
+ dFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
+ } catch(ParserConfigurationException ex) {
+ LOG.error(ex, ex);
+ }
+
+ try{
+ dFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
+ } catch(ParserConfigurationException ex) {
+ LOG.error(ex, ex);
+ }
+
+ try {
+ dFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
+ } catch(ParserConfigurationException ex) {
+ LOG.error(ex, ex);
+ }
+ return dFactory;
+ }
+
+ public static DocumentBuilder getDocBuilder() {
+ DocumentBuilderFactory dFactory = getDocBuilderFactory();
+ DocumentBuilder dBuilder = null;
+ try {
+ dBuilder = dFactory.newDocumentBuilder();
+ dBuilder.setEntityResolver(new EntityResolver() {
+ @Override
+ public InputSource resolveEntity(String publicId, String systemId)
+ throws SAXException, IOException {
+ return new InputSource(new StringReader(""));
+ }
+ });
+ } catch (ParserConfigurationException ex) {
+ LOG.error(ex, ex);
+ }
+ return dBuilder;
+ }
+
public String getValue(String name) {
try {
return (String) xpath.evaluate(name, docRoot, XPathConstants.STRING);
View
12 clc/modules/walrus/src/main/java/edu/ucsb/eucalyptus/cloud/ws/WalrusImageManager.java
@@ -128,6 +128,8 @@
import com.eucalyptus.util.EucalyptusCloudException;
import com.eucalyptus.util.Lookups;
import com.eucalyptus.util.WalrusProperties;
+import com.eucalyptus.util.XMLParser;
+
import edu.ucsb.eucalyptus.cloud.AccessDeniedException;
import edu.ucsb.eucalyptus.cloud.BucketLogData;
import edu.ucsb.eucalyptus.cloud.DecryptionFailedException;
@@ -154,7 +156,6 @@
import edu.ucsb.eucalyptus.util.EucaSemaphoreDirectory;
import edu.ucsb.eucalyptus.util.WalrusDataMessenger;
import edu.ucsb.eucalyptus.util.WalrusMonitor;
-import edu.ucsb.eucalyptus.util.XMLParser;
public class WalrusImageManager {
private static Logger LOG = Logger.getLogger( WalrusImageManager.class );
@@ -589,14 +590,7 @@ private void validateManifest(String bucketName, String objectKey, String accoun
sigCloud.update(verificationString.getBytes());
String signature = new String(Hashes.bytesToHex(sigCloud.sign()));
//TODO: refactor
- DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
- dbFactory.setExpandEntityReferences(false);
- try {
- dbFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
- } catch(ParserConfigurationException ex) {
- LOG.error(ex, ex);
- }
- DocumentBuilder docBuilder = dbFactory.newDocumentBuilder( );
+ DocumentBuilder docBuilder = XMLParser.getDocBuilder();
fileInputStream = new FileInputStream( file );
Document docRoot = docBuilder.parse( fileInputStream );
Element sigElement = docRoot.createElement("signature");
View
2 clc/modules/wsstack/src/main/java/com/eucalyptus/ws/handlers/WalrusRESTBinding.java
@@ -116,9 +116,9 @@
import com.eucalyptus.util.StorageProperties;
import com.eucalyptus.util.WalrusProperties;
import com.eucalyptus.util.WalrusUtil;
+import com.eucalyptus.util.XMLParser;
import com.eucalyptus.ws.InvalidOperationException;
import com.eucalyptus.ws.util.WalrusBucketLogger;
-import com.eucalyptus.ws.util.XMLParser;
import com.google.common.collect.Lists;
import edu.ucsb.eucalyptus.cloud.BucketLogData;

0 comments on commit e958e60

Please sign in to comment.
Something went wrong with that request. Please try again.