Skip to content

Instantly share code, notes, and snippets.

@dberzano
Created January 30, 2015 16:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dberzano/c474215151d1ff002929 to your computer and use it in GitHub Desktop.
Save dberzano/c474215151d1ff002929 to your computer and use it in GitHub Desktop.
Get CernVM Online context from API
#!/usr/bin/env python
# Usage:
# cvm-context-api.py [--user-data] <context_id> [<context_key>]
import sys
import requests
import base64
import hashlib
from Crypto.Cipher import AES
def decrypt(intext, secret):
unb64 = base64.b64decode(intext)
if unb64[0:8] != 'Salted__':
raise Exception('cannot decrypt: magic mismatch')
salt = unb64[8:16]
salted_secret = str(secret) + salt
hashes = [ hashlib.md5(salted_secret).digest() ]
for i in range(1,3):
hashes.append(hashlib.md5(hashes[i-1]+salted_secret).digest())
key = hashes[0] + hashes[1]
iv = hashes[2]
cypher = AES.new(key, AES.MODE_CFB, iv)
decrypted = cypher.decrypt(unb64[16:])
if decrypted.find('VM_CONTEXT_UUID=') < 0:
raise Exception('cannot decrypt: wrong password')
return decrypted
def main(argv):
opts = []
extra = []
for a in argv:
if a.startswith('--'):
opts.append(a)
else:
extra.append(a)
user_data = False
for o in opts:
if o == '--user-data':
user_data = True
context_id = extra[0]
if len(extra) > 1:
context_key = extra[1]
else:
context_key = None
apiurl = 'https://cernvm-online.cern.ch/api/context?uuid=&ver=&checksum=&context_id=%s' % \
context_id
r = requests.get(apiurl)
if r.text.startswith('ENCRYPTED:'):
if context_key is None:
raise Exception('context encrypted: password not provided')
context_enc = r.text[10:]
context = decrypt( r.text[10:], context_key )
else:
context = r.text
if user_data:
# do not print the raw context; print its embedded user-data, properly decoded
user_data_found = False
for l in context.splitlines(0):
if l.startswith('EC2_USER_DATA='):
print base64.b64decode(l[14:])
user_data_found = True
break
if user_data_found == False:
raise Exception('cannot extract user-data')
else:
print context
return 0
if __name__ == '__main__':
r = main(sys.argv[1:])
sys.exit(r)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment