Fuse


Fuse merupakan sebuah kerangka sistem berkas pada area pengguna. terdiri dari sebuah modul kernel (fuse.ko), sebuah pustaka pada area pengguna, dan sebuah utilitas untuk melakukan proses mount (fusermount). Salah satu keistimewaan FUSE yang paling utama adalah diizikannya proses mount oleh pengguna biasa yang aman. hal ini memberikan kemungkinan baru untuk menggunakan sistem berkas. salah satu contoh adalah sshfs, sebuah sistem berkas yang beroperasi pada tingkatan jaringan yang menggunakan protokol sftp. Semenjak proses mount() merupakan operasi yang membutuhkan pengguna yang memiliki hak khusus, sebuah program pembantu (fusermount) dibutuhkan untuk melakukannya yang terpasang dengan tingkatan pengguna root. Implikasi dengan menyediakan operasi mount untuk pengguna biasa adalah pemilik operasi mount tidak dapat menggunakan kemampuannya untuk melakukan hal-hal yang dapat membahayakan sistem. Syarat-syarat yang harus dipenuhi seiring dengan adanya keadaan tersebut adalah sebagai berikut :

Pemilik proses mount seharusnya tidak dapat melakukan operasi untuk meninggkatkan hak aksesnya dengan bantuan sistem berkas yang dimount
Pemilik proses mount seharusnya tidak dapat melakukan akses yang terlarang untuk mendapatkan informasi dari pengguna lainnya dan proses-proses yang dimiliki oleh pengguna super (root)
Pemilik proses mount seharusnya tidak dapat mengakibatkan perbuatan yang tidak diinginkan proses pengguna lain ataupun proses-proses yang dimiliki oleh pengguna super.
Meskipun demikian keadaan yang tidak diinginkan berkenaan dengan keistimewaan yang dimiliki oleh FUSE masih dapat terjadi dengan cara sebagai berikut:

Pemilik proses mount dapat meningkatkan hak aksesnya dengan cara :
Membuat sebuah sistem berkas yang berisikan sebuah berkas alat, yang kemudian membukanya.
Membuat sebuah sistem berkas yang berisikan sebuah aplikasi suid ataupun gid, yang kemudian mengeksekusinya.

Membuat fuse sendiri :

#ifdef linux
/* For pread()/pwrite() */
#define _XOPEN_SOURCE 500
#endif

#include <fuse.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#include <errno.h>
#include <sys/statfs.h>

static const char *dirpath = "/home/wicakson/Downloads";

char alamat[1000];

static int xmp_getattr(const char *path, struct stat *stbuf)
{
int res;
char fpath[1000];
sprintf(fpath, "%s%s", dirpath, path);
res = lstat(fpath, stbuf);
if (res == -1)
return -errno;

return 0;
}

static int xmp_readlink(const char *path, char *buf, size_t size)
{
int res;
char fpath[1000];
sprintf(fpath, "%s%s", dirpath, path);

res = readlink(fpath, buf, size - 1);
if (res == -1)
return -errno; 

buf[res] = '\0';
return 0;

}


static int xmp_getdir(const char *path, fuse_dirh_t h, fuse_dirfil_t filler)
{
    DIR *dp;
    struct dirent *de;
    int res = 0;
    char fpath[1000];
    sprintf(fpath, "%s%s", dirpath, path);

    dp = opendir(fpath);
    if(dp == NULL)
        return -errno;

    while((de = readdir(dp)) != NULL) {
        res = filler(h, de->d_name, de->d_type);
        if(res != 0)
            break;
    }

    closedir(dp);
    return res;
}

static int xmp_mknod(const char *path, mode_t mode, dev_t rdev)
{
    int res;
    char fpath[1000];
    sprintf(fpath, "%s%s", dirpath, path);


    res = mknod(fpath, mode, rdev);
    if(res == -1)
        return -errno;

    return 0;
}

static int xmp_mkdir(const char *path, mode_t mode)
{
    int res;
    char fpath[1000];
    sprintf(fpath, "%s%s", dirpath, path);


    res = mkdir(fpath, mode);
    if(res == -1)
        return -errno;

    return 0;
}

static int xmp_unlink(const char *path)
{
    int res,res2;
    char fpath[1000], temp[1000];
    sprintf(fpath, "%s%s", dirpath, path);
    strcpy(temp,fpath);
    res = unlink(fpath);
    do
{
sprintf(temp, "%s-copy", fpath);
res2=unlink(temp);
}
    while(res2!=-1);
    if(res == -1)
        return -errno;

    return 0;
}

static int xmp_rmdir(const char *path)
{
    int res;
    char fpath[1000];
    sprintf(fpath, "%s%s", dirpath, path);


    res = rmdir(fpath);
    if(res == -1)
        return -errno;

    return 0;
}

static int xmp_symlink(const char *from, const char *to)
{
    int res;
char from1[1000];
char to1[1000];
sprintf(from1,"%s%s", dirpath, from);
sprintf(to1,"%s%s", dirpath, to);

    res = symlink(from, to);
    if(res == -1)
        return -errno;

    return 0;
}

static int xmp_rename(const char *from, const char *to)
{
     int res;
char from1[1000];
char to1[1000];
sprintf(from1,"%s%s", dirpath, from);
sprintf(to1,"%s%s", dirpath, to);
res = rename(from1, to1);
if (res == -1)
return -errno;

return 0;
}

static int xmp_link(const char *from, const char *to)
{
    int res;
char from1[1000];
char to1[1000];
sprintf(from1,"%s%s", dirpath, from);
sprintf(to1,"%s%s", dirpath, to);

    res = link(from, to);
    if(res == -1)
        return -errno;

    return 0;
}

static int xmp_chmod(const char *path, mode_t mode)
{
    int res;

    char fpath[1000];
    sprintf(fpath, "%s%s", dirpath, path);


    res = chmod(fpath, mode);
    if(res == -1)
        return -errno;
    
    return 0;
}

static int xmp_chown(const char *path, uid_t uid, gid_t gid)
{
    int res;

    char fpath[1000];
    sprintf(fpath, "%s%s", dirpath, path);


    res = lchown(fpath, uid, gid);
    if(res == -1)
        return -errno;

    return 0;
}

static int xmp_truncate(const char *path, off_t size)
{
    int res;

    char fpath[1000];
    sprintf(fpath, "%s%s", dirpath, path);

    
    res = truncate(fpath, size);
    if(res == -1)
        return -errno;

    return 0;
}

static int xmp_utime(const char *path, struct utimbuf *buf)
{
    int res;

    char fpath[1000];
    sprintf(fpath, "%s%s", dirpath, path);

    
    res = utime(fpath, buf);
    if(res == -1)
        return -errno;

    return 0;
}


static int xmp_open(const char *path, int flags)
{
    int res;

    char fpath[1000];
    sprintf(fpath, "%s%s", dirpath, path);
    
    res = open(fpath, flags);
    if(res == -1) 
        return -errno;

    close(res);
    return 0;
}

static int xmp_read(const char *path, char *buf, size_t size, off_t offset)
{
    int fd;
    int res;

    char fpath[1000];
    sprintf(fpath, "%s%s", dirpath, path);
strcpy(alamat,path);

    fd = open(fpath, O_RDONLY);
    if(fd == -1)
        return -errno;

    res = pread(fd, buf, size, offset);
    if(res == -1)
        res = -errno;
    
    close(fd);
    return res;
}

\static int xmp_write(const char *path, const char *buf, size_t size,
                     off_t offset)
{
    int fd;
    int res;
    char fpath[1000];
    sprintf(fpath, "%s%s", dirpath, path);


    fd = open(fpath, O_WRONLY);
char temp1[1000], temp2[1000], kata[1000];
sprintf(temp1, "%s%s", dirpath, alamat);
sprintf(temp2, "%s-copy", temp1);
FILE* a; FILE* b;
a = fopen(temp2,"w+");
b = fopen(temp1, "a+");
while(fgets(kata,1000,b)!=NULL)
{
fprintf(a,"%s",kata);
}
fclose(a);
fclose(b);
    if(fd == -1)
        return -errno;

    res = pwrite(fd, buf, size, offset);
    if(res == -1)
        res = -errno;
    
    close(fd);
    return res;
}

static int xmp_release(const char *path, int flags)
{
    /* Just a stub.  This method is optional and can safely be left
       unimplemented */

    char fpath[1000];
    sprintf(fpath, "%s%s", dirpath, path);

    (void) fpath;
    (void) flags;
    return 0;
}

static int xmp_fsync(const char *path, int isdatasync)
{
    /* Just a stub.  This method is optional and can safely be left
       unimplemented */

    char fpath[1000];
    sprintf(fpath, "%s%s", dirpath, path);

    (void) fpath;
    (void) isdatasync;
    return 0;
}

static struct fuse_operations xmp_oper = {
    .getattr = xmp_getattr, //get file atribut
    .readlink = xmp_readlink, 
    .getdir = xmp_getdir, //get directory
    .mknod = xmp_mknod, //create a file node
    .mkdir = xmp_mkdir, //create directory
    .symlink = xmp_symlink, //create a symbolic link
    .unlink = xmp_unlink, //remove file
    .rmdir = xmp_rmdir, //remove directory
    .rename = xmp_rename, 
    .link = xmp_link, //create a link
    .chmod = xmp_chmod, //change the owner and group of a file
    .chown = xmp_chown, // sama
    .truncate = xmp_truncate, //change the size of a file
    .utime = xmp_utime, //change the access and modification times of a file
    .open = xmp_open,
    .read = xmp_read,
    .write = xmp_write,
    .release = xmp_release, //release directory
    .fsync = xmp_fsync //synchronize file contents
    
};

int main(int argc, char *argv[])
{
    fuse_main(argc, argv, &xmp_oper);
    return 0;
}

0 komentar: