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__
def GET_get_available_cloudlets(self): # Get a list of cloudlets in our current network. cloudlet_finder = finder.CloudletFinder() cloudlets = cloudlet_finder.find_cloudlets(seconds_to_wait=2) # Filter out ourselves from the list of cloudlets. current_cloudlet = Cloudlet.get_fqdn() print 'Current cloudlet: ' + current_cloudlet if current_cloudlet in cloudlets: del cloudlets[current_cloudlet] # Encode name, port and encryption info into string to be shown to user. cloudlet_info_dict = {} for cloudlet_name in cloudlets: cloudlet_info = cloudlets[cloudlet_name] encoded_cloudlet_info_to_display = cloudlet_name + ":" + str( cloudlet_info.port) + ":encryption-" + cloudlet_info.encryption encoded_cloudlet_info = cloudlet_info.address_string + ":" + cloudlet_name + ":" + str( cloudlet_info.port) + ":encryption-" + cloudlet_info.encryption cloudlet_info_dict[ encoded_cloudlet_info] = encoded_cloudlet_info_to_display print 'Available cloudlets: ' print cloudlet_info_dict return cloudlet_info_dict
def create_wifi_profile(self, message): print 'Creating Wi-Fi profile' with open("./wpa_supplicant/system-connection-template.ini", "r") as ini_file: file_data = ini_file.read() file_data = file_data.replace('$cloudlet-id', Cloudlet.get_id()) file_data = file_data.replace('$ssid', message['ssid']) file_data = file_data.replace('$name', message['ssid']) file_data = file_data.replace('$password', message['password']) file_data = file_data.replace('$ca-cert', message['server_cert_name']) filename = os.path.join("/etc/NetworkManager/system-connections", message['ssid']) print 'Writing Wi-Fi profile to file ' + filename with open(filename, "w") as profile: profile.write(file_data) if os.path.exists(filename): print 'Wi-Fi profile file created' else: print 'Wi-Fi profile file NOT created!' # The file needs to be r/w only by user (root) to be used by Network Manager. print 'Setting profile as read/write only by owner (root)' command = "sudo chmod 600 " + filename cmd = subprocess.Popen(command, shell=True, stdout=None) cmd.wait() print 'Permissions changed'
def POST_discover(self): try: secret = request.params.get('secret', None) print secret # Disable any lingering ad-hoc connections. wifi_adhoc.disable_adhoc_mode() # Enable ad-hoc mode. wifi_adhoc.enable_adhoc_mode(SKA_SERVER_IP) # Wait for messages. cloudlet = get_cloudlet_instance() server = WiFiSKAServer( host=SKA_SERVER_IP, port=SKA_SERVER_PORT, secret=secret, files_path=cloudlet.cloudletCredentialsFolder, pairing_handler=PairingHandler(), fqdn=Cloudlet.get_fqdn()) server.wait_for_messages() except Exception, e: message = 'Error setting up connection or receiving data (' + type( e).__name__ + '): ' + str(e) print message return ajaxutils.show_and_return_error_dict(message)
def GET_index(self): # Mark the active tab. c.home_active = 'active' # Get current metadata. page = HomePage() ret = Cloudlet.system_information() page.machine_status = ret # Render the page with the grid. return page.render()
def GET_metadata(self): timelog.TimeLog.reset() timelog.TimeLog.stamp("Request received: get metadata.") ret = Cloudlet.system_information() if bool_param('services'): ret.services = Service.find() if bool_param('apps'): ret.apps = App.find() timelog.TimeLog.stamp("Sending response back to " + request.environ['REMOTE_ADDR']) return ret
def handle_incoming(self, command, message, files_path): return_code = 'ok' return_data = '' print 'Handling command ' + command if command == "receive_file": full_path = os.path.join( self.get_storage_folder_path(files_path, message), message['file_id']) if message['file_id'] == 'device.key': self.store_encryption_password(message['cloudlet_name'], full_path) elif message['file_id'] == radius.RADIUS_CERT_FILE_NAME: shutil.copy(full_path, '/etc/ca-certificates/') elif command == "receive_data": if 'command' not in message: raise Exception( 'Invalid message received: it does not contain a command field.' ) data_command = message['command'] print 'Handling data command ' + data_command if data_command == "wifi-profile": try: self.create_wifi_profile(message) except Exception as e: print 'Error creating Wi-Fi profile: ' + str(e) raise Exception(e.message) else: raise Exception('Unknown data command: ' + data_command) elif command == "send_data": if 'device_id' in message: return_code = 'send' return_data = ('device_id', Cloudlet.get_id()) else: error_message = 'Unrecognized data request: ' + str(message) print error_message raise Exception(error_message) elif command == "transfer_complete": return_code = 'transfer_complete' else: error_message = 'Unrecognized command: ' + message['wifi_command'] print error_message raise Exception(error_message) return return_code, return_data
def __send_api_command(host, command, encrypted, payload, headers={}, files={}): if encrypted: # We need to send our id so that the remote API will be able to decrypt our requests properly. headers['X-Device-ID'] = Cloudlet.get_id() if not encrypted: remote_url = 'http://{0}/api/{1}'.format(host, command) else: remote_url = 'http://{0}/api/command'.format(host) # Get the appropriate encryption password for this host. cloudlet_fqdn = host.split(':')[0] credentials = CloudletCredential.by_cloudlet_fqdn(cloudlet_fqdn) if not credentials: raise Exception('Credentials to encrypt communication to cloudlet with fqdn {} are not stored in the DB'.format(cloudlet_fqdn)) # Add all payload elements. command_string = command for param in payload: command_string += "&" + param + "=" + str(payload[param]) # Encrypt the command and add it as a param. encrypted_command = encryption.encrypt_message(command_string, credentials.encryption_password) payload = {} payload['command'] = encrypted_command req = requests.Request('POST', remote_url, data=payload, headers=headers, files=files) prepared = req.prepare() print remote_url session = requests.Session() response = session.send(prepared) if response.status_code != requests.codes.ok: raise Exception('Error sending request {}: {} - {}'.format(command, response.status_code, response.text)) response_text = response.text if encrypted and response.text and response.text != '': response_text = encryption.decrypt_message(response.text, credentials.encryption_password) return response, response_text
def GET_state(self): machine_state = Cloudlet.system_information() return machine_state
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)