~tritone-team/tritone/eucalyptus

« back to all changes in this revision

Viewing changes to clc/modules/image-manager/src/main/java/com/eucalyptus/images/util/WalrusUtil.java

  • Committer: Bazaar Package Importer
  • Author(s): Dustin Kirkland
  • Date: 2009-12-01 21:09:28 UTC
  • mto: This revision was merged to the branch mainline in revision 75.
  • Revision ID: james.westby@ubuntu.com-20091201210928-o2dvg0ubljhb0ft6
Tags: upstream-1.6.1~bzr1083
ImportĀ upstreamĀ versionĀ 1.6.1~bzr1083

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*******************************************************************************
2
 
*Copyright (c) 2009  Eucalyptus Systems, Inc.
3
 
4
 
*  This program is free software: you can redistribute it and/or modify
5
 
*  it under the terms of the GNU General Public License as published by
6
 
*  the Free Software Foundation, only version 3 of the License.
7
 
8
 
9
 
*  This file is distributed in the hope that it will be useful, but WITHOUT
10
 
*  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
 
*  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12
 
*  for more details.
13
 
14
 
*  You should have received a copy of the GNU General Public License along
15
 
*  with this program.  If not, see <http://www.gnu.org/licenses/>.
16
 
17
 
*  Please contact Eucalyptus Systems, Inc., 130 Castilian
18
 
*  Dr., Goleta, CA 93101 USA or visit <http://www.eucalyptus.com/licenses/>
19
 
*  if you need additional information or have any questions.
20
 
21
 
*  This file may incorporate work covered under the following copyright and
22
 
*  permission notice:
23
 
24
 
*    Software License Agreement (BSD License)
25
 
26
 
*    Copyright (c) 2008, Regents of the University of California
27
 
*    All rights reserved.
28
 
29
 
*    Redistribution and use of this software in source and binary forms, with
30
 
*    or without modification, are permitted provided that the following
31
 
*    conditions are met:
32
 
33
 
*      Redistributions of source code must retain the above copyright notice,
34
 
*      this list of conditions and the following disclaimer.
35
 
36
 
*      Redistributions in binary form must reproduce the above copyright
37
 
*      notice, this list of conditions and the following disclaimer in the
38
 
*      documentation and/or other materials provided with the distribution.
39
 
40
 
*    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
41
 
*    IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
42
 
*    TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
43
 
*    PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
44
 
*    OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
45
 
*    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
46
 
*    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
47
 
*    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
48
 
*    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
49
 
*    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
50
 
*    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. USERS OF
51
 
*    THIS SOFTWARE ACKNOWLEDGE THE POSSIBLE PRESENCE OF OTHER OPEN SOURCE
52
 
*    LICENSED MATERIAL, COPYRIGHTED MATERIAL OR PATENTED MATERIAL IN THIS
53
 
*    SOFTWARE, AND IF ANY SUCH MATERIAL IS DISCOVERED THE PARTY DISCOVERING
54
 
*    IT MAY INFORM DR. RICH WOLSKI AT THE UNIVERSITY OF CALIFORNIA, SANTA
55
 
*    BARBARA WHO WILL THEN ASCERTAIN THE MOST APPROPRIATE REMEDY, WHICH IN
56
 
*    THE REGENTSā€™ DISCRETION MAY INCLUDE, WITHOUT LIMITATION, REPLACEMENT
57
 
*    OF THE CODE SO IDENTIFIED, LICENSING OF THE CODE SO IDENTIFIED, OR
58
 
*    WITHDRAWAL OF THE CODE CAPABILITY TO THE EXTENT NEEDED TO COMPLY WITH
59
 
*    ANY SUCH LICENSES OR RIGHTS.
60
 
*******************************************************************************/
 
2
 *Copyright (c) 2009  Eucalyptus Systems, Inc.
 
3
 * 
 
4
 *  This program is free software: you can redistribute it and/or modify
 
5
 *  it under the terms of the GNU General Public License as published by
 
6
 *  the Free Software Foundation, only version 3 of the License.
 
7
 * 
 
8
 * 
 
9
 *  This file is distributed in the hope that it will be useful, but WITHOUT
 
10
 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 
11
 *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 
12
 *  for more details.
 
13
 * 
 
14
 *  You should have received a copy of the GNU General Public License along
 
15
 *  with this program.  If not, see <http://www.gnu.org/licenses/>.
 
16
 * 
 
17
 *  Please contact Eucalyptus Systems, Inc., 130 Castilian
 
18
 *  Dr., Goleta, CA 93101 USA or visit <http://www.eucalyptus.com/licenses/>
 
19
 *  if you need additional information or have any questions.
 
20
 * 
 
21
 *  This file may incorporate work covered under the following copyright and
 
22
 *  permission notice:
 
23
 * 
 
24
 *    Software License Agreement (BSD License)
 
25
 * 
 
26
 *    Copyright (c) 2008, Regents of the University of California
 
27
 *    All rights reserved.
 
28
 * 
 
29
 *    Redistribution and use of this software in source and binary forms, with
 
30
 *    or without modification, are permitted provided that the following
 
31
 *    conditions are met:
 
32
 * 
 
33
 *      Redistributions of source code must retain the above copyright notice,
 
34
 *      this list of conditions and the following disclaimer.
 
35
 * 
 
36
 *      Redistributions in binary form must reproduce the above copyright
 
37
 *      notice, this list of conditions and the following disclaimer in the
 
38
 *      documentation and/or other materials provided with the distribution.
 
39
 * 
 
40
 *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 
41
 *    IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 
42
 *    TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 
43
 *    PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
 
44
 *    OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 
45
 *    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 
46
 *    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 
47
 *    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 
48
 *    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 
49
 *    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 
50
 *    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. USERS OF
 
51
 *    THIS SOFTWARE ACKNOWLEDGE THE POSSIBLE PRESENCE OF OTHER OPEN SOURCE
 
52
 *    LICENSED MATERIAL, COPYRIGHTED MATERIAL OR PATENTED MATERIAL IN THIS
 
53
 *    SOFTWARE, AND IF ANY SUCH MATERIAL IS DISCOVERED THE PARTY DISCOVERING
 
54
 *    IT MAY INFORM DR. RICH WOLSKI AT THE UNIVERSITY OF CALIFORNIA, SANTA
 
55
 *    BARBARA WHO WILL THEN ASCERTAIN THE MOST APPROPRIATE REMEDY, WHICH IN
 
56
 *    THE REGENTSā€™ DISCRETION MAY INCLUDE, WITHOUT LIMITATION, REPLACEMENT
 
57
 *    OF THE CODE SO IDENTIFIED, LICENSING OF THE CODE SO IDENTIFIED, OR
 
58
 *    WITHDRAWAL OF THE CODE CAPABILITY TO THE EXTENT NEEDED TO COMPLY WITH
 
59
 *    ANY SUCH LICENSES OR RIGHTS.
 
60
 *******************************************************************************/
61
61
package com.eucalyptus.images.util;
62
62
 
63
63
import java.io.ByteArrayInputStream;
95
95
import edu.ucsb.eucalyptus.util.XMLParser;
96
96
 
97
97
public class WalrusUtil {
98
 
    
99
 
  public static void checkValid( ImageInfo imgInfo ) {
100
 
    String[] parts = imgInfo.getImageLocation().split( "/" );
101
 
    CheckImageType check = new CheckImageType();
102
 
    check.setUserId( imgInfo.getImageOwnerId( ) );
103
 
    check.setBucket( parts[ 0 ] );
104
 
    check.setKey( parts[ 1 ] );
105
 
    RemoteDispatcher.lookupSingle( Component.walrus ).dispatch( check );
106
 
  }
107
 
 
108
 
  public static void triggerCaching( ImageInfo imgInfo ) {
109
 
    String[] parts = imgInfo.getImageLocation().split( "/" );
110
 
    CacheImageType cache = new CacheImageType();
111
 
    cache.setUserId( imgInfo.getImageOwnerId( ) );
112
 
    cache.setBucket( parts[ 0 ] );
113
 
    cache.setKey( parts[ 1 ] );
114
 
    RemoteDispatcher.lookupSingle( Component.walrus ).dispatch( cache );
115
 
  }
116
 
 
117
 
  public static void invalidate( ImageInfo imgInfo ) {
118
 
    String[] parts = imgInfo.getImageLocation().split( "/" );
119
 
    imgInfo.setImageState( "deregistered" );
120
 
    try {
121
 
      RemoteDispatcher.lookupSingle( Component.walrus ).dispatch( new FlushCachedImageType( parts[ 0 ], parts[ 1 ] ) );
122
 
    } catch ( Exception e ) {}
123
 
  }
124
 
 
125
 
  public static Document getManifestData( String userId, String bucketName, String objectName ) throws EucalyptusCloudException {
126
 
    GetObjectResponseType reply = null;
127
 
    try {
128
 
      GetObjectType msg = new GetObjectType( bucketName, objectName, true, false, true );
129
 
      msg.setUserId( userId );
130
 
      
131
 
      reply = ( GetObjectResponseType ) RemoteDispatcher.lookupSingle( Component.walrus ).send( msg );
132
 
    }
133
 
    catch ( Exception e ) {
134
 
      throw new EucalyptusCloudException( "Failed to read manifest file: " + bucketName + "/" + objectName, e );
135
 
    }
136
 
  
137
 
    Document inputSource = null;
138
 
    try {
139
 
      DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
140
 
      inputSource = builder.parse( new ByteArrayInputStream( reply.getBase64Data().getBytes() ) );
141
 
    }
142
 
    catch ( Exception e ) {
143
 
      throw new EucalyptusCloudException( "Failed to read manifest file: " + bucketName + "/" + objectName, e );
144
 
    }
145
 
    return inputSource;
146
 
  }
147
 
 
148
 
  public static GetBucketAccessControlPolicyResponseType getBucketAcl( RegisterImageType request, String[] imagePathParts ) throws EucalyptusCloudException {
149
 
    GetBucketAccessControlPolicyType getBukkitInfo = Admin.makeMsg( GetBucketAccessControlPolicyType.class, request );
150
 
    getBukkitInfo.setBucket( imagePathParts[ 0 ] );
151
 
    GetBucketAccessControlPolicyResponseType reply = ( GetBucketAccessControlPolicyResponseType ) RemoteDispatcher.lookupSingle( Component.walrus ).send( getBukkitInfo );
152
 
    return reply;
153
 
  }
154
 
 
155
 
  public static void verifyManifestIntegrity( final ImageInfo imgInfo ) throws EucalyptusCloudException {
156
 
    String[] imagePathParts = imgInfo.getImageLocation().split( "/" );
157
 
    GetObjectResponseType reply = null;
158
 
    GetObjectType msg = new GetObjectType( imagePathParts[ 0 ], imagePathParts[ 1 ], true, false, true );
159
 
    msg.setUserId( Component.eucalyptus.name() );
160
 
    msg.setEffectiveUserId( Component.eucalyptus.name() );
161
 
    try {
162
 
      reply = ( GetObjectResponseType ) ServiceDispatcher.lookupSingle( Component.walrus ).send( msg );
163
 
    } catch ( EucalyptusCloudException e ) {
164
 
      ImageManager.LOG.error( e );
165
 
      ImageManager.LOG.debug( e, e );
166
 
      throw new EucalyptusCloudException( "Invalid manifest reference: " + imgInfo.getImageLocation(), e );
167
 
    }
168
 
  
169
 
    if ( reply == null || reply.getBase64Data() == null ) throw new EucalyptusCloudException( "Invalid manifest reference: " + imgInfo.getImageLocation() );
170
 
    XMLParser parser = new XMLParser( reply.getBase64Data() );
171
 
    String encryptedKey = parser.getValue( "//ec2_encrypted_key" );
172
 
    String encryptedIV = parser.getValue( "//ec2_encrypted_iv" );
173
 
    String signature = parser.getValue( "//signature" );
174
 
    String image = parser.getXML( "image" );
175
 
    String machineConfiguration = parser.getXML( "machine_configuration" );
176
 
  
177
 
    List<String> aliases = Lists.newArrayList();
178
 
    try {
179
 
      for( X509Cert x : CredentialProvider.getUser( imgInfo.getImageOwnerId( ) ).getCertificates( ) ) {
180
 
        aliases.add( x.getAlias( ) );
181
 
      }
182
 
    } catch ( NoSuchUserException e ) {
183
 
      throw new EucalyptusCloudException( "Invalid Manifest: Failed to verify signature because of missing (deleted?) user certificate.", e );
184
 
    }
185
 
    boolean found = false;
186
 
    for ( String alias : aliases )
187
 
      found |= ImageUtil.verifyManifestSignature( signature, alias, machineConfiguration + image );
188
 
    if ( !found ) throw new EucalyptusCloudException( "Invalid Manifest: Failed to verify signature." );
189
 
  
190
 
    try {
191
 
      PrivateKey pk = SystemCredentialProvider.getCredentialProvider(Component.eucalyptus).getPrivateKey();
192
 
      Cipher cipher = Cipher.getInstance( "RSA/ECB/PKCS1Padding" );
193
 
      cipher.init( Cipher.DECRYPT_MODE, pk );
194
 
      cipher.doFinal( Hashes.hexToBytes( encryptedKey ) );
195
 
      cipher.doFinal( Hashes.hexToBytes( encryptedIV ) );
196
 
    } catch ( Exception ex ) {
197
 
      throw new EucalyptusCloudException( "Invalid Manifest: Failed to recover keys.", ex );
198
 
    }
199
 
  }
 
98
 
 
99
        public static void checkValid( ImageInfo imgInfo ) {
 
100
                String[] parts = imgInfo.getImageLocation().split( "/" );
 
101
                CheckImageType check = new CheckImageType();
 
102
                check.setUserId( imgInfo.getImageOwnerId( ) );
 
103
                check.setBucket( parts[ 0 ] );
 
104
                check.setKey( parts[ 1 ] );
 
105
                RemoteDispatcher.lookupSingle( Component.walrus ).dispatch( check );
 
106
        }
 
107
 
 
108
        public static void triggerCaching( ImageInfo imgInfo ) {
 
109
                String[] parts = imgInfo.getImageLocation().split( "/" );
 
110
                CacheImageType cache = new CacheImageType();
 
111
                cache.setUserId( imgInfo.getImageOwnerId( ) );
 
112
                cache.setBucket( parts[ 0 ] );
 
113
                cache.setKey( parts[ 1 ] );
 
114
                RemoteDispatcher.lookupSingle( Component.walrus ).dispatch( cache );
 
115
        }
 
116
 
 
117
        public static void invalidate( ImageInfo imgInfo ) {
 
118
                String[] parts = imgInfo.getImageLocation().split( "/" );
 
119
                imgInfo.setImageState( "deregistered" );
 
120
                try {
 
121
                        RemoteDispatcher.lookupSingle( Component.walrus ).dispatch( new FlushCachedImageType( parts[ 0 ], parts[ 1 ] ) );
 
122
                } catch ( Exception e ) {}
 
123
        }
 
124
 
 
125
        public static Document getManifestData( String userId, String bucketName, String objectName ) throws EucalyptusCloudException {
 
126
                GetObjectResponseType reply = null;
 
127
                try {
 
128
                        GetObjectType msg = new GetObjectType( bucketName, objectName, true, false, true );
 
129
                        msg.setUserId( userId );
 
130
 
 
131
                        reply = ( GetObjectResponseType ) RemoteDispatcher.lookupSingle( Component.walrus ).send( msg );
 
132
                }
 
133
                catch ( Exception e ) {
 
134
                        throw new EucalyptusCloudException( "Failed to read manifest file: " + bucketName + "/" + objectName, e );
 
135
                }
 
136
 
 
137
                Document inputSource = null;
 
138
                try {
 
139
                        DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
 
140
                        inputSource = builder.parse( new ByteArrayInputStream( reply.getBase64Data().getBytes() ) );
 
141
                }
 
142
                catch ( Exception e ) {
 
143
                        throw new EucalyptusCloudException( "Failed to read manifest file: " + bucketName + "/" + objectName, e );
 
144
                }
 
145
                return inputSource;
 
146
        }
 
147
 
 
148
        public static GetBucketAccessControlPolicyResponseType getBucketAcl( RegisterImageType request, String[] imagePathParts ) throws EucalyptusCloudException {
 
149
                GetBucketAccessControlPolicyType getBukkitInfo = Admin.makeMsg( GetBucketAccessControlPolicyType.class, request );
 
150
                if(getBukkitInfo != null) {
 
151
                        getBukkitInfo.setBucket( imagePathParts[ 0 ] );
 
152
                        GetBucketAccessControlPolicyResponseType reply = ( GetBucketAccessControlPolicyResponseType ) RemoteDispatcher.lookupSingle( Component.walrus ).send( getBukkitInfo );          
 
153
                        return reply;
 
154
                }
 
155
                return null;
 
156
        }
 
157
 
 
158
        public static void verifyManifestIntegrity( final ImageInfo imgInfo ) throws EucalyptusCloudException {
 
159
                String[] imagePathParts = imgInfo.getImageLocation().split( "/" );
 
160
                GetObjectResponseType reply = null;
 
161
                GetObjectType msg = new GetObjectType( imagePathParts[ 0 ], imagePathParts[ 1 ], true, false, true );
 
162
                msg.setUserId( Component.eucalyptus.name() );
 
163
                msg.setEffectiveUserId( Component.eucalyptus.name() );
 
164
                try {
 
165
                        reply = ( GetObjectResponseType ) ServiceDispatcher.lookupSingle( Component.walrus ).send( msg );
 
166
                } catch ( EucalyptusCloudException e ) {
 
167
                        ImageManager.LOG.error( e );
 
168
                        ImageManager.LOG.debug( e, e );
 
169
                        throw new EucalyptusCloudException( "Invalid manifest reference: " + imgInfo.getImageLocation(), e );
 
170
                }
 
171
 
 
172
                if ( reply == null || reply.getBase64Data() == null ) throw new EucalyptusCloudException( "Invalid manifest reference: " + imgInfo.getImageLocation() );
 
173
                XMLParser parser = new XMLParser( reply.getBase64Data() );
 
174
                String encryptedKey = parser.getValue( "//ec2_encrypted_key" );
 
175
                String encryptedIV = parser.getValue( "//ec2_encrypted_iv" );
 
176
                String signature = parser.getValue( "//signature" );
 
177
                String image = parser.getXML( "image" );
 
178
                String machineConfiguration = parser.getXML( "machine_configuration" );
 
179
 
 
180
                List<String> aliases = Lists.newArrayList();
 
181
                try {
 
182
                        for( X509Cert x : CredentialProvider.getUser( imgInfo.getImageOwnerId( ) ).getCertificates( ) ) {
 
183
                                aliases.add( x.getAlias( ) );
 
184
                        }
 
185
                } catch ( NoSuchUserException e ) {
 
186
                        throw new EucalyptusCloudException( "Invalid Manifest: Failed to verify signature because of missing (deleted?) user certificate.", e );
 
187
                }
 
188
                boolean found = false;
 
189
                for ( String alias : aliases )
 
190
                        found |= ImageUtil.verifyManifestSignature( signature, alias, machineConfiguration + image );
 
191
                if ( !found ) throw new EucalyptusCloudException( "Invalid Manifest: Failed to verify signature." );
 
192
 
 
193
                try {
 
194
                        PrivateKey pk = SystemCredentialProvider.getCredentialProvider(Component.eucalyptus).getPrivateKey();
 
195
                        Cipher cipher = Cipher.getInstance( "RSA/ECB/PKCS1Padding" );
 
196
                        cipher.init( Cipher.DECRYPT_MODE, pk );
 
197
                        cipher.doFinal( Hashes.hexToBytes( encryptedKey ) );
 
198
                        cipher.doFinal( Hashes.hexToBytes( encryptedIV ) );
 
199
                } catch ( Exception ex ) {
 
200
                        throw new EucalyptusCloudException( "Invalid Manifest: Failed to recover keys.", ex );
 
201
                }
 
202
        }
200
203
 
201
204
}