70 lines
3.7 KiB
Python
70 lines
3.7 KiB
Python
#!/usr/bin/env python
|
|
import requests, platform, subprocess, config, logging, simplejson as json, argparse, base64
|
|
from subprocess import call
|
|
|
|
# You must initialize logging, otherwise you'll not see debug output.
|
|
logging.basicConfig(level=logging.INFO,format='%(asctime)s - [%(levelname)s] %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
|
|
|
|
def request(resource, method='GET', data=None):
|
|
if data is None:
|
|
data = ''
|
|
url = 'https://127.0.0.1/api/v1.0/{}'.format(resource)
|
|
logging.debug('Request URL: {}'.format(url))
|
|
logging.debug('Request Data: {}'.format(data))
|
|
logging.debug('CA Certificate Path: {}'.format(config.CA_CERT_PATH))
|
|
if not config.CA_CERT_PATH:
|
|
config.CA_CERT_PATH = False
|
|
else:
|
|
config.CA_CERT_PATH = '{}'.format(config.CA_CERT_PATH)
|
|
r = requests.request(
|
|
method,
|
|
url,
|
|
data=json.dumps(data),
|
|
headers={'Content-Type': "application/json"},
|
|
auth=('root', '{}'.format(config.FREENAS_ROOT_PASSWORD)),
|
|
verify=config.CA_CERT_PATH
|
|
)
|
|
logging.debug('Request Status Code: {}'.format(r.status_code))
|
|
if r.ok:
|
|
try:
|
|
logging.debug('Request Returned JSON: {}'.format(r.json()))
|
|
return {'ok': r.ok, 'status_code': r.status_code, 'response': r.json()}
|
|
except:
|
|
logging.debug('Request Returned Text: {}'.format(r.text))
|
|
return {'ok': r.ok, 'status_code': r.status_code, 'response': r.text}
|
|
raise ValueError(r)
|
|
|
|
# Create a small ramdrive to store our recovery keys temporarily
|
|
rc = call("mkdir /mnt/ramfs", shell=True)
|
|
rc = call("mdmfs -s 1m md /mnt/ramfs", shell=True)
|
|
|
|
# Send our unlock/mount script to the pi and execute it on the pi using ssh
|
|
rc = call("ssh {}@{} 'mkdir /mnt/FreeNASPoolKeys; echo -n {} | cryptsetup luksOpen {} FreeNASPoolKeys -d - && mount /dev/mapper/FreeNASPoolKeys /mnt/FreeNASPoolKeys'".format(config.KEY_HOST_USER, config.KEY_HOST, config.LUKS_PASSWORD, config.LUKS_VOLUME), shell=True)
|
|
|
|
# Now we can copy the keys to the ramfs
|
|
for poolName in config.POOL_NAMES:
|
|
#rc= call("scp {}@{}:/mnt/FreeNASPoolKeys/{}.recoveryKey /mnt/ramfs".format(config.KEY_HOST_USER, config.KEY_HOST, poolName), shell=True)
|
|
rc= call("scp {}@{}:/mnt/FreeNASPoolKeys/{}.passphrase /mnt/ramfs".format(config.KEY_HOST_USER, config.KEY_HOST, poolName), shell=True)
|
|
|
|
# We can close the luks volume now
|
|
rc = call("ssh {}@{} 'umount /mnt/FreeNASPoolKeys; cryptsetup luksClose FreeNASPoolKeys; rm -rf /mnt/FreeNASPoolKeys'".format(config.KEY_HOST_USER, config.KEY_HOST), shell=True)
|
|
|
|
# Loop through the pools and only unlock the locked ones
|
|
POOLS = request('storage/volume/', 'GET')
|
|
for pool in POOLS['response']:
|
|
if pool['is_decrypted'] == False:
|
|
#recovery_key = open('/mnt/ramfs/{}.recoveryKey'.format(pool['name']),'rb')
|
|
passphrase = open('/mnt/ramfs/{}.passphrase'.format(pool['name'])).read()
|
|
#recovery_key_binary = recovery_key.read()
|
|
#recovery_key_string = (base64.b64encode(recovery_key_binary)).decode('ascii')
|
|
#response = request('storage/volume/{}/unlock/'.format(pool['name']), 'POST', {'recovery_key': '{}'.format(recovery_key_string)})
|
|
response = request('storage/volume/{}/unlock/'.format(pool['name']), 'POST', {'passphrase': '{}'.format(passphrase)})
|
|
if response['ok']:
|
|
logging.info('Pool {} was unlocked successfully'.format(pool['name']))
|
|
else:
|
|
logging.error('Pool {} was NOT unlocked successfully'.format(pool['name']))
|
|
else:
|
|
logging.debug('Pool {} is already unlocked'.format(pool['name']))
|
|
|
|
# wipe the files, unmount the ramfs, and remove the folder
|
|
rc = call("umount -f /mnt/ramfs; rm -fP /mnt/ramfs/*; rmdir /mnt/ramfs", shell=True) |