Date: Tue, 14 Aug 2012 17:40:56 +0000 From: gpf@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r240351 - in soc2012/gpf/pefs_kmod: sbin/pefs sys/fs/pefs Message-ID: <20120814174056.A5A21106564A@hub.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: gpf Date: Tue Aug 14 17:40:56 2012 New Revision: 240351 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=240351 Log: minor fixes and some cosmetic changes 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/sys/fs/pefs/pefs_checksum.c Modified: soc2012/gpf/pefs_kmod/sbin/pefs/pefs_checksum.c ============================================================================== --- soc2012/gpf/pefs_kmod/sbin/pefs/pefs_checksum.c Tue Aug 14 14:07:34 2012 (r240350) +++ soc2012/gpf/pefs_kmod/sbin/pefs/pefs_checksum.c Tue Aug 14 17:40:56 2012 (r240351) @@ -53,11 +53,8 @@ #include <fs/pefs/pefs.h> -#include <openssl/dsa.h> -#include <openssl/engine.h> #include <openssl/evp.h> #include <openssl/pem.h> -#include <openssl/rand.h> #include "pefs_ctl.h" @@ -86,7 +83,7 @@ TAILQ_HEAD(checksum_head, checksum); /* tail that contains all file headers that require integrity checking */ TAILQ_HEAD(file_header_head, file_header); -/* tail for all the file_headers that refere to the same inode */ +/* tail for all the file_headers that refer to the same inode */ TAILQ_HEAD(hardlink_fh_head, file_header); /* RB tree for hardlink counters */ @@ -99,20 +96,26 @@ #define PEFS_FH_SIZE 16 /* - * This struct is used to check if all hardlinks for a given inode are supplied - * by the user + * This struct is used to check if all hardlinks for a given inode are + * supplied by the user. */ struct hardlink_counter { - ino_t inode; /* inode number for the file in question */ - uint32_t total_links; /* total hardlinks of the file */ - uint32_t links_found; /* how many links are found in user supplied list */ - struct hardlink_fh_head file_headers; /* file headers of the links we have found */ - RB_ENTRY(hardlink_counter) hardlink_entries; /* entry in hardlink RB tree */ + /* inode number for the file in question */ + ino_t inode; + /* total hardlinks of the file */ + uint32_t total_links; + /* how many links are found in user supplied list */ + uint32_t links_found; + /* file headers of the links we have found */ + struct hardlink_fh_head file_headers; + /* entry in hardlink RB tree */ + RB_ENTRY(hardlink_counter) hardlink_entries; }; -/* XXXgpf: unions for on disk structs and move to a different header? */ - -/* this is the unique file header of the .pefs.checksum file, found in the beginning of the file */ +/* + * This is the unique file header of the .pefs.checksum file, found in + * the beginning of the file. + */ struct checksum_file_header { uint8_t version; uint8_t reserved; @@ -134,21 +137,39 @@ /* XXXgpf: [TODO] turns offsets to uint64_t? */ struct file_header { - /* on disk information */ - uint32_t nhashes; /* the number of hashes for the file */ - uint32_t offset_to_checksums; /* in file offset to start of checksums */ - union file_id fid; /* id is MAC tweak from filename (first 64 bits) */ - - /* in memory information */ - char path[MAXPATHLEN + 1]; /* fullpath for this file */ - char dirpath[MAXPATHLEN + 1]; /* fullpath for this file's parent dir */ - char filename[MAXNAMLEN + 1]; /* filename */ - char *target_path; /*fullpath to this symlink's immediate next target */ - int fd, pfd; /* file descriptors for the file and its parent dir */ - int found; /* mark that this entry was found during "verify" action */ - struct checksum_head checksums; /* this file's checksums */ - TAILQ_ENTRY(file_header) file_header_entries; /* entry in global file header tail */ - TAILQ_ENTRY(file_header) fh_hardlink_entries; /* entry in hardlink counter */ + /* + * on disk information + */ + + /* the number of hashes for the file */ + uint32_t nhashes; + /* in file offset to start of checksums */ + uint32_t offset_to_checksums; + /* id is MAC tweak from filename (first 64 bits) */ + union file_id fid; + + /* + * in memory information + */ + + /* fullpath for this file */ + char path[MAXPATHLEN + 1]; + /* fullpath for this file's parent dir */ + char dirpath[MAXPATHLEN + 1]; + /* filename */ + char filename[MAXNAMLEN + 1]; + /*fullpath to this symlink's immediate next target */ + char *target_path; + /* file descriptors for the file and its parent dir */ + int fd, pfd; + /* mark that this entry was found during "verify" action */ + int found; + /* this file's checksums */ + struct checksum_head checksums; + /* entry in global file header tail */ + TAILQ_ENTRY(file_header) file_header_entries; + /* entry in hardlink counter */ + TAILQ_ENTRY(file_header) fh_hardlink_entries; }; struct bucket { @@ -203,8 +224,37 @@ return 0; } +static struct file_header * +pefs_allocate_file_header(void) +{ + struct file_header *fhp; + + fhp = malloc(sizeof(struct file_header)); + if (fhp == NULL) { + pefs_warn("memory allocation error"); + return (NULL); + } + + fhp->nhashes = 0; + fhp->offset_to_checksums = 0; + fhp->fid.fid_num = 0; + fhp->fd = -1; + fhp->pfd = -1; + fhp->found = 0; + + fhp->target_path = NULL; + + fhp->path[0] = '\0'; + fhp->dirpath[0] = '\0'; + fhp->filename[0] = '\0'; + + TAILQ_INIT(&(fhp->checksums)); + + return (fhp); +} + static void -pefs_close_file(struct file_header *fhp) +pefs_close_files(struct file_header *fhp) { if (fhp->fd >= 0) { close(fhp->fd); @@ -216,6 +266,24 @@ } } +static void +pefs_free_file_header(struct file_header *fhp) +{ + struct checksum *csp, *tcsp; + if (fhp != NULL) { + pefs_close_files(fhp); + TAILQ_FOREACH_SAFE(csp, &(fhp->checksums), checksum_entries, tcsp) { + TAILQ_REMOVE(&(fhp->checksums), csp, checksum_entries); + if (csp->hash != NULL) + free(csp->hash); + free(csp); + } + if (fhp->target_path != NULL) + free(fhp->target_path); + free(fhp); + } +} + static int pefs_compute_symlink_checksum(struct file_header *fhp, const EVP_MD *md, uint8_t hash_len, int flags) @@ -355,10 +423,10 @@ EVP_DigestInit_ex(&mdctx, md, NULL); EVP_DigestUpdate(&mdctx, buf, buf_len); - //dprintf(("read %d bytes\n\n", buf_len)); - //dprintf(("printing contents of buffer:")); - //for (i=0; i < (int)buf_len; i++) dprintf(("%c", buf[i])); - //dprintf(("!\n")); + dprintf(("read %d bytes\n\n", buf_len)); + dprintf(("printing contents of buffer:")); + for (i=0; i < (int)buf_len; i++) dprintf(("%c", buf[i])); + dprintf(("!\n")); csp = malloc(sizeof(struct checksum)); if (csp == NULL) { @@ -464,53 +532,6 @@ return (0); } -static struct file_header * -pefs_allocate_file_header(void) -{ - struct file_header *fhp; - - fhp = malloc(sizeof(struct file_header)); - if (fhp == NULL) { - pefs_warn("memory allocation error"); - return (NULL); - } - - fhp->nhashes = 0; - fhp->offset_to_checksums = 0; - fhp->fid.fid_num = 0; - fhp->fd = -1; - fhp->pfd = -1; - fhp->found = 0; - - fhp->target_path = NULL; - - fhp->path[0] = '\0'; - fhp->dirpath[0] = '\0'; - fhp->filename[0] = '\0'; - - TAILQ_INIT(&(fhp->checksums)); - - return (fhp); -} - -static void -pefs_free_file_header(struct file_header *fhp) -{ - struct checksum *csp, *tcsp; - if (fhp != NULL) { - pefs_close_file(fhp); - TAILQ_FOREACH_SAFE(csp, &(fhp->checksums), checksum_entries, tcsp) { - TAILQ_REMOVE(&(fhp->checksums), csp, checksum_entries); - if (csp->hash != NULL) - free(csp->hash); - free(csp); - } - if (fhp->target_path != NULL) - free(fhp->target_path); - free(fhp); - } -} - static void pefs_free_hash_table(struct cuckoo_hash_table *chtp) { @@ -809,7 +830,7 @@ pefs_warn("target file %s of symlink %s was not " "found in inputlist", targetfh.path, fhp->path); } - pefs_close_file(&targetfh); + pefs_close_files(&targetfh); } } } @@ -1123,7 +1144,7 @@ * A1d) Open and store file descriptors to file & parent_directory. * A2) the file_id is retrieved. (filename MAC) * A3) list of checksums is computed for the file's 4k blocks. - * A4) file entry is added to universal fh_head. + * A4) file entry is added to the universal fh_head. * B) Print warnings for hardlinks if the number of links found in inputlist * isn't equal to the number of total inode links. * C) Hash tables are allocated. @@ -1133,7 +1154,7 @@ * and try again until we succeed. The possibility to fail twice in a row is * 1.5% * 1.5% = 0.0225% * E) For each symlink found in input list, print warnings if its target file - * was not found in input list as well since symlinks are not traversed. + * was not found in input list since symlinks are not traversed. */ static int pefs_create_in_memory_db(FILE *fpin, const EVP_MD *md, uint8_t hash_len, @@ -1174,7 +1195,7 @@ } TAILQ_INSERT_TAIL(&fh_head, fhp, file_header_entries); - pefs_close_file(fhp); + pefs_close_files(fhp); } /* checking I/O error from pefs_next_file() */ @@ -1594,7 +1615,6 @@ unsigned char *sign; int bytes, error, rval, sign_len; - /* read public key from .pefs.pkey */ pkey = pefs_read_dsa_pubkey(pk_fp); if (pkey == NULL) return (PEFS_ERR_SYS); @@ -1859,11 +1879,11 @@ } (*buckets_offset)+= sizeof(fhp->fid.fid_str); - //dprintf(("\nfile header offset = %d\n", *fh_offset)); - //dprintf(("\n++priting file header info++\n")); - //dprintf(("nhashes %d\noffset_to_checksums %u\n", - //fhp->nhashes, fhp->offset_to_checksums)); - //dprintf(("file id %llu\n", fhp->file_id)); + dprintf(("\nfile header offset = %d\n", *fh_offset)); + dprintf(("\n++priting file header info++\n")); + dprintf(("nhashes %d\noffset_to_checksums %u\n", + fhp->nhashes, fhp->offset_to_checksums)); + dprintf(("file id %llu\n", fhp->file_id)); return (0); } @@ -1874,7 +1894,7 @@ struct file_header *fhp; int error; - //dprintf(("bucket offset = %d\n", *buckets_offset)); + dprintf(("bucket offset = %d\n", *buckets_offset)); fhp = pefs_allocate_file_header(); if (fhp == NULL) return (PEFS_ERR_SYS); @@ -1889,7 +1909,7 @@ } bp->fhp = fhp; - //dprintf(("\n++priting bucket info++\n")); + dprintf(("\n++priting bucket info++\n")); return (0); } @@ -1907,8 +1927,8 @@ } (*hashes_offset)+= hash_len; - //dprintf(("hashes offset = %d\n", *hashes_offset)); - //dprintf(("hash %s\n", csp->hash)); + dprintf(("hashes offset = %d\n", *hashes_offset)); + dprintf(("hash %s\n", csp->hash)); return (0); } @@ -2041,6 +2061,10 @@ /* * Traverse the entire filesystem and for every regular file or symbolic link, * look it up in .pefs.checksum index and verify its checksums. + * + * This function will try to avoid returning due to errors encountered when + * checksums mismatch or immutable flags are missing so as to print as many + * warnings as possible. */ static int pefs_traverse_fs(struct cuckoo_hash_table *chtp, const EVP_MD *md, @@ -2058,14 +2082,11 @@ while (dirp) { sdp = readdir(dirp); if (sdp != NULL) { - /* XXXgpf: [TODO] Need to pay special attention to these files */ if (strcmp(sdp->d_name, "..") == 0 || strcmp(sdp->d_name, ".") == 0 || strcmp(sdp->d_name, ".pefs.db") == 0 || strcmp(sdp->d_name, ".pefs.conf") == 0 || - strcmp(sdp->d_name, ".pefs.checksum") == 0 || - strcmp(sdp->d_name, ".pefs.signature") == 0 || - strcmp(sdp->d_name, ".pefs.pkey") == 0) + strcmp(sdp->d_name, ".pefs.checksum") == 0) continue; dprintf(("dirent: %s\n", sdp->d_name)); @@ -2089,8 +2110,8 @@ * Look up the file and verify its checksums. * Total number of checksums should be the same and checksums * should match. - * Also, take notice of hardlinks & symlink warnings. - * After the traversal is done, we must have found all of our + * Also, take care of hardlinks & symlink warnings. + * After the traversal is done, we should have found all of the * entries in the checksum file. */ /* FALLTHROUGH */ @@ -2152,7 +2173,7 @@ } /* - * if error encountered during pefs_compare_cehcksums, + * if error encountered during pefs_compare_checksums, * keep on traversing the fs to find other errors as well. */ error = pefs_compare_checksums(fhp, indexfhp, hash_len); @@ -2160,7 +2181,7 @@ *checksum_error = error; TAILQ_INSERT_TAIL(fh_headp, fhp, file_header_entries); - pefs_close_file(fhp); + pefs_close_files(fhp); break; default: break; @@ -2280,7 +2301,6 @@ pefs_symlink_warn(&cht, &fh_head); error = pefs_found_all_entries(&cht); - if (error == 0 && checksum_error != 0) error = checksum_error; @@ -2324,4 +2344,5 @@ return (error); } -RB_GENERATE(hardlink_head, hardlink_counter, hardlink_entries, pefs_hardlink_cmp); +RB_GENERATE(hardlink_head, hardlink_counter, hardlink_entries, + pefs_hardlink_cmp); Modified: soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.c ============================================================================== --- soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.c Tue Aug 14 14:07:34 2012 (r240350) +++ soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.c Tue Aug 14 17:40:56 2012 (r240351) @@ -1019,6 +1019,8 @@ * * inputfile contains list of files that need integrity checking. If * the argument is not supplied, input is read from stdin by default. + * These files should be either regular files or symbolic links. + * Symlinks are not traversed. * * path defines where .pefs.checksum should be created. By default, * .pefs.checksum is created under $PWD. path should be a directory, @@ -1038,7 +1040,7 @@ pefs_addchecksum(int argc, char *argv[]) { char fsroot[MAXPATHLEN + 1]; - char csm_path[MAXPATHLEN + 1], pk_path[MAXPATHLEN + 1]; + char csm_path[MAXPATHLEN + 1]; struct stat sb; FILE *fpin, *pk_fp; int error, flags, i, j; @@ -1049,9 +1051,8 @@ pk_fp = NULL; /* by default use sha256 */ algo = supported_digests[0]; - /* by default create checksum files under $PWD */ + /* by default create checksum file under $PWD */ snprintf(csm_path, sizeof(csm_path), "./%s", PEFS_FILE_CHECKSUM); - snprintf(pk_path, sizeof(pk_path), "./%s", PEFS_FILE_PKEY); while ((i = getopt(argc, argv, "fa:i:k:p:")) != -1) switch(i) { @@ -1102,8 +1103,6 @@ snprintf(csm_path, sizeof(csm_path), "%s/%s", optarg, PEFS_FILE_CHECKSUM); - snprintf(pk_path, sizeof(pk_path), "%s/%s", optarg, - PEFS_FILE_PKEY); break; default: if (fpin != NULL) @@ -1286,6 +1285,8 @@ * * filepath may refer to any kind of file that is encrypted by pefs filesystem, * such as directories, regular files, symlinks, etc. + * + * Symlinks are not traversed. */ static int pefs_nameid(int argc, char *argv[]) Modified: soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.h ============================================================================== --- soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.h Tue Aug 14 14:07:34 2012 (r240350) +++ soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.h Tue Aug 14 17:40:56 2012 (r240351) @@ -43,8 +43,6 @@ #define PEFS_FILE_KEYCHAIN ".pefs.db" #define PEFS_FILE_KEYCONF ".pefs.conf" #define PEFS_FILE_CHECKSUM ".pefs.checksum" -#define PEFS_FILE_SIGNATURE ".pefs.signature" -#define PEFS_FILE_PKEY ".pefs.pkey" #define PEFS_NOKEY 0x0001 #define PEFS_UNMOUNTED 0x0002 Modified: soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_checksum.c ============================================================================== --- soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_checksum.c Tue Aug 14 14:07:34 2012 (r240350) +++ soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_checksum.c Tue Aug 14 17:40:56 2012 (r240351) @@ -48,65 +48,6 @@ const char *pefs_checksum_supported_digests[] = {"sha256","sha512"}; uint8_t pefs_checksum_supported_hash_lengths[] = {32, 64}; -/* XXXgpf: tmp 4 dbg purposes */ -//static void -//pefs_dbg_checksum_file(struct pefs_checksum *pcs) -//{ - //char *p; - //int i; - //uint32_t nhashes; - //uint32_t offset; - //uint64_t file_id; - - ///* print .pefs.checksum file header info */ - //printf("\n+++CHECKSUM FILE HEADER INFO+++\n"); - //printf("version = %x\nreserved = %d\nhash len = %d\noffset = %d\nsize = %d\nalgo = %s\n\n", - //pcs->pcs_version, pcs->pcs_reserved, pcs->pcs_hash_len, pcs->pcs_offset_to_hash_table, - //pcs->pcs_hash_table_size, pcs->pcs_hash_algo_name); - - ///* print table1 */ - //printf("+++HASH TABLE 1+++\n\n"); - //for (i = 0; i < pcs->pcs_hash_table_size; i++) { - //p = &(pcs->pcs_table1[i * PEFS_HT_CELL_SIZE]); - - //memcpy(&nhashes, p, sizeof(nhashes)); - //nhashes = le32toh(nhashes); - //if (nhashes != 0) { - //p+=sizeof(nhashes); - //memcpy(&offset, p, sizeof(offset)); - //offset = le32toh(offset); - //p+=sizeof(offset); - //memcpy(&file_id, p, sizeof(file_id)); - //printf("cell %d:\n", i); - //printf("\thashes = %d\n\toffset = %d\n\tfile id = %llu\n", - //nhashes, offset, file_id); - //} - //else - //printf("cell %d: empty\n", i); - //} - - ///* print table2 */ - //printf("\n+++HASH TABLE 2+++\n\n"); - //for (i = 0; i < pcs->pcs_hash_table_size; i++) { - //p = &(pcs->pcs_table2[i * PEFS_HT_CELL_SIZE]); - - //memcpy(&nhashes, p, sizeof(nhashes)); - //nhashes = le32toh(nhashes); - //if (nhashes != 0) { - //p+=sizeof(nhashes); - //memcpy(&offset, p, sizeof(offset)); - //offset = le32toh(offset); - //p+=sizeof(offset); - //memcpy(&file_id, p, sizeof(file_id)); - //printf("cell %d:\n", i); - //printf("\thashes = %d\n\toffset = %d\n\tfile id = %llu\n", - //nhashes, offset, file_id); - //} - //else - //printf("cell %d: empty\n", i); - //} -//} - /* sanitize .pefs.checkum's global file header that's read during VFS_MOUNT() */ int pefs_sanitize_checksum_header(struct pefs_checksum *pcs) @@ -164,7 +105,7 @@ return (nbucket); } -/* fill out pcie for from data pointed to by p */ +/* fill out pcie from data pointed to by p */ static void pefs_get_index_entry(char *p, struct pefs_checksum_index_entry *pcie) { @@ -251,12 +192,9 @@ || ((pn->pn_flags & PN_NO_CHECKSUM) != 0)) goto not_found; - /* XXXgpf: What if user wants integrity checking for .pefs.db or .conf? */ if (strncmp(enc_name, ".pefs.db", enc_name_len) == 0 || strncmp(enc_name, ".pefs.conf", enc_name_len) == 0 || - strncmp(enc_name, ".pefs.checksum", enc_name_len) == 0 || - strncmp(enc_name, ".pefs.signature", enc_name_len) == 0 || - strncmp(enc_name, ".pefs.pkey", enc_name_len) == 0) + strncmp(enc_name, ".pefs.checksum", enc_name_len) == 0) goto not_found; enc_name++; @@ -282,6 +220,10 @@ /* * Check to see if schg flag is set, if not mark the vnode so that all * read access is denied. + * + * XXXgpf: [TODO] I should make sure that the PN_WRONG_CHECKSUM flag is + * used in other parts of the pefs codebase to deny access to the file + * data. */ error = VOP_GETATTR(vp, &va, cred); if (error != 0) { @@ -406,10 +348,6 @@ dprintf(("integrity checking!\noffset %llu\n", offset)); - /* - * XXXgpf: For the moment, this flag's only purpose is to deny read access - * to the file. Should it do more? - */ if ((pn->pn_flags & PN_WRONG_CHECKSUM) != 0) return (EAUTH);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20120814174056.A5A21106564A>