Esempio n. 1
0
    def access(self, path, mode):
        """
        Forge authorization check

        Authorization is performed based on the repository path
        /neighborhood/project/repository

        To optimize access checking, a short-lived permission cache is used.
        The cache is only invoked if the file path minimally identifies a repo,
        and then only for the portion of the path that identifies the repo.

        Thus, /n/p/r/some/path/a and /n/p/r/some/path/b get the same entry
        from the cache: the most recent authorization check for the repository.
        """
        if mode & (os.R_OK | os.W_OK) == 0:
            return

        mo = AUTH_PATH_REGEX.match(path)
        if mo:
            apath = mo.group(1)
            uid, gid, pid = fuse_get_context()
            entry = self.perm_cache.get(uid, apath)
            if (mode & entry) != mode:
                user = self.perm_cache.get_user(uid)
                msg = "Authorization failure: user {} repository {} mode {}"
                LOG.warn(msg.format(user, apath, mode))
                raise FuseOSError(EACCES)
        else:
            uid, gid, pid = fuse_get_context()
            user = self.perm_cache.get_user(uid)
            msg = "Improper repository authorization request: user {} path {}"
            LOG.warn(msg.format(user, path))
            raise FuseOSError(EACCES)
Esempio n. 2
0
    def readdir(self, path, fh):
        ls = os.listdir(path)
        for entry in self.ignore_entries:
            if entry in ls: ls.remove(entry)

        out = ['.', '..'] + ls

        try:
            uid, gid, pid = fuse_get_context()
            comm = os.path.basename(os.readlink('/proc/%d/exe' % pid))
        except:
            comm = ''

        # for anything that starts with svn we pretend that there are no
        # property files
        if comm in self.comm_ignore:
            return out

        try:
            for name, prop_dict in self.client.proplist(path, depth=pysvn.depth.files):
                if  name == path:
                    name = ''
                else:
                    name = '#' + os.path.basename(name)
                for prop in prop_dict.keys():
                    out += ['.' + name + '#' + prop]
        except:
            pass

        return out
Esempio n. 3
0
    def rmdir(self, path):
        _path = path[1:]
        apath = os.path.join(self.tmp, _path)
        dpath = os.path.join(self.tmp, ".hgfs", _path)
        hpath = os.path.join(self.tmp, ".hgfs", _path + ".attr")

        try:
            status = os.rmdir(dpath)
        except:
            pass

        status = os.rmdir(apath)

        try:
            status = os.unlink(hpath)
        except:
            pass

        uid, gid, pid = fuse_get_context()
        username = pwd.getpwuid(uid)[0]

        dispatch(
            request(["--cwd", self.tmp, "commit", "-A", "-u", username, "-m", "hgfs[rmdir]: %s" % (_path), str(_path)])
        )
        if self.args.clone:
            dispatch(request(["--cwd", self.tmp, "push"]))

        return status
Esempio n. 4
0
    def getattr(self, path, fh=None):
        (uid, gid, pid) = fuse_get_context()

        working_path = path

        try:
            entry = self._get_entry(path)
        except EntryNotFoundError:
            return errno.ENOENT

        if self._is_directory(entry):
            mode = (stat.S_IFDIR | PERMISSION_ALL_READ)
            nlink = 2
            ts = unixtimestamp(entry.timestamp())
            size = 0
        else:
            mode = (stat.S_IFREG | PERMISSION_ALL_READ)
            nlink = 1
            ts = 0
            size = len(entry.raw_data())

        return {
            "st_atime": 0,
            "st_ctime": 0,
            #"st_crtime": unixtimestamp(record.standard_information().created_time()),
            "st_mtime": ts,
            "st_size": size,
            "st_uid": uid,
            "st_gid": gid,
            "st_mode": mode,
            "st_nlink": nlink,
        }
Esempio n. 5
0
    def symlink(self, target, source):
        _source = source[1:]
        _target = target[1:]

        asource = os.path.join(self.tmp, _source)
        atarget = os.path.join(self.tmp, _target)

        status = os.symlink(source, atarget)

        uid, gid, pid = fuse_get_context()
        username = pwd.getpwuid(uid)[0]

        dispatch(
            request(
                [
                    "--cwd",
                    self.tmp,
                    "commit",
                    "-A",
                    "-u",
                    username,
                    "-m",
                    "hgfs[symlink]: %s -> %s" % (_target, source),
                    str(source),
                    str(_target),
                ]
            )
        )
        if self.args.clone:
            dispatch(request(["--cwd", self.tmp, "push"]))

        return status
Esempio n. 6
0
 def open(self, path, flags):
     # Only support 'READ ONLY' flag
     access_flags = os.O_RDONLY | os.O_WRONLY | os.O_RDWR
     fh = 0
     if flags & access_flags != os.O_RDONLY:
         raise fuse.FuseOSError(errno.EACCES)
     else:
         cur_path = path.split('/')
         if len(cur_path) == 6:
             uid, gid, pid = fuse.fuse_get_context()
             username = self.get_username(uid)
             files = get_datasets(username, cur_path[1], cur_path[2], cur_path[3], cur_path[4], self.datapath)
             fname = next((f[1] for f in files if f[0]==cur_path[5]), None)
             if fname:
                 self.gzfile = None
                 fh = os.open(fname, flags)
             elif cur_path[5].endswith('ugz'):
                 # Check to see if we're being asked about a gzipped file
                 fn = cur_path[5][:-3] +'gz'
                 fname = next((f[1] for f in files if f[0]==fn), None)
                 if fname:
                     self.gzfile = gzip.open(fname,'r')
                     fh = self.gzfile.fileno()
                 else:
                     raise fuse.FuseOSError(errno.ENOENT)
             else:
                 raise fuse.FuseOSError(errno.ENOENT)
     return fh
Esempio n. 7
0
    def getattr(self, path, fh=None):
        uid, gid, pid = fuse_get_context()

        pp = path.split('/')

        if path == '/':
            st = dict(st_mode=(stat.S_IFDIR | 0o755), st_nlink=2)
        elif len(pp) < 5:
            st = dict(st_mode=(stat.S_IFDIR | 0o755), st_nlink=2)
        elif len(pp) == 5 and pp[3] == "documents":
            st = dict(st_mode=(stat.S_IFDIR | 0o755), st_nlink=2)
        else:
            st = dict(st_mode=(stat.S_IFREG | 0o444), st_size=0)
            if pp[3] == "properties":
                es_json = self.prop_cache[self.es_base_url +
                                          '/%s/%s/_mapping' % (pp[1], pp[2])]
                mapping = json.dumps(es_json
                                     [pp[1]]['mappings'][pp[2]]
                                     ['properties'][pp[4]]) + "\n"
                st['st_size'] = len(mapping)
            elif pp[3] == "documents":
                st['st_size'] = len(self.doc_cache[self.es_base_url +
                                    '/%s/%s/%s' % (pp[1], pp[2], pp[5])])

        st['st_ctime'] = st['st_mtime'] = st['st_atime'] = time()

        return st
Esempio n. 8
0
    def rename(self, old, new):
        _old = old[1:]
        _new = new[1:]

        uid, gid, pid = fuse_get_context()
        username = pwd.getpwuid(uid)[0]

        dispatch(request(["--cwd", self.tmp, "mv", _old, _new]))
        dispatch(
            request(
                ["--cwd", self.tmp, "mv", os.path.join(".hgfs", _old + ".attr"), os.path.join(".hgfs", _new + ".attr")]
            )
        )
        dispatch(
            request(
                [
                    "--cwd",
                    self.tmp,
                    "commit",
                    "-u",
                    username,
                    "-m",
                    "hgfs[rename]: %s -> %s" % (_old, _new),
                    str(_old),
                    str(_new),
                ]
            )
        )
        if self.args.clone:
            dispatch(request(["--cwd", self.tmp, "push"]))

        return 0
Esempio n. 9
0
 def fsync(self, path, datasync, fh):
     context = fuse_get_context()
     print "fync context:", context, " path: ", path
     if fh in self.files:
         active_file = self.files[fh] 
         if active_file.changed:
             retval = os.fsync(active_file.cfh)
             try:
                 text = open(active_file.cpath, "r").read()
                 if not self.seap.allow_write_by_path(active_file.cpath,
                                                      active_file.path, context):
                 #if text.find("block") != -1:
                     print "block sync"
                     retval = -EACCES
                 else:
                     shutil.copy2(active_file.cpath, active_file.path)
                     print "fsync changed: " + active_file.to_string()
             except (IOError, os.error) as why:
                 print "here"
                 errors.append((active_file.cpath, active_file.cpath, str(why)))
             active_file.changed = False
             return retval
         else:
             print "fsync unchanged; " + active_file.to_string()
             return os.fsync(active_file.fh)
     else:
         print "fsync error EBADF fh:", active_file.fh  
         return -EBADF
Esempio n. 10
0
    def getattr(self, path, fh=None):
        if path == '/':
            uid, gid, pid = fuse.fuse_get_context()

            return {
                'st_uid': uid,
                'st_gid': gid,
                'st_mode': stat.S_IFDIR | 0555,
                'st_nlink': 2,

                'st_atime': self._load_time,
                'st_mtime': self._load_time,
                'st_ctime': self._load_time,
            }
        else:
            stats = [os.stat(f) for f in self._metafiles(path)]

            # bitwise OR of all the modes
            mode = reduce(lambda a, b: a | (b.st_mode & 0777), stats, 0)

            return {
                'st_uid': stats[0].st_uid,
                'st_gid': stats[0].st_gid,
                'st_mode': stat.S_IFREG |  mode,
                'st_size': self._exploded_info(path).filesize,
                'st_nlink': min(i.st_nlink for i in stats),

                'st_atime': max(i.st_atime for i in stats),
                'st_mtime': max(i.st_mtime for i in stats),
                'st_ctime': max(i.st_ctime for i in stats),
            }
Esempio n. 11
0
    def getattr(self, path, fh=None):
        self.logger.info('getattr %s', path)
        try:
            cache_entry = self.cache.get_entry(path)
        except FileNotFoundError:
            raise fuse.FuseOSError(errno.ENOENT)

        now = time.time()
        if 'modified' in cache_entry.metadata:
            modified = cache_entry.metadata['modified'].replace('+0000', '').strip()
            modified = time.strptime(modified, '%a, %d %b %Y %H:%M:%S')
            modified = time.mktime(modified)
        else:
            modified = now

        uid, gid, pid = fuse.fuse_get_context()
        ret = dict(
            st_size=int(cache_entry.metadata['bytes']),
            st_ctime=now,
            st_mtime=modified,
            st_atime=now,
            st_uid=uid,
            st_gid=gid
        )
        if cache_entry.metadata['is_dir'] is True:
            ret['st_mode'] = stat.S_IFDIR | 0755
            ret['st_nlink'] = 3
        else:
            ret['st_mode'] = stat.S_IFREG | 0644
            ret['st_nlink'] = 1

        return ret
Esempio n. 12
0
    def __build_stat_from_entry(self, entry):
        (uid, gid, pid) = fuse_get_context()

        if entry.is_directory:
            effective_permission = int(Conf.get("default_perm_folder"), 8)
        elif entry.editable:
            effective_permission = int(Conf.get("default_perm_file_editable"), 8)
        else:
            effective_permission = int(Conf.get("default_perm_file_noneditable"), 8)

        stat_result = {
            "st_mtime": entry.modified_date_epoch,  # modified time.
            "st_ctime": entry.modified_date_epoch,  # changed time.
            "st_atime": time(),
            "st_uid": uid,
            "st_gid": gid,
        }

        if entry.is_directory:
            # Per http://sourceforge.net/apps/mediawiki/fuse/index.php?title=SimpleFilesystemHowto,
            # default size should be 4K.
            # TODO(dustin): Should we just make this (0), since that's what it is?
            stat_result["st_size"] = 1024 * 4
            stat_result["st_mode"] = stat.S_IFDIR | effective_permission
            stat_result["st_nlink"] = 2
        else:
            stat_result["st_size"] = DisplacedFile.file_size if entry.requires_mimetype else entry.file_size

            stat_result["st_mode"] = stat.S_IFREG | effective_permission
            stat_result["st_nlink"] = 1

        stat_result["st_blocks"] = int(math.ceil(float(stat_result["st_size"]) / 512.0))

        return stat_result
Esempio n. 13
0
    def open(self, path, flags):
        self.log.debug(" open(%s, flags=0x%x)", path, flags)

        (unused, unused1, pid) = fuse_get_context()
        self.log.debug('  - pid: %d', pid)

        if hasattr(self, 'lock_owner'):
            self.log.debug('  - lock owner %d', self.lock_owner)

        if flags & os.O_EXCL:
            self.log.debug("  - exclusive bit set")

        access = X_OK
        if flags & os.O_CREAT: access |= W_OK
        self.checkAccess(os.path.dirname(path), access)

        item = self.getRecordOrThrow(path, ["type", "readLock", "writeLock", "st_mode", "st_uid", "st_gid"])

        access = 0
        if flags & (os.O_RDONLY | os.O_RDWR) or flags == 0: access |= R_OK
        if flags & (os.O_WRONLY | os.O_RDWR | os.O_APPEND | os.O_TRUNC): access |= W_OK

        if not item.access(access) == 0:
            raise FuseOSError(EACCES)

        self.lockManager.create(path)

        return self.allocId()
Esempio n. 14
0
 def getattr(self, path, fh=None):
     print "Calling getattr"
     to_return = None
     uid, gid, pid = fuse_get_context()
     split = normpath(path).split("/")
     if len(split) != 5:
         to_return = {
             'st_atime': time(),
             'st_gid': 0,
             'st_uid': 0,
             'st_mode': S_IFDIR | 0755,
             'st_mtime': 667908000,
             'st_ctime': 667908000,
             'st_size': 4096
         }
     else:
         schema = split[1]
         tablename = split[2]
         pk = split[3]
         col = split[4]
         formatted = self._get_pk_data(schema, tablename, pk, col)
         if formatted is not None:
             to_return = {
                 'st_atime': time(),
                 'st_gid': 0,
                 'st_uid': 0,
                 'st_mode': S_IFREG | 0666,
                 'st_mtime': 667908000,
                 'st_ctime': 667908000,
                 'st_size': len(formatted)
             }
         else:
             raise FuseOSError(ENOENT)
     return to_return
Esempio n. 15
0
 def write(self, path, data, offset, fh):
     context = fuse_get_context()
     if fh in self.files:
         active_file = self.files[fh]
         if active_file.changed == False:
             active_file.changed = True 
             active_file.cpath = TMP_PATH + path               
             if not os.path.exists(os.path.dirname(active_file.cpath)):
                 os.makedirs(os.path.dirname(active_file.cpath))
             try:
                 shutil.copy2(path, active_file.cpath)
                 print "write cpath; " + active_file.to_string()
             except (IOError, os.error) as why:
                 print str(why)
             if active_file.mode !=0:
                 active_file.cfh = os.open(active_file.cpath,
                                           active_file.flags, active_file.mode)
             else:
                 active_file.cfh = os.open(active_file.cpath, active_file.flags)
         with self.rwlock:
             print "write to cpath; " + active_file.to_string()
             os.lseek(active_file.cfh, offset, 0)
             return os.write(active_file.cfh, data)
     else:
         print "write error EBADF fh:" + fh
         return -EBADF 
Esempio n. 16
0
        def wrapper(*args, **kwargs):
        
            try:
                pid = fuse_get_context()[2]
            except:
                # Just in case.
                pid = 0
        
            if not prefix:
                log.info('--------------------------------------------------')

            log.info("%s>>>>>>>>>> %s(%d) >>>>>>>>>> (%d)" % 
                     (prefix, f.__name__, sn, pid))
        
            if args or kwargs:
                condensed = {}
                for i in xrange(len(args)):
                    # Skip the 'self' argument.
                    if i == 0:
                        continue
                
                    if i - 1 >= len(argument_names):
                        break

                    condensed[argument_names[i - 1]] = args[i]

                for k, v in kwargs.iteritems():
                    condensed[k] = v

                values_nice = [("%s= [%s]" % (k, v)) for k, v \
                                                     in condensed.iteritems() \
                                                     if k not in excluded]
                
                if otherdata_cb:
                    data = otherdata_cb(*args, **kwargs)
                    for k, v in data.iteritems():
                        values_nice[k] = v
                
                if values_nice:
                    values_string = '  '.join(values_nice)
                    log.debug("DATA: %s" % (values_string))

            suffix = ''

            try:
                result = f(*args, **kwargs)
            except FuseOSError as e:
                log.info("FUSE error [%s] (%s) will be forwarded back to "
                         "GDFS: %s" % (e.__class__.__name__, e.errno, str(e)))
                raise
            except Exception as e:
                log.exception("There was an exception.")
                suffix = (' (E(%s): "%s")' % (e.__class__.__name__, str(e)))
                raise
            finally:
                log.info("%s<<<<<<<<<< %s(%d) (%d)%s" % 
                         (prefix, f.__name__, sn, pid, suffix))
            
            return result
Esempio n. 17
0
  def getattr(self, path, fh=None):
    uid, gid, pid = fuse_get_context()
    node = self.get_node(path)

    if node:
      return node['attributes']

    raise RuntimeError('unexpected path: %r' % path)
Esempio n. 18
0
    def mkdir(self, path, mode):
        uid, gid, pid = fuse_get_context()
        self.files[path] = dict(st_mode=(S_IFDIR | mode), st_nlink=2,
                                st_size=0, st_ctime=time(), st_mtime=time(),
                                st_atime=time(),
                                st_uid=uid, st_gid=gid)

        self.files['/']['st_nlink'] += 1
Esempio n. 19
0
    def get_eps_context(self):
        context_data = list(fuse_get_context())

        group_ids = [self.get_group_id(gname) for gname in
                     self.users.get(context_data[0], {}).get('groups')]
        group_ids.sort()
        context_data[1] = group_ids
        return tuple(context_data)
Esempio n. 20
0
 def flush(self, path, fh):
     logger.debug("flush file %s, pid is:%d" % (path, fuse_get_context()[2]))
     hashpath = self.__hashpath(path, enablepid=True)
     logger.debug(hashpath)
     downloadtask = self.taskpool.query_download_task(hashpath)
     if downloadtask:
         downloadtask.end_download_file()
         self.taskpool.delete_download_task(hashpath)
Esempio n. 21
0
    def open(self, path, fi):
        # Run command and return fd to it
        pid = fuse.fuse_get_context()[2]
        logging.info('open %s for %d', path, pid)
        fd = self._getnewfd(path, pid)

        fi.fh = fd
        fi.direct_io = True
Esempio n. 22
0
    def create(self, path, mode):
        uid, gid, pid = fuse_get_context()
        self.files[path] = dict(st_mode=(S_IFREG | mode), st_nlink=1,
                                st_size=0, st_ctime=time(), st_mtime=time(),
                                st_atime=time(),
                                st_uid=uid, st_gid=gid)

        self.fd += 1
        return self.fd
Esempio n. 23
0
 def read(self, path, size, offset, fh):
     uid, gid, pid = fuse_get_context()
     if path == '/uid':
         return '%s\n' % uid
     elif path == '/gid':
         return '%s\n' % gid
     elif path == '/pid':
         return '%s\n' % pid
     return ''
Esempio n. 24
0
 def create(self, path, mode):
     context = fuse_get_context()
     fh = os.open(path, os.O_WRONLY | os.O_CREAT, mode)
     if not fh in self.files:
         active_file = ActiveFile(path, context, fh)
         active_file.mode = mode
         active_file.flags = os.O_WRONLY | os.O_CREAT
         self.files.update({fh: active_file})
     print "create; "+ self.files[fh].to_string()    
     return fh
Esempio n. 25
0
 def open(self, path, flags):
     context = fuse_get_context()
     fh = os.open(path, flags)
     print "open context:", context, " path: ", path
     if not (context, path) in self.files:
         active_file = ActiveFile(path, context, fh)
         active_file.flags = flags
         print "open new: " + active_file.to_string()
         self.files.update({fh: active_file})
     return fh
Esempio n. 26
0
 def _debug(self, op, path, args, ret):
     own = op in self.__class__.__dict__
     sys.stderr.write('%s:%s:%i/%i/%i\n' % (
         (op.upper(), own) + fuse_get_context()
         ))
     sys.stderr.write(':: %s\n' % path)
     if op not in ('read', 'write'):
         sys.stderr.write(':: %s\n' % pf(args))
         sys.stderr.write(':: %s\n' % pf(ret))
     sys.stderr.write('\n')
     sys.stderr.flush()
Esempio n. 27
0
    def write(self, path, data, offset, fh):
        self.log.debug(" write(%s, len=%d, offset=%d)", path, len(data), offset)

        (uid, gid, pid) = fuse_get_context()
        self.log.debug('  - uid: %d, gid: %d, pid: %d, lock_owner: %d', uid, gid, pid, getattr(self, 'lock_owner') if hasattr(self, 'lock_owner') else -1)

        item = self.getRecordOrThrow(path)
        if not item.isFile() and not item.isHardLink():
            raise FuseOSError(EINVAL)

        return item.write(data, offset)
Esempio n. 28
0
 def __init__(self):
     uid, gid, _ = fuse_get_context()
     self.attrs = {
         'st_mode': (S_IFREG | 0o755),
         'st_mtime': time(),
         'st_atime': time(),
         'st_nlink': 0,
         'st_uid': uid,
         'st_gid': gid,
         'st_size': 0
     }
Esempio n. 29
0
 def getattr(self, path, fh=None):
     """Return a dict of file attributes for the given file/directory."""
     # This will work for either file or directory, but raises ValueError if
     # it doesn't exist-- convert that error to ENOENT if it happens.
     try:
         st = self.tree.stat(path)
     except ValueError:
         raise fuse.FuseOSError(errno.ENOENT)
     # Apply UID and GID from fuse's context.  The other values are fine
     # as-is.
     st["st_uid"], st["st_gid"] = fuse.fuse_get_context()[0:2]
     return st
Esempio n. 30
0
 def __call__(self, *args, **kwargs):
     uid, gid, pid = fuse.fuse_get_context()
     try:
         self._log("starting ", args[0])
         res = fuse.Operations.__call__(self, *args, **kwargs)
     except Exception as e:
         self._log(pid, args, kwargs, e)
         raise
     else:
         if VERBOSE:
             self._log(pid, args, kwargs, res)
         return res
Esempio n. 31
0
 def getattr(self, path, fh=None):
     uid, guid, pid  = fuse_get_context()
     print "getattr: ", uid, guid, pid
     st = os.lstat(path)
     return dict((key, getattr(st, key)) for key in ('st_atime', 'st_ctime',
         'st_gid', 'st_mode', 'st_mtime', 'st_nlink', 'st_size', 'st_uid'))
Esempio n. 32
0
 def link(self, target, source):
     uid, guid, pid  = fuse_get_context()
     print "link: ", uid, guid, pid
     return os.link(source, target)
Esempio n. 33
0
 def readdir(self, path, fh):
     uid, guid, pid  = fuse_get_context()
     print "readdir: ", uid, guid, pid, fh
     return ['.', '..'] + os.listdir(path)
Esempio n. 34
0
    def rename(self, old, new):
        uid, guid, pid  = fuse_get_context()
        print "rename", uid, guid, pid

        return os.rename(old, new)
Esempio n. 35
0
def get_uid_gid():
    uid, gid, pid = fuse_get_context()
    return int(uid), int(gid)
Esempio n. 36
0
    def read(self, path, size, offset, fd):
        path = self._full_path(path)
        uid, gid, pid = fuse_get_context()
        printDebug(
            "read", "reading {} bytes from {} (fd {}) at offset {}".format(
                size, path, fd, offset))
        printDebug("read", uid)
        printDebug("read", gid)

        if uid not in self._user_cache:
            self._generate_user_attr()

        # Fetch user's cached key.
        key = self._user_cache[uid]["key"]

        # Fetch the encrypted AES key.
        c1 = self._file_cache[path]["c1"]

        # Calculate the first extent to read based on the offset.
        e = int(offset / 4096)

        # Adjust offset to account for cryptographic metadata, seek, and read.
        offset, new_size, first, last = self._calc_offsets(offset, size, path)
        printDebug("read", "adjusted offset: {}".format(offset))
        printDebug("read", "adjusted size: {}".format(new_size))
        printDebug("read", "first: {}".format(first))
        printDebug("read", "last: {}".format(last))
        os.lseek(fd, offset, os.SEEK_SET)
        b = os.read(fd, new_size)

        # Process read data, decrypting each read extent.
        plaintexts = []
        printDebug("read", "e: {}".format(e))
        num_extents = ceil(new_size / 4096.0)

        for i in range(num_extents):
            printDebug("read", "index: {}".format(e + i))
            # Get IV and tag for extent e + i.
            iv = self._file_cache[path]["IV"][e + i]
            tag = self._file_cache[path]["tags"][e + i]
            printDebug("read", "tag length: {}".format(len(tag)))
            printDebug("read", "tag: {}".format(tag))
            #printDebug("read", "ct: {}".format(b[i:i + 4096]))

            # Perform decryption
            msg = self._abe.decrypt(key, c1, b[i:i + 4096], iv, tag)
            if not msg:
                # Attempt to unpad last block before breaking out of loop.
                if i > 0:
                    plaintexts[i] = self._unpad(plaintexts[i])

                break

            # Remove padding if last block.
            if i == num_extents - 1:
                msg = self._unpad(msg)

            # Store message in both list to be returned and the cache.
            plaintexts.append(msg)
            printDebug("read", "decrypted msg: {}".format(msg))
            self._file_cache[path][e + i] = msg

        # Adjust plaintext to contain only what was requested.
        p = b"".join(plaintexts)
        p = p[first:]  # Drop unrequested bytes at beginning.
        if last:
            p = p[:-last]  # Drop unrequested bytes at end.
        printDebug(
            "read",
            "requested {} bytes, returning {} bytes".format(size, len(p)))
        return p
Esempio n. 37
0
 def access(self, path, amode):
     (uid, gid, unused) = fuse_get_context()
     self.accessLog.debug(" access(%s, mode=%d) by (%d, %d)", path, amode, uid, gid)
     item = self.getRecordOrThrow(path)
     return item.access(amode)
Esempio n. 38
0
 def create(self, path, mode):
     notify(path, 'c')
     ret = os.open(path, os.O_WRONLY | os.O_CREAT, mode)
     uid, gid, pid = fuse.fuse_get_context()
     os.chown(path, uid, gid)
     return ret
Esempio n. 39
0
 def context_uid(self):
     cxt = fuse_get_context()
     return cxt[0]
Esempio n. 40
0
 def __call__(self, op, path, *args):
     """wrapper around Owncloud class, that verifies only the owncloudUser can access this copy of the filesystem."""
     ctx = fuse.fuse_get_context()
     if ctx[0] != self.owncloudUID:
         raise fuse.FuseOSError(errno.EACCES)
     return super(Owncloud, self).__call__(op, path, *args)
Esempio n. 41
0
 def read(self, path, length, offset, fh):
   uid, gid, pid = fuse_get_context()
   node = self.get_node(path)
   entry = node['file']
   return self.pbo.read(entry, offset, length)
Esempio n. 42
0
    def write(self, path, data, offset, fd):
        path = self._full_path(path)
        printDebug(
            "write",
            "writing to {} (fd {}) at offset {}".format(path, fd, offset))
        printDebug("write", "writing {} bytes".format(len(data)))

        uid, gid, pid = fuse_get_context()
        if uid not in self._user_cache:
            self._generate_user_attr()

        # Fetch user's cached key and policy.
        key = self._user_cache[uid]["key"]
        policy = self._read_policy_file(path)

        # Fetch the encrypted AES key.
        c1 = self._file_cache[path]["c1"]

        # Calculate the first extent to read based on the offset.
        e = int(offset / 4096)
        printDebug("write", "e: {}".format(e))

        # Calculate new offset and seek.
        offset, new_size, first, last = self._calc_offsets(
            offset, len(data), path)
        os.lseek(fd, offset, os.SEEK_SET)
        printDebug("write", "new offset: {}".format(offset))
        printDebug("write", "new size: {}".format(new_size))

        # Prepare data to be written to the cache. Prepend the missing bytes of
        # the first extent and append the missing bytes of the last extent from
        # the cache.
        num_extents = int(ceil(new_size / 4096.0))
        printDebug("write", "# of extents: {}".format(num_extents))
        try:
            prepend = self._file_cache[path][e][:first + 1]
        except KeyError:
            prepend = b""

        try:
            append = self._file_cache[path][e + num_extents][-last]
        except KeyError:
            append = b""

        data = prepend + data + append
        printDebug("write", "new length of data: {}".format(len(data)))
        #assert len(data) % 4096 == 0 # Ensure I'm not breaking everything...
        data_list = [data[i:i + 4096] for i in range(0, len(data), 4096)]

        # Encrypt each extent.
        ciphertexts = []
        for i in range(num_extents):
            printDebug("write", "index: {}".format(e + i))
            # Write to cache.
            try:
                self._file_cache[path]["cache"][e + i] = data_list[i]
            except IndexError:
                cachelen = len(self._file_cache[path]["cache"])
                printDebug(
                    "write",
                    "cache size {} and index {}".format(cachelen, e + i))
                assert cachelen == e + i
                self._file_cache[path]["cache"].append(data_list[i])

            #printDebug("write", "msg: {}".format(data_list[i]))
            # Encrypt extent.
            if len(data_list[i]) % 4096:
                c, iv, tag = self._abe.encrypt(self._pad(data_list[i]), key,
                                               c1)
            else:
                c, iv, tag = self._abe.encrypt(data_list[i], key, c1)

            #printDebug("write", "ct: {}".format(c))
            printDebug("write", "length of tag: {}".format(len(tag)))
            printDebug("write", "tag: {}".format(tag))
            ciphertexts.append(c)
            printDebug("write", "length of ct: {}".format(len(c)))
            self._file_cache[path]["IV"][e + i] = iv
            self._file_cache[path]["tags"][e + i] = tag

        c = b"".join(ciphertexts)
        printDebug("write", "ct len: {}".format(len(c)))
        os.fsync(fd)
        return os.write(fd, c)
Esempio n. 43
0
def get_caller_pid():
    uid, gid, pid = fuse_get_context()
    return pid
Esempio n. 44
0
 def read(self, path, length, offset, fh):
     (uid, gid, pid) = fuse_get_context()
     if path.split("/")[-1] == "config":
         return 0
     os.lseek(fh, offset, os.SEEK_SET)
     return os.read(fh, length)
Esempio n. 45
0
    def getLockOwner(self):
        (uid, gid, pid) = fuse_get_context()

        return getattr(self, 'lock_owner') if hasattr(self, 'lock_owner') else pid
Esempio n. 46
0
 def create(self, path, mode, fi=None):
     uid, gid, pid = fuse_get_context()
     full_path = self._full_path(path)
     fd = os.open(full_path, os.O_WRONLY | os.O_CREAT, mode)
     os.chown(full_path, uid, gid)  #chown to context uid & gid
     return fd
Esempio n. 47
0
        def wrapper(*args, **kwargs):
        
            try:
                pid = fuse.fuse_get_context()[2]
            except:
                # Just in case.
                pid = 0
        
            if not prefix:
                _logger.debug("-----------------------------------------------"
                              "---")

            _logger.debug("%s>>>>>>>>>> %s(%d) >>>>>>>>>> (%d)",
                          prefix, f.__name__, sn, pid)
        
            if args or kwargs:
                condensed = {}
                for i in range(len(args)):
                    # Skip the 'self' argument.
                    if i == 0:
                        continue
                
                    if i - 1 >= len(argument_names):
                        break

                    condensed[argument_names[i - 1]] = args[i]

                for k, v in list(kwargs.items()):
                    condensed[k] = v

                values_nice = [("%s= [%s]" % (k, v)) for k, v \
                                                     in list(condensed.items()) \
                                                     if k not in excluded]
                
                if otherdata_cb:
                    data = otherdata_cb(*args, **kwargs)
                    for k, v in list(data.items()):
                        values_nice[k] = v
                
                if values_nice:
                    values_string = '  '.join(values_nice)
                    _logger.debug("DATA: %s", values_string)

            suffix = ''

            try:
                result = f(*args, **kwargs)
            except fuse.FuseOSError as e:
                if e.errno not in (errno.ENOENT,):
                    _logger.error("FUSE error [%s] (%s) will be forwarded "
                                  "back to GDFS from [%s]: %s", 
                                  e.__class__.__name__, e.errno, f.__name__, 
                                  str(e))
                raise
            except Exception as e:
                _logger.exception("There was an exception in [%s]", f.__name__)
                suffix = (' (E(%s): "%s")' % (e.__class__.__name__, str(e)))
                raise
            finally:
                _logger.debug("%s<<<<<<<<<< %s(%d) (%d)%s", 
                              prefix, f.__name__, sn, pid, suffix)
            
            return result
Esempio n. 48
0
    def getattr(self, path, fh=None):
        '''
        return file attributes
        st_atime   /* Time when file data last accessed.*/
        st_mode    /* inode protection mode */
        st_mtime   /* Time when file data last modified. */
        st_ctime   /* Time when file was created. */
        st_size    /* file size, in bytes */
        st_uid;    /* user-id of owner */
        st_gid;    /* group-id of owner */
        '''
        try:
            # because getattr returns size, we need to wait on writes to complete
            self.flush(path, fh)
            logger.debug("flush done")

            path = path.lstrip('/')
            directory, filename = self._get_separated_path(path)
            st = {}
            uid, gid, pid = fuse_get_context()

            st['st_uid'] = uid
            st['st_gid'] = gid

            if path == '':
                st['st_mode'] = stat.S_IFDIR | 0o755
                st['st_nlink'] = 2
                return st

            directory_listing = self._get_cached_dir(directory)
            item = directory_listing.get(filename)
            if item is None:
                logger.debug("item doesn't exist: path:%r fh:%s return:%s",
                             path, fh, st)
                raise FuseOSError(ENOENT)

            if isinstance(item, models.Directory):
                st['st_mode'] = stat.S_IFDIR | 0o755
                st['st_nlink'] = 2
                properties = self._files_service.get_directory_properties(
                    self._azure_file_share_name, path).properties
            else:
                st['st_mode'] = stat.S_IFREG | 0o644
                st['st_nlink'] = 1
                st['st_size'] = item.properties.content_length
                properties = self._files_service.get_file_properties(
                    self._azure_file_share_name, directory,
                    filename).properties

            # Setting Modified Time
            try:
                st['st_mtime'] = properties.last_modified.timestamp()
            except Exception:
                logger.warning(
                    "getattr operation setting modified time failed: path:%r fh:%d st:%s",
                    path, fh, st)

            # Setting Created Time
            try:
                st['st_ctime'] = properties.last_modified.timestamp()
            except Exception:
                logger.warning(
                    "getattr operation setting create time failed: path:%r fh:%d st:%s",
                    path, fh, st)

            return st
        except Exception as e:
            # This log is noisy as it occurs if the file isn't found. Only uncomment for debugging.
            #logger.exception(
            #    "getattr operation exception: path:%r fh:%d exception:%s", path, fh, e)
            raise FuseOSError(ENOENT)