socsvn commit: r240351 - in soc2012/gpf/pefs_kmod: sbin/pefs
sys/fs/pefs
gpf at FreeBSD.org
gpf at FreeBSD.org
Tue Aug 14 17:40:58 UTC 2012
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);
More information about the svn-soc-all
mailing list