Exemple #1
0
static direntry_t *direntry_from_listing (CALLER_DECL listing_t *li)
{
    /* TODO: stop being lazy and have listing_init */
    direntry_t *de = realloc(li, sizeof(direntry_t));


    bzero(de + sizeof(listing_t), sizeof(direntry_t) - sizeof(listing_t));

    de->inode = inode_next();
    inode_map_add(de);

    direntry_trace(
        "[direntry %p inode %lu] new (" CALLER_FORMAT ") ref %u\n",
        de, de->inode, CALLER_PASS 1
    );


    return de;
}
Exemple #2
0
/*
 * Read a container with the provided key
 * Read all files and place them into the provided list
 * Returns:
 * >0   Number of read files
 * -1   File error during reading
 * -2   Wrong password in input
 */
int memfile_readfiles(char * filename, char * password, memfile * root)
{
    char *  buf ;
    char *  cur ;
    int     fd ;
    int     i ;
    struct stat fileinfo ;

    uint8_t nonce[NONCE_SZ];
    uint8_t key[KEY_SZ];

    uint64_t    u1, u2, u3 ;
    size_t      header_sz ;
    size_t      payload_sz ;
    char        fname[MAXNAMESZ];

    header_sz = MAGIC_SZ + 2 + NONCE_SZ + CANARI_SZ ;
    /* Find out file size in bytes */
    if (stat(filename, &fileinfo)!=0) {
        logger("no such file: %s", filename);
        return 1 ;
    }
    if (fileinfo.st_size < header_sz) {
        logger("not a container: ", filename);
        return -1 ;
    }
    /* Map input file */
    if ((fd=open(filename, O_RDONLY))==-1) {
        logger("cannot open: %s", filename);
        return -1 ;
    }
    buf = (char*)mmap(0,
                      fileinfo.st_size,
                      PROT_READ | PROT_WRITE,
                      MAP_PRIVATE,
                      fd,
                      0);
    close(fd);
    if (buf==(char*)-1) {
        logger("cannot map: %s", filename);
        return -1;
    }
    cur = buf ;
    payload_sz = fileinfo.st_size - header_sz ;
    /*
     * A container header is composed of:
     * A magic number of MAGIC_SZ bytes
     * A version number on 2 bytes: major.minor
     * A nonce of size NONCE_SZ bytes
     * A canari of size CANARI_SZ bytes
     */
    /* Check magic number */
    for (i=0 ; i<MAGIC_SZ ; i++) {
        if (cur[i]!=mefs_magic[i]) {
            logger("not a container: ", filename);
            munmap(buf, fileinfo.st_size);
            return -1 ;
        }
    }
    cur += MAGIC_SZ ;
    /* Read version number */
    if (cur[0]!=mefs_version[0] ||
        cur[1]!=mefs_version[1]) {
        logger("unsupported version for: ", filename);
        munmap(buf, fileinfo.st_size);
        return -1 ;
    }
    cur+=2 ;

    /* Copy nonce for later use */
    memcpy(nonce, cur, NONCE_SZ);
    cur += NONCE_SZ ;
    /* Derive key from password */
    derive_key(password,
               strlen(password),
               nonce,
               NONCE_SZ,
               key,
               KEY_SZ,
               20000);
    /* Decrypt everything starting from CANARI, using nonce and key */
    stream_cipher(cur,
                  fileinfo.st_size-(MAGIC_SZ+2+NONCE_SZ),
                  0,
                  key,
                  nonce);
    /* Test canari has expected pattern: 0xaaaa...aa */
    for (i=0 ; i<CANARI_SZ ; i++) {
        if ((unsigned char)cur[i]!=0xaa) {
            logger("wrong password for container: %s", filename);
            munmap(buf, fileinfo.st_size);
            return -2 ;
        }
    }
    cur+=CANARI_SZ ;

    /* Read files one by one */
    /*
     * filename is a zero-padded string of size MAXNAMESZ
     * filesize on a 64 big-endian unsigned int
     * ctime    on a 64-big-endian unsigned int
     * mtime    on a 64-big-endian unsigned int
     */
    i=0 ;
    while (1) {
        memcpy(fname, cur, MAXNAMESZ);
        cur+=MAXNAMESZ;
        memcpy(&u1, cur, sizeof(uint64_t));
        cur+=sizeof(uint64_t);
        memcpy(&u2, cur, sizeof(uint64_t));
        cur+=sizeof(uint64_t);
        memcpy(&u3, cur, sizeof(uint64_t));
        cur+=sizeof(uint64_t);

        root[i].name = strdup(fname);
        root[i].sta.st_ino = inode_next();
        root[i].sta.st_size     = u1 ;
        root[i].sta.st_ctime    = u2 ;
        root[i].sta.st_mtime    = u3 ;

        root[i].data = malloc(u1);
        memcpy(root[i].data, cur, u1);
        cur+=u1 ;
        if ((cur-buf) >= fileinfo.st_size)
            break ;
        i++ ;
    }
    munmap(buf, fileinfo.st_size);
    return 0 ;
}