Date: Wed, 30 May 2012 12:26:30 +0000 From: gpf@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r236735 - in soc2012/gpf/pefs_kmod: sbin/pefs sys/fs/pefs Message-ID: <20120530122630.59184106564A@hub.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: gpf Date: Wed May 30 12:26:29 2012 New Revision: 236735 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=236735 Log: -update XXX markers -axe the pefs_addchecklist command and all associated code -some code refactoring -fix endianess bug with exported name checksum value from kernel by ioctl() Modified: soc2012/gpf/pefs_kmod/sbin/pefs/pefs_checksum.c soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.c soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.h soc2012/gpf/pefs_kmod/sbin/pefs/pefs_subr.c soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs.h soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_vnops.c Modified: soc2012/gpf/pefs_kmod/sbin/pefs/pefs_checksum.c ============================================================================== --- soc2012/gpf/pefs_kmod/sbin/pefs/pefs_checksum.c Wed May 30 11:48:57 2012 (r236734) +++ soc2012/gpf/pefs_kmod/sbin/pefs/pefs_checksum.c Wed May 30 12:26:29 2012 (r236735) @@ -52,7 +52,7 @@ #include "pefs_ctl.h" -//#define PEFS_INTEGRITY_DEBUG +#define PEFS_INTEGRITY_DEBUG #if defined (PEFS_INTEGRITY_DEBUG) #define dprintf(a) printf a #else @@ -84,7 +84,7 @@ TAILQ_ENTRY(checksum) checksum_entries; }; -/* XXXgpf: [TODO] turns offsets to 64bits uints (or off_t?) */ +/* XXXgpf: [TODO] turns offsets to uint64_t? */ struct file_header { uint32_t nhashes; uint64_t file_id; @@ -359,8 +359,9 @@ pefs_get_file_id(struct file_header *fhp) { char parent_dir[MAXPATHLEN]; - struct pefs_namemac namemac; + struct pefs_xnamecsum xncs; char *pch; + uint64_t temp; int error, fd; /* feed parent directory to ioctl() */ @@ -380,13 +381,16 @@ pch = strrchr(fhp->path, '/'); pch++; - strlcpy(namemac.pnm_filename, pch, sizeof(namemac.pnm_filename)); - namemac.pnm_namelen = strnlen(namemac.pnm_filename, sizeof(namemac.pnm_filename)); + strlcpy(xncs.pxnc_filename, pch, sizeof(xncs.pxnc_filename)); + xncs.pxnc_namelen = strnlen(xncs.pxnc_filename, sizeof(xncs.pxnc_filename)); - error = ioctl(fd, PEFS_GETNAMEMAC, &namemac); + error = ioctl(fd, PEFS_GETNAMECSUM, &xncs); - if (error == 0) - fhp->file_id = namemac.pnm_csum; + if (error == 0) { + /* XXXgpf: Is this correct? */ + memcpy(&temp, xncs.pxnc_csum, sizeof(xncs.pxnc_csum)); + fhp->file_id = be64toh(temp); + } else pefs_warn("failed to fetch file id from kernel"); @@ -645,7 +649,8 @@ * All data member writes are done separately so as to avoid alignment problems. * Writes are always in little endian byte order. * - * XXXgpf: [TODO] more comments about internal structure of file. + * XXXgpf: [TODO] more comments about internal structure of file. This should probably + * be done after design crystalizes (cuckoo hashing? embed? etc). */ static int pefs_write_checksum_file(int fdout, struct checksum_file_header *cfhp, struct hash_table *chtp) @@ -749,7 +754,9 @@ } /* - * XXXgpf: [TODO] proper comment header, I am sleepy Z_Z + * An in memory database is created from entries in fpin. This database is later written + * to file ".pefs.checksum" which is created under csm_path. algo is used as a cryptographic + * hash function that produces checksums for 4k blocks of each file. */ int pefs_create_checksum_file(FILE *fpin, char *fsroot, char *csm_path, const char *algo) @@ -794,159 +801,3 @@ return (error); } - -/* - * Transform a decrypted fullpath residing in fsroot to an - * encrypted fullpath residing in fromfsroot. - */ -static int -pefs_get_enc_path(struct file_header *fhp, char *fsroot, char *fromfsroot) -{ - /* XXXgpf: can there be a problem with paths greater than MAXPATHLEN? */ - char enc_path[MAXPATHLEN]; - char dec_path[MAXPATHLEN]; - char original_path[MAXPATHLEN]; - char buf[MAXPATHLEN]; - struct stat sb; - char *rel_path; - char *pch; - DIR *dirp; - struct dirent *dp; - uint32_t ino; - int found; - - strlcpy(enc_path, fromfsroot, sizeof(enc_path)); - strlcpy(dec_path, fsroot, sizeof(dec_path)); - - strlcpy(original_path, fhp->path, sizeof(original_path)); - rel_path = original_path + strlen(fsroot); - - dprintf(("constructing encrypted path for: %s%s\n", fsroot, rel_path)); - - pch = strtok (rel_path,"/"); - while (pch != NULL) { - dprintf(("enc path = %s\tdec path = %s\n", enc_path, dec_path)); - dprintf(("next element: %s", pch)); - snprintf(buf, sizeof(buf), "%s/%s", dec_path, pch); - strlcpy(dec_path, buf, sizeof(dec_path)); - - /* grab inode from dec_path */ - if (stat(buf, &sb) != 0) { - warn("cannot stat file %s", buf); - return (PEFS_ERR_SYS); - } - ino = sb.st_ino; - dprintf(("\t%d\n", ino)); - - /* try to find inode in dirents of enc_path */ - dirp = opendir(enc_path); - if (dirp == NULL) { - warn("cannot open dir %s", enc_path); - return (PEFS_ERR_SYS); - } - - found = 0; - while (dirp != NULL) { - if ( (dp = readdir(dirp)) != NULL) { - if (dp->d_fileno == ino) { - found = 1; - break; - } - } - else { - closedir(dirp); - break; - } - } - - if (found == 0) { - pefs_warn("inode: %d not found in directory: %s", ino, enc_path); - return (PEFS_ERR_NOENT); - } - - /* append the encrypted filename and continue */ - snprintf(buf, sizeof(buf), "%s/%s", enc_path, dp->d_name); - strlcpy(enc_path, buf, sizeof(enc_path)); - closedir(dirp); - - pch = strtok (NULL, "/"); - } - - dprintf(("\nresulting enc path = %s\n", enc_path)); - if (stat(buf, &sb) != 0) { - warn("cannot stat file %s", enc_path); - return (PEFS_ERR_SYS); - } - - /* - * XXXgpf: [TODO] deal with other types of files - */ - if (S_ISREG(sb.st_mode) == 0) { - pefs_warn("filename: %s is not a regular file", enc_path); - return (PEFS_ERR_INVALID); - } - - strlcpy(fhp->path, enc_path, sizeof(fhp->path)); - strlcat(fhp->path, "\n", sizeof(fhp->path)); - - return (0); -} - -static int -pefs_write_to_checklist(int fdout, struct file_header *fhp) -{ - uint32_t bytes, len; - - len = strnlen(fhp->path, sizeof(fhp->path)); - bytes = write(fdout, fhp->path, len); - if (bytes != len) { - warn("error writing '%s' to checklist file", fhp->path); - return (PEFS_ERR_IO); - } - - return (0); -} - -/* - * This function creates the checklist that will be used by pefs_addchecksum. - * For each file entry: - * 1) semantic checks: residing in pefs filesystem & regular file type checks. - * 2) the encrypted fullpath of the file is retrieved - * 3) entry is written to checklist_file - */ -int -pefs_create_checklist(FILE *fpin, int fdout, char *fsroot, char *fromfsroot) -{ - struct statfs fs; - struct file_header *fhp; - int error; - - error = 0; - - if (statfs(fsroot, &fs) == -1) { - pefs_warn("statfs failed: %s: %s", fsroot, strerror(errno)); - return (PEFS_ERR_SYS); - } - - while((fhp = pefs_next_file(fpin, &error)) != NULL) { - error = pefs_file_semantic_checks(fhp, &fs); - if (error != 0) - goto out; - - error = pefs_get_enc_path(fhp, fsroot, fromfsroot); - if (error != 0) - goto out; - - error = pefs_write_to_checklist(fdout, fhp); - if (error != 0) - goto out; - - free(fhp); - } - -out: - if (fhp != NULL) - free(fhp); - - return (error); -} Modified: soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.c ============================================================================== --- soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.c Wed May 30 11:48:57 2012 (r236734) +++ soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.c Wed May 30 12:26:29 2012 (r236735) @@ -76,7 +76,6 @@ static int pefs_showchains(int argc, char *argv[]); static int pefs_showalgs(int argc, char *argv[]); static int pefs_addchecksum(int argc, char *argv[]); -static int pefs_addchecklist(int argc, char *argv[]); typedef int (*command_func_t)(int argc, char **argv); typedef int (*keyop_func_t)(struct pefs_keychain_head *kch, int fd, @@ -104,7 +103,6 @@ { "showchains", pefs_showchains }, { "showalgs", pefs_showalgs }, { "addchecksum", pefs_addchecksum}, - { "addchecklist", pefs_addchecklist}, { NULL, NULL }, }; @@ -146,16 +144,6 @@ exit(PEFS_ERR_INVALID); } -static void -initfsroots(int argc, char **argv, int flags, char *fsroot, char *fromfsroot, size_t size) -{ - if (!checkargs_fs(argc, argv)) - pefs_usage(); - - if (pefs_getfsroots(argv[0], flags, fsroot, fromfsroot, size) != 0) - exit(PEFS_ERR_INVALID); -} - static int openx_rdonly(const char *path) { @@ -1115,102 +1103,6 @@ return (error); } -/* - * XXXgpf: This should get the axe soon. But I'm keeping it here - * a little while longer just in case. - * - * pefs addchecklist [-i inputfile] [-o outputfile] filesystem - * - * $command creates an outputfile that may be supplied to - * `pefs addchecksum`. - * - * inputfile contains list of files that need integrity checking. - * Entries of this file list are just filepaths. Only one entry per line - * is allowed. - * e.g. "/mnt/my_file.txt\n" - * - * outputfile will be created and it will contain the same list of files, - * but encrypted filenames will be used instead. - * - * filesystem should be already mounted and key already supplied, so that - * filenames are decrypted. However, it must *not* be mounted on the same - * directory so that both decrypted and encrypted filenames exist at the - * same time in the system. - * - * A proper way of ensuring integrity checks for a pefs filesystem would be: - * - * pefs mount /usr/home/paul/priv.enc /mnt - * pefs addkey -c /mnt - * ./my_script > filelist.txt - * pefs addchecklist -i filelist.txt pefs_filelist /mnt - * pefs unmount /mnt - * pefs addchecksum -i pefs_filelist /usr/home/paul/p.enc - * pefs mount -o checksum=yes /usr/home/paul/priv.enc /any/path - * - */ -static int -pefs_addchecklist(int argc, char *argv[]) -{ - char fsroot[MAXPATHLEN], fromfsroot[MAXPATHLEN]; - char output_file[MAXPATHLEN]; - FILE *fpin; - int error, fdout, i; - - fpin = NULL; - fdout = -1; - - while ((i = getopt(argc, argv, "i:o:")) != -1) - switch(i) { - case 'i': - fpin = fopen(optarg, "r"); - if (fpin == NULL) { - warn("cannot open inputfile: %s", optarg); - return (PEFS_ERR_INVALID); - } - break; - case 'o': - strlcpy(output_file, optarg, sizeof(output_file)); - fdout = open(output_file, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); - if (fdout == -1) { - warn("cannot open %s", optarg); - return (PEFS_ERR_IO); - } - break; - default: - pefs_usage(); - } - argc -= optind; - argv += optind; - - if (fpin == NULL) { - pefs_warn("please supply an input file [-i]"); - return (PEFS_ERR_USAGE); - } - - if (fdout == -1) { - pefs_warn("please supply an output file [-o]"); - return (PEFS_ERR_USAGE); - } - - initfsroots(argc, argv, 0, fsroot, fromfsroot, sizeof(fsroot)); - - if (strcmp(fsroot, fromfsroot) == 0) { - pefs_warn("filesystem: %s must not be mounted upon itself!\n", fromfsroot); - unlink(output_file); - return (PEFS_ERR_USAGE); - } - - error = pefs_create_checklist(fpin, fdout, fsroot, fromfsroot); - - fclose(fpin); - close(fdout); - - if (error != 0) - unlink(output_file); - - return (error); -} - static void pefs_usage_alg(void) { @@ -1237,7 +1129,6 @@ " pefs showchains [-fp] [-i iterations] [-k keyfile] filesystem\n" " pefs showalgs\n" " pefs addchecksum [-a algo] [-i inputfile] [-p checksumpath] filesystem\n" -" pefs addchecklist [-i inputfile] [-o outputfile] filesystem\n" ); exit(PEFS_ERR_USAGE); } Modified: soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.h ============================================================================== --- soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.h Wed May 30 11:48:57 2012 (r236734) +++ soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.h Wed May 30 12:26:29 2012 (r236735) @@ -95,7 +95,6 @@ const struct pefs_xkey *xk_parent); uintmax_t pefs_keyid_as_int(char *keyid); int pefs_create_checksum_file(FILE *fpin, char *fsroot, char *csm_path, const char *algo); -int pefs_create_checklist(FILE *fpin, int fdout, char *fsroot, char *fromfsroot); const char * pefs_alg_name(struct pefs_xkey *xk); void pefs_alg_list(FILE *stream); Modified: soc2012/gpf/pefs_kmod/sbin/pefs/pefs_subr.c ============================================================================== --- soc2012/gpf/pefs_kmod/sbin/pefs/pefs_subr.c Wed May 30 11:48:57 2012 (r236734) +++ soc2012/gpf/pefs_kmod/sbin/pefs/pefs_subr.c Wed May 30 12:26:29 2012 (r236735) @@ -74,33 +74,3 @@ return (0); } -int -pefs_getfsroots(const char *path, int flags, char *fsroot, char * fromfsroot, size_t size) -{ - struct statfs fs; - const char *realfsroot, *realfromfsroot; - - if (statfs(path, &fs) == -1) { - pefs_warn("statfs failed: %s: %s", path, strerror(errno)); - return (PEFS_ERR_SYS); - } - - realfsroot = fs.f_mntonname; - if (strcmp(PEFS_FSTYPE, fs.f_fstypename) != 0) { - if ((flags & PEFS_FS_IGNORE_TYPE) != 0) - realfsroot = path; - else { - pefs_warn("invalid file system type: %s", path); - return (PEFS_ERR_INVALID); - } - } - - realfromfsroot = fs.f_mntfromname; - if (fromfsroot != NULL) - strlcpy(fromfsroot, realfromfsroot, size); - - if (fsroot != NULL) - strlcpy(fsroot, realfsroot, size); - - return (0); -} Modified: soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs.h ============================================================================== --- soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs.h Wed May 30 11:48:57 2012 (r236734) +++ soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs.h Wed May 30 12:26:29 2012 (r236735) @@ -48,17 +48,11 @@ char pxk_key[PEFS_KEY_SIZE]; }; -/* - * XXXgpf: [TODO] gleb says: - Adding 'x' to mark - it as exported to userspace will also be wise. So it's better be - pefs_xnamecsum or pefs_xname_csum. - */ -struct pefs_namemac { - uint64_t pnm_csum; - uint32_t pnm_namelen; +struct pefs_xnamecsum { + uint32_t pxnc_namelen; + char pxnc_csum[PEFS_NAME_CSUM_SIZE]; /* XXXgpf: should probably be MAXNAMLEN */ - char pnm_filename[MAXPATHLEN]; + char pxnc_filename[MAXPATHLEN]; }; struct pefs_xsector_ctext { @@ -74,7 +68,7 @@ #define PEFS_DELKEY _IOWR('p', 3, struct pefs_xkey) #define PEFS_FLUSHKEYS _IO('p', 4) #define PEFS_GETNODEKEY _IOWR('p', 5, struct pefs_xkey) -#define PEFS_GETNAMEMAC _IOWR('p', 6, struct pefs_namemac) +#define PEFS_GETNAMECSUM _IOWR('p', 6, struct pefs_xnamecsum) #define PEFS_GETSECTORCTEXT _IOWR('p', 7, struct pefs_xsector_ctext) #endif Modified: soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_vnops.c ============================================================================== --- soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_vnops.c Wed May 30 11:48:57 2012 (r236734) +++ soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_vnops.c Wed May 30 12:26:29 2012 (r236735) @@ -2362,7 +2362,7 @@ struct vnode *vp = ap->a_vp; struct vnode *lvp = PEFS_LOWERVP(vp); struct pefs_xkey *xk = ap->a_data; - struct pefs_namemac *namemac = ap->a_data; + struct pefs_xnamecsum *xncs = ap->a_data; struct pefs_xsector_ctext *xsct = ap->a_data; struct ucred *cred = ap->a_cred; struct thread *td = ap->a_td; @@ -2520,7 +2520,7 @@ pefs_chunk_free(&pc, pn); VOP_UNLOCK(vp, 0); break; - case PEFS_GETNAMEMAC: + case PEFS_GETNAMECSUM: vn_lock(vp, LK_EXCLUSIVE); /* XXXgpf: should I change printf to something else? e.g. PEFSDEBUG */ if (vp->v_type != VDIR) { @@ -2529,14 +2529,14 @@ return (EINVAL); } - if (strnlen(namemac->pnm_filename, sizeof(namemac->pnm_filename)) != - namemac->pnm_namelen) { - printf("pefs_ioctl: PEFS_GETNAMEMAC incorrect pnm_namelen %d\n", namemac->pnm_namelen); + if (strnlen(xncs->pxnc_filename, sizeof(xncs->pxnc_filename)) != + xncs->pxnc_namelen) { + printf("pefs_ioctl: PEFS_GETNAMEMAC incorrect pnm_namelen %d\n", xncs->pxnc_namelen); VOP_UNLOCK(vp, 0); return (EINVAL); } - if (strchr(namemac->pnm_filename, '/') != NULL) { + if (strchr(xncs->pxnc_filename, '/') != NULL) { printf("pefs_ioctl: PEFS_GETNAMEMAC pnm_filename contains '/'\n"); VOP_UNLOCK(vp, 0); return (EINVAL); @@ -2549,9 +2549,10 @@ cn.cn_cred = cred; cn.cn_lkflags = 0; cn.cn_flags = 0; - cn.cn_nameptr = namemac->pnm_filename; - cn.cn_namelen = namemac->pnm_namelen; + cn.cn_nameptr = xncs->pxnc_filename; + cn.cn_namelen = xncs->pxnc_namelen; + /* XXXgpf: does this lookup rely solely on present cache data? */ error = pefs_enccn_lookup(&enccn, vp, &cn); VOP_UNLOCK(vp, 0); @@ -2572,12 +2573,8 @@ r = pefs_name_pton(enc, enc_len, buf, buf_len); if (r <= 0) error = EINVAL; - /* - * XXXgpf: [TODO] endianess!! Change int64_t to char[8] - * and deal with endianess at user-space - */ else - memcpy(&(namemac->pnm_csum), buf, PEFS_NAME_CSUM_SIZE); + memcpy(xncs->pxnc_csum, buf, sizeof(xncs->pxnc_csum)); pefs_enccn_free(&enccn); free(buf, M_TEMP);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20120530122630.59184106564A>