Пример #1
0
    def POST_bootstrap(self):
        # Get the duration.
        # TODO: check when no duration is received, or an invalid duration is received.
        duration = int(request.params.get('duration', 0))

        # Remove all data from DB.
        self.clear_deployment()

        # Setup initial configurations for each device type.
        BluetoothSKADevice.bootstrap()
        ADBSKADevice.bootstrap()

        # Create server keys.
        server_keys = credentials.ServerCredentials.create_object(app_globals.cloudlet.credentials_type,
                                                                  app_globals.cloudlet.data_folder)
        server_keys.generate_and_save_to_file()

        # Create RADIUS server certificate.
        radius_server = radius.RadiusServer(app_globals.cloudlet.radius_users_file,
                                            app_globals.cloudlet.radius_certs_folder,
                                            app_globals.cloudlet.radius_eap_conf_file)
        radius_server.generate_certificate()

        # Set up a new deployment.
        deployment = Deployment()
        deployment.auth_start = datetime.datetime.now()
        deployment.auth_duration = duration
        deployment.save()

        # Go to the main page.
        return h.redirect_to(controller='devices', action='list')
Пример #2
0
def generate_migration_device_credentials(device_id, connection_id, svm_id):
    print 'Preparing credentials and cloudlet information.'
    device_credentials = PairedDeviceDataBundle()
    try:
        # Get the new credentials for the device on the current deployment.
        print 'Generating credentials for device that will migrate to our cloudlet.'
        deployment = Deployment.get_instance()
        device_type = 'mobile'
        device_keys = deployment.pair_device(device_id, connection_id, device_type)

        # Configure the associated instance.
        paired_device = PairedDevice.by_id(device_id)
        paired_device.instance = svm_id
        paired_device.save()

        # Bundle the credentials for a newly paired device.
        print 'Bundling credentials for device.'
        device_credentials.auth_password = device_keys.auth_password
        device_credentials.server_public_key = device_keys.server_public_key
        device_credentials.device_private_key = device_keys.private_key
        device_credentials.load_certificate(deployment.radius_server.cert_file_path)
    except DeviceAlreadyPairedException as e:
        print 'Credentials not generated: ' + e.message

    # Bundle common cloudlet information.
    print 'Bundling cloudlet information for device.'
    cloudlet = get_cloudlet_instance()
    device_credentials.cloudlet_name = Cloudlet.get_hostname()
    device_credentials.cloudlet_fqdn = Cloudlet.get_fqdn()
    device_credentials.cloudlet_encryption_enabled = cloudlet.api_encrypted
    device_credentials.ssid = cloudlet.ssid

    print 'Returning credentials and cloudlet data.'
    return device_credentials.__dict__
Пример #3
0
    def GET_clear(self):
        deployment = Deployment.get_instance()
        deployment.clear()
        deployment.remove()

        # Go to the main page.
        return h.redirect_to(controller='devices', action='list')
Пример #4
0
    def GET_list(self):
        c.devices_active = 'active'
        page = DevicesPage()

        # Ensure the device types are initialized.
        BluetoothSKADevice.initialize(app_globals.cloudlet.data_folder)
        ADBSKADevice.initialize(app_globals.cloudlet.data_folder)

        # Get the overall deployment info.
        page.deployment = Deployment.get_instance()
        if page.deployment.auth_start is None:
            page.deployment_auth_start = 'not set'
            page.deployment_auth_duration = 'not set'
            page.deployment_auth_end = 'not set'
        else:
            page.deployment_auth_start = page.deployment.auth_start.strftime(
                '%Y-%m-%d %X')
            page.deployment_auth_duration = page.deployment.auth_duration
            page.deployment_auth_end = (
                page.deployment.auth_start +
                datetime.timedelta(minutes=page.deployment.auth_duration)
            ).strftime('%Y-%m-%d %X')

        # Get the paired devices.
        page.paired_devices = PairedDevice.by_type('mobile')

        # Get the paired cloudlets.
        page.paired_cloudlets = PairedDevice.by_type('cloudlet')

        return page.render()
Пример #5
0
    def GET_authorize(self, did):
        connection_id = request.params.get('cid', None)
        auth_password = request.params.get('auth_password', None)
        enc_password = request.params.get('enc_password', None)

        # Create a new paired device with the id info we just received.
        print 'Adding paired device to DB.'
        paired_device = PairedDevice()
        paired_device.device_id = did
        paired_device.connection_id = connection_id
        paired_device.password = enc_password

        # By default, authorization for a device will be the same as the deployment info.
        deployment = Deployment.find_one()
        paired_device.auth_start = deployment.auth_start
        paired_device.auth_duration = deployment.auth_duration
        paired_device.auth_enabled = True

        # Store the paired device.
        paired_device.save()

        # Store the new device credentials in the RADIUS server.
        radius_server = radius.RadiusServer(app_globals.cloudlet.radius_users_file,
                                            app_globals.cloudlet.radius_certs_folder,
                                            app_globals.cloudlet.radius_eap_conf_file)
        radius_server.add_user_credentials(paired_device.device_id, auth_password)

        # Go to the main page.
        print 'Device added to DB.'
        return ajaxutils.JSON_OK
Пример #6
0
    def clear_deployment(self):
        # Remove users from RADIUS server.
        print 'Removing paired devices from RADIUS server.'
        devices = PairedDevice.find()
        device_ids = []
        for device in devices:
            device_ids.append(device.device_id)
            stop_associated_instance(device.device_id)

        radius_server = radius.RadiusServer(app_globals.cloudlet.radius_users_file,
                                            app_globals.cloudlet.radius_certs_folder,
                                            app_globals.cloudlet.radius_eap_conf_file)
        radius_server.remove_user_credentials(device_ids)

        # Remove all data from DB.
        print 'Clearing up database.'
        PairedDevice.clear_data()
        Deployment.remove()
Пример #7
0
    def POST_bootstrap(self):
        # Get the duration.
        # TODO: check when no duration is received, or an invalid duration is received.
        duration = int(request.params.get('duration', 0))

        # Setup initial configurations for each device type.
        BluetoothSKADevice.bootstrap()
        ADBSKADevice.bootstrap()

        deployment = Deployment.get_instance()
        deployment.bootstrap(duration)

        # Go to the main page.
        return h.redirect_to(controller='devices', action='list')
Пример #8
0
def abort_migration(svm_id):
    # Get the id and load the metadata for this SVM.
    migrated_svm = ServiceVM.by_id(svm_id, only_find_ready_ones=False)
    if not migrated_svm:
        raise SVMNotFoundException("No SVM found with the given id {}".format(svm_id))

    print 'Aborting migration, cleaning up...'
    migrated_svm.stop()

    # Unpairing all paired devices that were using this VM.
    deployment = Deployment.get_instance()
    paired_devices = PairedDevice.by_instance(svm_id)
    for paired_device in paired_devices:
        deployment.unpair_device(paired_device.device_id)
    print 'Cleanup finished.'
Пример #9
0
    def GET_pair(self, id):
        device_type = 'mobile'

        connection = request.params.get('connection', None)
        if connection is None:
            connection = 'bt'

        curr_device = None
        try:
            # Create a device depending on the type.
            if connection == 'bt':
                port = request.params.get('port', None)
                name = request.params.get('name', None)
                curr_device = BluetoothSKADevice({
                    'host': id,
                    'port': int(port),
                    'name': name
                })
            else:
                curr_device = ADBSKADevice(id)

            # Now the pairing process will be followed, generating all required credentials.
            # The first step is to connect to the device.
            successful_connection = curr_device.connect()
            if not successful_connection:
                raise Exception(
                    "Could not connect to device with id {}.".format(id))

            # Get the device id.
            id_data = curr_device.get_data({'device_id': 'none'})
            device_internal_id = id_data['device_id']
            print 'Device id: ' + device_internal_id

            # Pair the device, send the credentials, and clear their local files.
            deployment = Deployment.get_instance()
            device_keys = deployment.pair_device(device_internal_id,
                                                 curr_device.get_name(),
                                                 device_type)
            deployment.send_paired_credentials(curr_device, device_keys)
            deployment.clear_device_keys(device_keys)
        except Exception, e:
            return ajaxutils.show_and_return_error_dict(e.message)
Пример #10
0
    def GET_list(self):
        c.devices_active = 'active'
        page = DevicesPage()

        # Ensure the device types are initialized.
        BluetoothSKADevice.initialize(app_globals.cloudlet.data_folder)
        ADBSKADevice.initialize(app_globals.cloudlet.data_folder)

        # Get the overall deployment info.
        page.deployment = Deployment.find_one()
        if page.deployment is None:
            page.deployment_auth_start = 'not set'
            page.deployment_auth_duration = 'not set'
            page.deployment_auth_end = 'not set'
        else:
            page.deployment_auth_start = page.deployment.auth_start.strftime('%Y-%m-%d %X')
            page.deployment_auth_duration = page.deployment.auth_duration
            page.deployment_auth_end = (page.deployment.auth_start + datetime.timedelta(minutes=page.deployment.auth_duration)).strftime('%Y-%m-%d %X')

        # Get the paired devices.
        page.paired_devices = PairedDevice.find()

        return page.render()
Пример #11
0
def migrate_svm(svm_id, remote_host, remote_ip, encrypted):
    # Find the SVM.
    svm = ServiceVM.by_id(svm_id)
    if svm is None:
        raise MigrationException("SVM with id %s was not found" % str(svm_id))

    # remote_host has host and port.
    print 'VM found: ' + str(svm)
    print 'Migrating to remote cloudlet: ' + remote_host

    # Transfer the metadata.
    print 'Starting metadata file transfer...'
    payload = {'svm_json_string': svm.to_json_string()}
    result, response_text = __send_api_command(remote_host, MIGRATE_METADATA_CMD, encrypted, payload)
    print 'Metadata was transferred: ' + str(result)

    # We pause the VM before transferring its disk and memory state.
    print 'Pausing VM...'
    was_pause_successful = svm.pause()
    if not was_pause_successful:
        raise MigrationException("Cannot pause VM: %s" % str(svm_id))
    print 'VM paused.'

    try:
        # Transfer the disk image file.
        print 'Starting disk image file transfer...'
        payload = {'id': svm_id}
        disk_image_full_path = os.path.abspath(svm.vm_image.disk_image)
        files = {'disk_image_file': open(disk_image_full_path, 'rb')}
        result, response_text = __send_api_command(remote_host, MIGRATE_DISK_CMD, encrypted, payload, files=files)
        print 'Disk image file was transferred: ' + str(result)

        # Do the memory state migration.
        remote_host_name = remote_host.split(':')[0]
        remote_host_port = remote_host.split(':')[1]
        print 'Migrating through libvirtd to {} ({})'.format(remote_host_name, remote_ip)
        svm.migrate(remote_host_name)
        print 'Memory migration through libvirtd completed'

        # If needed, ask the remote cloudlet for credentials for the devices associated to the SVM.
        devices = PairedDevice.by_instance(svm_id)
        for device in devices:
            # So that the paired device has a connection id on the remote cloudlet, we set it as this cloudlet's id
            # plus the device id. Connection id is commonly used with USB or Bluetooth pairing as a way to identify
            # the ID of the physical connection used when pairing. This gives similar auditing possibilities.
            print 'Starting remote credentials generation for device {}...'.format(device.device_id)
            deployment = Deployment.get_instance()
            connection_id = deployment.cloudlet.get_id() + "-" + device.device_id
            payload = {'device_id': device.device_id, 'connection_id': connection_id, 'svm_id': svm_id}
            response, serialized_credentials = __send_api_command(remote_host, MIGRATE_CREDENTIALS_CMD, encrypted, payload)

            # De-serializing generated data.
            print serialized_credentials
            paired_device_data_bundle = PairedDeviceDataBundle()
            paired_device_data_bundle.fill_from_dict(json.loads(serialized_credentials))
            paired_device_data_bundle.cloudlet_ip = remote_ip
            paired_device_data_bundle.cloudlet_port = remote_host_port
            print 'Remote credentials to be sent: ' + str(paired_device_data_bundle)

            # Create the appropriate command.
            data_contains_only_cloudlet_info = paired_device_data_bundle.auth_password is None
            if data_contains_only_cloudlet_info:
                device_command = ConnectToNewCloudletMessage(paired_device_data_bundle)
            else:
                device_command = AddTrustedCloudletDeviceMessage(paired_device_data_bundle)

            # Add device and service id data, and store the message to be picked up by the phone.
            device_command.device_id = device.device_id
            device_command.service_id = svm.service_id
            device_command.save()
    except Exception as e:
        # If migration fails, ask remote to remove svm.
        print 'Error migrating: {}'.format(e.message)
        print 'Requesting migration abort for cleanup...'
        payload = {'svm_id': svm_id}
        result, response_text = __send_api_command(remote_host, MIGRATE_ABORT_CMD, encrypted, payload)

        # Remove pending migration messages.
        devices = PairedDevice.by_instance(svm_id)
        for device in devices:
            AddTrustedCloudletDeviceMessage.clear_messages(device.device_id)

        print 'Migration aborted: ' + str(result)
        raise e

    # Notify remote cloudlet that migration finished.
    print 'Asking remote cloudlet to resume migrated VM.'
    payload = {'id': svm_id}
    result, response_text = __send_api_command(remote_host, MIGRATE_RESUME_CMD, encrypted, payload)
    print 'Cloudlet notified: ' + str(result)

    # Remove the local VM.
    svm = ServiceVM.by_id(svm_id)
    svm.stop()
Пример #12
0
    def GET_reauthorize(self, id):
        deployment = Deployment.get_instance()
        deployment.reauthorize_device(id)

        # Go to the main page.
        return h.redirect_to(controller='devices', action='list')
Пример #13
0
    def POST_pair(self):
        # Generate secret to display
        device_type = 'cloudlet'
        secret = request.params.get('secret', None)
        ssid = request.params.get('ssid', None)
        psk = request.params.get('psk', None)

        print ssid + '-' + psk + '-' + secret

        connection = request.params.get('connection', None)
        if connection is None:
            connection = 'wifi'

        remote_cloudlet = None
        try:
            if connection == 'wifi':
                # Disable any lingering ad-hoc connections.
                wifi_adhoc.disable_adhoc_mode()

                # Set up the ad-hoc network.
                wifi_adhoc.configure_wpa2_params(ssid, psk)
                wifi_adhoc.enable_adhoc_mode(SKA_CLIENT_IP)

                # Connect to the server (cloudlet) in the network.
                remote_cloudlet_name = "WiFiServer"
                remote_cloudlet = WiFiSKADevice(
                    {
                        'host': SKA_SERVER_IP,
                        'port': int(SKA_SERVER_PORT),
                        'name': remote_cloudlet_name,
                        'secret': secret
                    },
                    fqdn=Cloudlet.get_fqdn())

                print 'Connecting to cloudlet server'
                successful_connection = remote_cloudlet.connect()
                if not successful_connection:
                    raise Exception(
                        "Could not connect to cloudlet with id {}.".format(
                            ssid))
                else:
                    print 'Connected to cloudlet server'

            # TODO: test this.
            # Get the device id.
            id_data = remote_cloudlet.get_data({'device_id': 'none'})
            device_internal_id = id_data['device_id']
            print 'Device id: ' + device_internal_id

            # Pair the device, send the credentials, and clear their local files.
            deployment = Deployment.get_instance()
            device_keys = deployment.pair_device(device_internal_id,
                                                 remote_cloudlet.get_name(),
                                                 device_type)
            deployment.send_paired_credentials(remote_cloudlet, device_keys)
            deployment.clear_device_keys(device_keys)

        except Exception, e:
            error_message = 'Error connecting or pairing: (' + type(
                e).__name__ + '): ' + str(e)
            print error_message
            return ajaxutils.show_and_return_error_dict(error_message)