socsvn commit: r236605 - in soc2012/gpf/pefs_kmod: sbin/pefs
sys/fs/pefs
gpf at FreeBSD.org
gpf at FreeBSD.org
Mon May 28 17:02:34 UTC 2012
Author: gpf
Date: Mon May 28 17:02:31 2012
New Revision: 236605
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=236605
Log:
add ioctl() to retrieve ciphertext for specific 4k sector.
Modified:
soc2012/gpf/pefs_kmod/sbin/pefs/pefs_checksum.c
soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.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 Mon May 28 16:37:42 2012 (r236604)
+++ soc2012/gpf/pefs_kmod/sbin/pefs/pefs_checksum.c Mon May 28 17:02:31 2012 (r236605)
@@ -69,6 +69,7 @@
#define PEFS_FH_SIZE 16
#define PEFS_BUCKET_SIZE 8
+/* XXXgpf: unions for on disk structs and move to a different header? */
struct checksum_file_header {
uint8_t version;
uint8_t reserved;
@@ -83,6 +84,7 @@
TAILQ_ENTRY(checksum) checksum_entries;
};
+/* XXXgpf: [TODO] turns offsets to 64bits uints (or off_t?) */
struct file_header {
uint32_t nhashes;
uint64_t file_id;
@@ -108,13 +110,25 @@
pefs_compute_file_checksums(struct file_header *fhp, const EVP_MD *md,
uint8_t hash_len)
{
- char buf[PEFS_SECTOR_SIZE];
+
+ struct pefs_xsector_ctext xsct;
EVP_MD_CTX mdctx;
- int md_len, i, fd, bytes_read;
+ struct stat sb;
+ off_t resid;
+ uint32_t bytes_to_read;
+ int error, i, fd, md_len;
struct checksum *csp;
TAILQ_INIT(&(fhp->checksums));
+ /* XXXgpf: what happens if file size > 2^64? */
+ if (stat(fhp->path, &sb) != 0) {
+ warn("cannot stat file %s", fhp->path);
+ return (PEFS_ERR_SYS);
+ }
+
+ resid = sb.st_size;
+
fd = open(fhp->path, O_RDONLY);
if (fd < 0) {
warn("failed to open file: %s", fhp->path);
@@ -122,13 +136,31 @@
}
fhp->nhashes = 0;
- while ((bytes_read = read(fd, buf, sizeof(buf))) > 0) {
+ xsct.pxsct_offset = 0;
+ while (resid > 0) {
+ if (resid > PEFS_SECTOR_SIZE)
+ bytes_to_read = PEFS_SECTOR_SIZE;
+ else
+ bytes_to_read = resid;
+
+ resid-=bytes_to_read;
+ xsct.pxsct_ctext_len = bytes_to_read;
+ error = ioctl(fd, PEFS_GETSECTORCTEXT, &xsct);
+ if (error != 0) {
+ pefs_warn("error retrieving ciphertext of %s", fhp->path);
+ close(fd);
+ return (PEFS_ERR_IO);
+ }
+ xsct.pxsct_offset+= xsct.pxsct_ctext_len;
+
EVP_MD_CTX_init(&mdctx);
EVP_DigestInit_ex(&mdctx, md, NULL);
- EVP_DigestUpdate(&mdctx, buf, bytes_read);
+ EVP_DigestUpdate(&mdctx, xsct.pxsct_ctext, xsct.pxsct_ctext_len);
- dprintf(("read %d bytes\n", bytes_read));
- //for (i=0; i<bytes_read; i++) dprintf(("%c", buf[i]));
+ dprintf(("read %d bytes from kernel\n\n", bytes_to_read));
+ dprintf(("printing contents of buffer:"));
+ for (i=0; i < (int)bytes_to_read; i++) dprintf(("%c", xsct.pxsct_ctext[i]));
+ dprintf(("!\n"));
csp = malloc(sizeof(struct checksum));
if (csp == NULL) {
@@ -304,7 +336,7 @@
dprintf(("\nbucket %d with elements: %u\n", i, checksum_hash_tablep->buckets[i].nelements));
LIST_FOREACH(fhp, &(checksum_hash_tablep->buckets[i].file_headers), bucket_entries) {
//printf(("\tpath=%s!\t id = %d!\tnhashes = %d\n", fhp->path, (int)fhp->file_id, fhp->nhashes));
- dprintf(("\tid = %d!\tnhashes = %d\n", (int)fhp->file_id, fhp->nhashes));
+ dprintf(("\tid = %llu!\tnhashes = %d\n", fhp->file_id, fhp->nhashes));
TAILQ_FOREACH(csp, &(fhp->checksums), checksum_entries) {
dprintf(("\t\tdigest="));
for (j = 0; j < hash_len; j++)
@@ -613,7 +645,7 @@
* All data member writes are done separately so as to avoid alignment problems.
* Writes are always in little endian byte order.
*
- * TODO more comments about internal structure of file
+ * XXXgpf: [TODO] more comments about internal structure of file.
*/
static int
pefs_write_checksum_file(int fdout, struct checksum_file_header *cfhp, struct hash_table *chtp)
Modified: soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.c
==============================================================================
--- soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.c Mon May 28 16:37:42 2012 (r236604)
+++ soc2012/gpf/pefs_kmod/sbin/pefs/pefs_ctl.c Mon May 28 17:02:31 2012 (r236605)
@@ -108,6 +108,8 @@
{ NULL, NULL },
};
+
+/* XXXgpf: [TODO] should probably add more at a later point */
const char *supported_digests[] = {"sha256","sha512"};
void
@@ -1048,7 +1050,6 @@
/* by default create checksum file under $PWD */
snprintf(csm_path, sizeof(csm_path), "./%s", PEFS_FILE_CHECKSUM);
- /* XXXgpf: [TODO] add argument for user to specify path for .pefs. checksum */
while ((i = getopt(argc, argv, "a:i:p:")) != -1)
switch(i) {
case 'a':
Modified: soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs.h
==============================================================================
--- soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs.h Mon May 28 16:37:42 2012 (r236604)
+++ soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs.h Mon May 28 17:02:31 2012 (r236605)
@@ -61,6 +61,12 @@
char pnm_filename[MAXPATHLEN];
};
+struct pefs_xsector_ctext {
+ off_t pxsct_offset;
+ uint32_t pxsct_ctext_len;
+ char pxsct_ctext[PEFS_SECTOR_SIZE];
+};
+
#ifdef _IO
#define PEFS_GETKEY _IOWR('p', 0, struct pefs_xkey)
#define PEFS_ADDKEY _IOWR('p', 1, struct pefs_xkey)
@@ -69,6 +75,7 @@
#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_GETSECTORCTEXT _IOWR('p', 7, struct pefs_xsector_ctext)
#endif
#ifdef _KERNEL
Modified: soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_vnops.c
==============================================================================
--- soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_vnops.c Mon May 28 16:37:42 2012 (r236604)
+++ soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_vnops.c Mon May 28 17:02:31 2012 (r236605)
@@ -2357,15 +2357,20 @@
{
struct pefs_enccn enccn;
struct componentname cn;
+ struct pefs_chunk pc;
+ u_quad_t fsize;
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_xsector_ctext *xsct = ap->a_data;
struct ucred *cred = ap->a_cred;
struct thread *td = ap->a_td;
struct mount *mp = vp->v_mount;
struct pefs_mount *pm = VFS_TO_PEFS(mp);
struct pefs_node *pn;
struct pefs_key *pk;
+ struct uio *puio;
char *enc, *buf;
size_t enc_len, buf_len;
int error = 0, i, r;
@@ -2470,28 +2475,73 @@
if (pefs_key_remove_all(pm))
pefs_flushkey(mp, td, PEFS_FLUSHKEY_ALL, NULL);
break;
+ case PEFS_GETSECTORCTEXT:
+ vn_lock(vp, LK_EXCLUSIVE);
+
+ if (vp->v_type != VREG) {
+ printf("pefs_ioctl: PEFS_GETSECTORCTEXT vp is not a reg file\n");
+ VOP_UNLOCK(vp, 0);
+ return (EOPNOTSUPP);
+ }
+
+ error = pefs_getsize(vp, &fsize, cred);
+ if (error != 0) {
+ VOP_UNLOCK(vp, 0);
+ return (error);
+ }
+
+ if (xsct->pxsct_ctext_len > PEFS_SECTOR_SIZE || xsct->pxsct_ctext_len == 0
+ || xsct->pxsct_ctext_len > fsize) {
+ printf("pefs_ioctl: PEFS_GETSECTORCTEXT invalid len: %d\n",
+ xsct->pxsct_ctext_len);
+ VOP_UNLOCK(vp, 0);
+ return (EINVAL);
+ }
+
+ if (xsct->pxsct_offset > (fsize - xsct->pxsct_ctext_len)) {
+ printf("pefs_ioctl: PEFS_GETSECTORCTEXT invalid offset: %llu\n",
+ xsct->pxsct_offset);
+ VOP_UNLOCK(vp, 0);
+ return (EINVAL);
+ }
+
+ pn = VP_TO_PN(vp);
+ pefs_chunk_create(&pc, pn, xsct->pxsct_ctext_len);
+ puio = pefs_chunk_uio(&pc, xsct->pxsct_offset, UIO_READ);
+
+ /* XXXgpf: is this lock really necessary? */
+ vn_lock(lvp, LK_EXCLUSIVE);
+ error = VOP_READ(lvp, puio, IO_UNIT | IO_NODELOCKED, cred);
+ VOP_UNLOCK(lvp, 0);
+
+ if (error == 0)
+ memcpy(xsct->pxsct_ctext, pc.pc_base, xsct->pxsct_ctext_len);
+
+ pefs_chunk_free(&pc, pn);
+ VOP_UNLOCK(vp, 0);
+ break;
case PEFS_GETNAMEMAC:
- /* XXXgpf: should I change printf to PEFSDEBUG or something else? */
+ vn_lock(vp, LK_EXCLUSIVE);
+ /* XXXgpf: should I change printf to something else? e.g. PEFSDEBUG */
if (vp->v_type != VDIR) {
printf("pefs_ioctl: PEFS_GETNAMEMAC vp is not a directory\n");
- error = EINVAL;
- break;
+ VOP_UNLOCK(vp, 0);
+ 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);
- error = EINVAL;
- break;
+ VOP_UNLOCK(vp, 0);
+ return (EINVAL);
}
if (strchr(namemac->pnm_filename, '/') != NULL) {
printf("pefs_ioctl: PEFS_GETNAMEMAC pnm_filename contains '/'\n");
- error = EINVAL;
- break;
+ VOP_UNLOCK(vp, 0);
+ return (EINVAL);
}
- vn_lock(vp, LK_EXCLUSIVE);
pefs_enccn_init(&enccn);
cn.cn_nameiop = LOOKUP;
@@ -2522,6 +2572,10 @@
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);
More information about the svn-soc-all
mailing list