def mount(self, passwd=None): if self.mountpoint and os.path.ismount(self.mountpoint): raise Exception("Virtual disk already mounted") signals.emit("filesystems", "pre_mount", self) if not os.path.isdir(os.path.join("/media", self.id)): os.makedirs(os.path.join("/media", self.id)) mount_point = self.mountpoint if self.mountpoint else os.path.join("/media", self.id) # Find a free loopback device and mount loop = losetup.find_unused_loop_device() loop.mount(str(self.path), offset=1048576) if self.crypt and passwd: # If it's an encrypted virtual disk, decrypt first then mount s = crypto.luks_open(loop.device, self.id, passwd) if s != 0: loop.unmount() raise Exception("Failed to decrypt %s with errno %s" % (self.id, str(s))) s = libc.mount(ctypes.c_char_p(os.path.join("/dev/mapper", self.id)), ctypes.c_char_p(mount_point), ctypes.c_char_p(self.fstype), 0, ctypes.c_char_p("")) if s == -1: crypto.luks_close(self.id) loop.unmount() raise Exception("Failed to mount %s: %s" % (self.id, os.strerror(ctypes.get_errno()))) elif self.crypt and not passwd: raise Exception("Must provide password to decrypt encrypted container") else: s = libc.mount(ctypes.c_char_p(loop.device), ctypes.c_char_p(mount_point), ctypes.c_char_p(self.fstype), 0, ctypes.c_char_p("")) if s == -1: loop.unmount() raise Exception("Failed to mount %s: %s" % (self.id, os.strerror(ctypes.get_errno()))) signals.emit("filesystems", "post_mount", self) self.mountpoint = mount_point
def encrypt(self, passwd, cipher="", keysize=0, mount=False): cipher = cipher or config.get("filesystems", "cipher") or "aes-xts-plain64" keysize = keysize or config.get("filesystems", "keysize") or 256 os.rename(self.path, os.path.join(config.get("filesystems", "vdisk_dir"), self.id+".crypt")) self.path = os.path.join(config.get("filesystems", "vdisk_dir"), self.id+".crypt") # Find an open loopback device and mount loop = losetup.find_unused_loop_device() loop.mount(str(self.path), offset=1048576) # Encrypt the file inside the loopback and mount s = crypto.luks_format(loop.device, passwd, cipher, int(keysize)) if s != 0: loop.unmount() os.rename(self.path, os.path.join(config.get("filesystems", "vdisk_dir"), self.id+".img")) raise Exception("Failed to encrypt %s with errno %s"%(self.id, str(s))) s = crypto.luks_open(loop.device, self.id, passwd) if s != 0: loop.unmount() raise Exception("Failed to decrypt %s with errno %s"%(self.id, str(s))) # Create a filesystem inside the encrypted device s = shell("mkfs.ext4 /dev/mapper/%s" % self.id) crypto.luks_close(self.id) loop.unmount() if s["code"] != 0: raise Exception("Failed to format loop device: %s" % s["stderr"]) self.crypt = True if mount: self.mount(passwd)
def mount(self, fs, passwd=''): if not os.path.isdir(os.path.join('/media', fs.name)): os.mkdirs(os.path.join('/media', fs.name)) if fs.fstype in ['crypt', 'vdisk', 'loop']: dev = losetup.find_unused_loop_device() dev.mount(fs.img) if fs.fstype == 'crypt': s = shell_cs('echo "%s" | cryptsetup luksOpen %s %s'%(passwd,dev.device,fs.name), stderr=True) if s[0] != 0: dev.unmount() raise Exception('Failed to decrypt %s: %s'%(fs.name, s[1])) s = shell_cs('mount /dev/mapper/%s %s'%(fs.name, os.path.join('/media', fs.name)), stderr=True) if s[0] != 0: shell('cryptsetup luksClose %s'%fs.name) dev.unmount() raise Exception('Failed to mount %s: %s'%(fs.name, s[1])) else: s = shell_cs('mount %s %s'%(dev.device, os.path.join('/media', fs.name)), stderr=True) if s[0] != 0: dev.unmount() raise Exception('Failed to mount %s: %s'%(fs.name, s[1])) apis.poicontrol(self.app).add(fs.name, 'vdisk', fs.mount, 'filesystems', False) else: s = shell_cs('mount %s %s'%(fs.dev, os.path.join('/media', fs.name)), stderr=True) if s[0] != 0: raise Exception('Failed to mount %s: %s'%(fs.name, s[1])) apis.poicontrol(self.app).add(fs.name, 'disk', fs.mount, 'filesystems', False)
def encrypt_vdisk(self, fs, passwd, opts={'cipher': 'aes-xts-plain64', 'keysize': '256', 'hash': 'sha1'}, move=True, mount=False): opts = '-c %s -s %s -h %s'%(opts['cipher'], str(opts['keysize']), opts['hash']) l = losetup.get_loop_devices() if move: os.rename(os.path.join('/vdisk', fs.name+'.img'), os.path.join('/vdisk', fs.name+'.crypt')) dev = losetup.find_unused_loop_device() dev.mount(os.path.join('/vdisk', fs.name+'.crypt')) fs.img = os.path.join('/vdisk', fs.name+'.crypt') s = shell_cs('echo "%s" | cryptsetup %s luksFormat %s'%(passwd,opts,dev.device), stderr=True) if s[0] != 0: if move: dev.unmount() os.rename(os.path.join('/vdisk', fs.name+'.crypt'), os.path.join('/vdisk', fs.name+'.img')) raise Exception('Failed to encrypt %s: %s'%(fs.name, s[1])) fs.fstype = 'crypt' s = shell_cs('echo "%s" | cryptsetup luksOpen %s %s'%(passwd,dev.device,fs.name), stderr=True) if s[0] != 0: dev.unmount() raise Exception('Failed to decrypt %s: %s'%(fs.name, s[1])) s = shell_cs('mkfs.ext4 /dev/mapper/%s'%fs.name, stderr=True) shell('cryptsetup luksClose %s'%fs.name) dev.unmount() if s[0] != 0: raise Exception('Failed to format loop device: %s'%s[1]) if mount: self.mount(fs, passwd)
def create(self, mount=False): vdisk_dir = config.get("filesystems", "vdisk_dir") if not os.path.exists(os.path.join(config.get("filesystems", "vdisk_dir"))): os.mkdir(os.path.join(config.get("filesystems", "vdisk_dir"))) self.path = str(os.path.join(vdisk_dir, self.id+".img")) if os.path.exists(self.path): raise Exception("This virtual disk already exists") signals.emit("filesystems", "pre_add", self) # Create an empty file matching disk size with open(self.path, "wb") as f: written = 0 with file("/dev/zero", "r") as zero: while self.size > written: written += 1024 f.write(zero.read(1024)) # Get a free loopback device and mount loop = losetup.find_unused_loop_device() loop.mount(str(self.path), offset=1048576) # Make a filesystem s = shell("mkfs.ext4 %s" % loop.device) if s["code"] != 0: raise Exception("Failed to format loop device: %s" % s["stderr"]) loop.unmount() signals.emit("filesystems", "pre_add", self) if mount: self.mount()
def encrypt_vdisk(self, fs, passwd, opts={ 'cipher': 'aes-xts-plain64', 'keysize': '256', 'hash': 'sha1' }, move=True, mount=False): opts = '-c %s -s %s -h %s' % (opts['cipher'], str( opts['keysize']), opts['hash']) l = losetup.get_loop_devices() if move: os.rename(os.path.join('/vdisk', fs.name + '.img'), os.path.join('/vdisk', fs.name + '.crypt')) dev = losetup.find_unused_loop_device() dev.mount(os.path.join('/vdisk', fs.name + '.crypt')) fs.img = os.path.join('/vdisk', fs.name + '.crypt') s = shell_csin('cryptsetup %s luksFormat %s' % (opts, dev.device), passwd, stderr=True) if s[0] != 0: if move: dev.unmount() os.rename(os.path.join('/vdisk', fs.name + '.crypt'), os.path.join('/vdisk', fs.name + '.img')) raise Exception('Failed to encrypt %s: %s' % (fs.name, s[1])) fs.fstype = 'crypt' s = shell_csin('cryptsetup luksOpen %s %s' % (dev.device, fs.name), passwd, stderr=True) if s[0] != 0: dev.unmount() raise Exception('Failed to decrypt %s: %s' % (fs.name, s[1])) s = shell_cs('mkfs.ext4 /dev/mapper/%s' % fs.name, stderr=True) shell('cryptsetup luksClose %s' % fs.name) dev.unmount() if s[0] != 0: raise Exception('Failed to format loop device: %s' % s[1]) if mount: self.mount(fs, passwd)
def add_vdisk(self, name, size, mkfs=True, mount=False): with open(os.path.join('/vdisk', name+'.img'), 'wb') as f: written = 0 while (int(size)*1048576) > written: written += 1024 f.write(os.urandom(1024)) f.close() if mkfs: l = losetup.find_unused_loop_device() l.mount(os.path.join('/vdisk', name+'.img')) s = shell_cs('mkfs.ext4 %s'%l.device) if s[0] != 0: raise Exception('Failed to format loop device: %s'%s[1]) l.unmount() fs = Filesystem() fs.name = name fs.img = os.path.join('/vdisk', name+'.img') fs.fstype = 'vdisk' if mount: self.mount(fs) return fs
def add_vdisk(self, name, size, mkfs=True, mount=False): with open(os.path.join('/vdisk', name + '.img'), 'wb') as f: written = 0 while (int(size) * 1048576) > written: written += 1024 f.write(os.urandom(1024)) f.close() if mkfs: l = losetup.find_unused_loop_device() l.mount(os.path.join('/vdisk', name + '.img')) s = shell_cs('mkfs.ext4 %s' % l.device) if s[0] != 0: raise Exception('Failed to format loop device: %s' % s[1]) l.unmount() fs = Filesystem() fs.name = name fs.img = os.path.join('/vdisk', name + '.img') fs.fstype = 'vdisk' if mount: self.mount(fs) return fs
def mount(self, fs, passwd=''): if not os.path.isdir(os.path.join('/media', fs.name)): os.makedirs(os.path.join('/media', fs.name)) if fs.fstype in ['crypt', 'vdisk', 'loop']: dev = losetup.find_unused_loop_device() dev.mount(fs.img) if fs.fstype == 'crypt': s = shell_csin('cryptsetup luksOpen %s %s' % (dev.device, fs.name), passwd, stderr=True) if s[0] != 0: dev.unmount() raise Exception('Failed to decrypt %s: %s' % (fs.name, s[1])) s = shell_cs('mount /dev/mapper/%s %s' % (fs.name, os.path.join('/media', fs.name)), stderr=True) if s[0] != 0: shell('cryptsetup luksClose %s' % fs.name) dev.unmount() raise Exception('Failed to mount %s: %s' % (fs.name, s[1])) else: s = shell_cs('mount %s %s' % (dev.device, os.path.join('/media', fs.name)), stderr=True) if s[0] != 0: dev.unmount() raise Exception('Failed to mount %s: %s' % (fs.name, s[1])) apis.poicontrol(self.app).add(fs.name, 'vdisk', fs.mount, 'filesystems', 'gen-storage', False) else: s = shell_cs('mount %s %s' % (fs.dev, os.path.join('/media', fs.name)), stderr=True) if s[0] != 0: raise Exception('Failed to mount %s: %s' % (fs.name, s[1])) apis.poicontrol(self.app).add(fs.name, 'disk', fs.mount, 'filesystems', 'gen-storage', False)