[Libguestfs] [PATCH v2 3/3] find_block: added API tests
NTFS file system always has the Boot file at block 0. This reliable information helps testing the API. Signed-off-by: Matteo Cafasso--- tests/tsk/Makefile.am| 1 + tests/tsk/test-find-block.sh | 66 2 files changed, 67 insertions(+) create mode 100755 tests/tsk/test-find-block.sh diff --git a/tests/tsk/Makefile.am b/tests/tsk/Makefile.am index 07c74f9..44a893e 100644 --- a/tests/tsk/Makefile.am +++ b/tests/tsk/Makefile.am @@ -21,6 +21,7 @@ TESTS = \ test-download-inode.sh \ test-download-blocks.sh \ test-filesystem-walk.sh \ + test-find-block.sh \ test-find-inode.sh TESTS_ENVIRONMENT = $(top_builddir)/run --test diff --git a/tests/tsk/test-find-block.sh b/tests/tsk/test-find-block.sh new file mode 100755 index 000..984947d --- /dev/null +++ b/tests/tsk/test-find-block.sh @@ -0,0 +1,66 @@ +#!/bin/bash - +# libguestfs +# Copyright (C) 2016 Red Hat Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +# Test the find-block command. + +if [ -n "$SKIP_TEST_FIND_BLOCK_SH" ]; then +echo "$0: test skipped because environment variable is set." +exit 77 +fi + +# Skip if TSK is not supported by the appliance. +if ! guestfish add /dev/null : run : available "libtsk"; then +echo "$0: skipped because TSK is not available in the appliance" +exit 77 +fi + +if [ ! -s ../../test-data/phony-guests/windows.img ]; then +echo "$0: skipped because windows.img is zero-sized" +exit 77 +fi + +output=$( +guestfish --ro -a ../../test-data/phony-guests/windows.img
[Libguestfs] [PATCH v2 1/3] New API: internal_find_block
The internal_find_block command searches all entries referring to the given filesystem data block and returns a tsk_dirent structure for each of them. For filesystems such as NTFS which do not delete the block mapping when removing files, it is possible to get multiple non-allocated entries for the same block. The gathered list of tsk_dirent structs is serialised into XDR format and written to a file by the appliance. Signed-off-by: Matteo Cafasso--- daemon/tsk.c | 90 generator/actions.ml | 9 ++ src/MAX_PROC_NR | 2 +- 3 files changed, 100 insertions(+), 1 deletion(-) diff --git a/daemon/tsk.c b/daemon/tsk.c index af803d7..38d7c3f 100644 --- a/daemon/tsk.c +++ b/daemon/tsk.c @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -42,9 +43,16 @@ enum tsk_dirent_flags { DIRENT_COMPRESSED = 0x04 }; +typedef struct { + bool found; + uint64_t block; +} findblk_data; + static int open_filesystem (const char *, TSK_IMG_INFO **, TSK_FS_INFO **); static TSK_WALK_RET_ENUM fswalk_callback (TSK_FS_FILE *, const char *, void *); static TSK_WALK_RET_ENUM findino_callback (TSK_FS_FILE *, const char *, void *); +static TSK_WALK_RET_ENUM findblk_callback (TSK_FS_FILE *, const char *, void *); +static TSK_WALK_RET_ENUM attrwalk_callback (TSK_FS_FILE *, TSK_OFF_T , TSK_DADDR_T , char *, size_t , TSK_FS_BLOCK_FLAG_ENUM , void *); static int send_dirent_info (TSK_FS_FILE *, const char *); static char file_type (TSK_FS_FILE *); static int file_flags (TSK_FS_FILE *fsfile); @@ -109,6 +117,36 @@ do_internal_find_inode (const mountable_t *mountable, int64_t inode) return ret; } +int +do_internal_find_block (const mountable_t *mountable, int64_t block) +{ + int ret = -1; + TSK_FS_INFO *fs = NULL; + TSK_IMG_INFO *img = NULL; /* Used internally by tsk_fs_dir_walk */ + const int flags = +TSK_FS_DIR_WALK_FLAG_ALLOC | TSK_FS_DIR_WALK_FLAG_UNALLOC | +TSK_FS_DIR_WALK_FLAG_RECURSE | TSK_FS_DIR_WALK_FLAG_NOORPHAN; + + ret = open_filesystem (mountable->device, , ); + if (ret < 0) +return ret; + + reply (NULL, NULL); /* Reply message. */ + + ret = tsk_fs_dir_walk (fs, fs->root_inum, flags, + findblk_callback, (void *) ); + if (ret == 0) +ret = send_file_end (0); /* File transfer end. */ + else +send_file_end (1); /* Cancel file transfer. */ + + fs->close (fs); + img->close (img); + + return ret; +} + + /* Inspect the device and initialises the img and fs structures. * Return 0 on success, -1 on error. */ @@ -172,6 +210,58 @@ findino_callback (TSK_FS_FILE *fsfile, const char *path, void *data) return (ret == 0) ? TSK_WALK_CONT : TSK_WALK_ERROR; } +/* Find block, it gets called on every FS node. + * + * Return TSK_WALK_CONT on success, TSK_WALK_ERROR on error. + */ +static TSK_WALK_RET_ENUM +findblk_callback (TSK_FS_FILE *fsfile, const char *path, void *data) +{ + findblk_data blkdata; + const TSK_FS_ATTR *fsattr = NULL; + int ret = 0, count = 0, index = 0; + uint64_t *block = (uint64_t *) data; + const int flags = TSK_FS_FILE_WALK_FLAG_AONLY | TSK_FS_FILE_WALK_FLAG_SLACK; + + if (entry_is_dot (fsfile)) +return TSK_WALK_CONT; + + blkdata.found = false; + blkdata.block = *block; + + /* Retrieve block list */ + count = tsk_fs_file_attr_getsize (fsfile); + + for (index = 0; index < count; index++) { +fsattr = tsk_fs_file_attr_get_idx (fsfile, index); + +if (fsattr != NULL && fsattr->flags & TSK_FS_ATTR_NONRES) + tsk_fs_attr_walk (fsattr, flags, attrwalk_callback, (void*) ); + } + + if (blkdata.found) +ret = send_dirent_info (fsfile, path); + + return (ret == 0) ? TSK_WALK_CONT : TSK_WALK_ERROR; +} + +/* Attribute walk, searches the given block within the FS node attributes. */ +static TSK_WALK_RET_ENUM +attrwalk_callback (TSK_FS_FILE *fsfile, TSK_OFF_T offset, + TSK_DADDR_T blkaddr, char *buf, size_t size, + TSK_FS_BLOCK_FLAG_ENUM flags, void *data) +{ + findblk_data *blkdata = (findblk_data *) data; + + if (blkaddr == blkdata->block) { +blkdata->found = true; + +return TSK_WALK_STOP; + } + + return TSK_WALK_CONT; +} + /* Extract the information from the entry, serialize and send it out. * Return 0 on success, -1 on error. */ diff --git a/generator/actions.ml b/generator/actions.ml index 91a1819..b38a30f 100644 --- a/generator/actions.ml +++ b/generator/actions.ml @@ -13253,6 +13253,15 @@ is removed." }; shortdesc = "search the entries associated to the given inode"; longdesc = "Internal function for find_inode." }; + { defaults with +name = "internal_find_block"; added = (1, 35, 6); +style = RErr, [Mountable "device"; Int64 "block"; FileOut "filename";], []; +proc_nr = Some 471; +visibility = VInternal; +optional = Some "libtsk"; +shortdesc = "search the entries associated to the given block"; +
[Libguestfs] [PATCH v2 2/3] New API: find_block
Library's counterpart of the daemon's internal_find_block command. It writes the daemon's command output on a temporary file and parses it, deserialising the XDR formatted tsk_dirent structs. It returns to the caller the list of tsk_dirent structs generated by the internal_find_block command. Signed-off-by: Matteo Cafasso--- generator/actions.ml | 16 src/tsk.c| 17 + 2 files changed, 33 insertions(+) diff --git a/generator/actions.ml b/generator/actions.ml index b38a30f..8947551 100644 --- a/generator/actions.ml +++ b/generator/actions.ml @@ -3729,6 +3729,22 @@ Searches all the entries associated with the given inode. For each entry, a C structure is returned. See C for more information about C structures." }; + { defaults with +name = "find_block"; added = (1, 35, 6); +style = RStructList ("dirents", "tsk_dirent"), [Mountable "device"; Int64 "block";], []; +optional = Some "libtsk"; +progress = true; cancellable = true; +shortdesc = "search the entries referring to the given data block"; +longdesc = "\ +Searches all the entries referring to the given data block. + +Certain filesystems preserve the block mapping when deleting a file. +Therefore, it is possible to see multiple deleted files referring +to the same block. + +For each entry, a C structure is returned. +See C for more information about C structures." }; + ] (* daemon_functions are any functions which cause some action diff --git a/src/tsk.c b/src/tsk.c index 1def9c9..7db6f71 100644 --- a/src/tsk.c +++ b/src/tsk.c @@ -72,6 +72,23 @@ guestfs_impl_find_inode (guestfs_h *g, const char *mountable, int64_t inode) return parse_dirent_file (g, tmpfile); /* caller frees */ } +struct guestfs_tsk_dirent_list * +guestfs_impl_find_block (guestfs_h *g, const char *mountable, int64_t block) +{ + int ret = 0; + CLEANUP_UNLINK_FREE char *tmpfile = NULL; + + tmpfile = make_temp_file (g, "find_block"); + if (tmpfile == NULL) +return NULL; + + ret = guestfs_internal_find_block (g, mountable, block, tmpfile); + if (ret < 0) +return NULL; + + return parse_dirent_file (g, tmpfile); /* caller frees */ +} + /* Parse the file content and return dirents list. * Return a list of tsk_dirent on success, NULL on error. */ -- 2.9.3 ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
[Libguestfs] [PATCH v2 0/3] New API - find_block
v2: - use boolean field in struct - move refactoring to previous series Matteo Cafasso (3): New API: internal_find_block New API: find_block find_block: added API tests daemon/tsk.c | 90 generator/actions.ml | 25 src/MAX_PROC_NR | 2 +- src/tsk.c| 17 + tests/tsk/Makefile.am| 1 + tests/tsk/test-find-block.sh | 66 6 files changed, 200 insertions(+), 1 deletion(-) create mode 100755 tests/tsk/test-find-block.sh -- 2.9.3 ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
Re: [Libguestfs] [PATCH v7 0/4] New API - find_inode
On Monday, 19 September 2016 19:42:48 CEST Matteo Cafasso wrote: > v7: > > - Merge src/tsk.c refactoring patch with #4 of find_block series > > Matteo Cafasso (4): > lib: logic refactoring > New API: internal_find_inode > New API: find_inode > find_inode: added API tests LGTM, pushed. Thanks for the work, and all the patience to polish it! -- Pino Toscano signature.asc Description: This is a digitally signed message part. ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
Re: [Libguestfs] [PATCH 3/3] OCaml tools: add crypto support (RHBZ#1362649)
On Mon, Sep 19, 2016 at 07:12:46PM +0200, Pino Toscano wrote: > Make use of the additional command line arguments, and API needed to > decrypt LUKS partitions. > > This affects only virt-customize, virt-get-kernel, virt-sparsify, and > virt-sysprep, as they are the main OCaml tools interacting with > user-provided images. > --- > customize/customize_main.ml| 5 - > customize/virt-customize.pod | 12 > get-kernel/get_kernel.ml | 5 - > get-kernel/virt-get-kernel.pod | 12 > sparsify/cmdline.ml| 2 +- > sparsify/copying.ml| 3 +++ > sparsify/in_place.ml | 3 +++ > sparsify/virt-sparsify.pod | 12 > sysprep/main.ml| 5 - > sysprep/virt-sysprep.pod | 12 > 10 files changed, 67 insertions(+), 4 deletions(-) > > diff --git a/customize/customize_main.ml b/customize/customize_main.ml > index 07fd790..5613277 100644 > --- a/customize/customize_main.ml > +++ b/customize/customize_main.ml > @@ -102,7 +102,7 @@ A short summary of the options is given below. For > detailed help please > read the man page virt-customize(1). > ") >prog in > - let opthandle = create_standard_options argspec usage_msg in > + let opthandle = create_standard_options argspec ~key_opts:true usage_msg in >Getopt.parse opthandle; > >if not !format_consumed then > @@ -175,6 +175,9 @@ read the man page virt-customize(1). > g#launch (); > g in > > + (* Decrypt the disks. *) > + inspect_decrypt g; > + >(* Inspection. *) >(match Array.to_list (g#inspect_os ()) with >| [] -> > diff --git a/customize/virt-customize.pod b/customize/virt-customize.pod > index e594f61..a0ca9c9 100644 > --- a/customize/virt-customize.pod > +++ b/customize/virt-customize.pod > @@ -107,6 +107,13 @@ used instead of names. > Perform a read-only "dry run" on the guest. This runs the sysprep > operation, but throws away any changes to the disk at the end. > > +=item B<--echo-keys> > + > +When prompting for keys and passphrases, virt-customize normally turns > +echoing off so you cannot see what you are typing. If you are not > +worried about Tempest attacks and there is no one else in the room > +you can specify this flag to see what you are typing. > + > =item B<--format> raw|qcow2|.. > > =item B<--format> auto > @@ -131,6 +138,11 @@ If you have untrusted raw-format guest disk images, you > should use > this option to specify the disk format. This avoids a possible > security problem with malicious guests (CVE-2010-3851). > > +=item B<--keys-from-stdin> > + > +Read key or passphrase parameters from stdin. The default is > +to try to read passphrases from the user by opening F. > + > =item B<-m> MB > > =item B<--memsize> MB > diff --git a/get-kernel/get_kernel.ml b/get-kernel/get_kernel.ml > index f83a940..adf9649 100644 > --- a/get-kernel/get_kernel.ml > +++ b/get-kernel/get_kernel.ml > @@ -70,7 +70,7 @@ A short summary of the options is given below. For > detailed help please > read the man page virt-get-kernel(1). > ") >prog in > - let opthandle = create_standard_options argspec usage_msg in > + let opthandle = create_standard_options argspec ~key_opts:true usage_msg in >Getopt.parse opthandle; > >(* Machine-readable mode? Print out some facts about what > @@ -174,6 +174,9 @@ let main () = >add g; >g#launch (); > > + (* Decrypt the disks. *) > + inspect_decrypt g; > + >let roots = g#inspect_os () in >if Array.length roots = 0 then > error (f_"no operating system found"); > diff --git a/get-kernel/virt-get-kernel.pod b/get-kernel/virt-get-kernel.pod > index 97a159c..8298fe5 100644 > --- a/get-kernel/virt-get-kernel.pod > +++ b/get-kernel/virt-get-kernel.pod > @@ -70,6 +70,13 @@ not used at all. > Add all the disks from the named libvirt guest. Domain UUIDs can be > used instead of names. > > +=item B<--echo-keys> > + > +When prompting for keys and passphrases, virt-get-kernel normally turns > +echoing off so you cannot see what you are typing. If you are not > +worried about Tempest attacks and there is no one else in the room > +you can specify this flag to see what you are typing. > + > =item B<--format> raw|qcow2|.. > > =item B<--format> auto > @@ -82,6 +89,11 @@ If you have untrusted raw-format guest disk images, you > should use > this option to specify the disk format. This avoids a possible > security problem with malicious guests (CVE-2010-3851). > > +=item B<--keys-from-stdin> > + > +Read key or passphrase parameters from stdin. The default is > +to try to read passphrases from the user by opening F. > + > =item B<--machine-readable> > > This option is used to make the output more machine friendly > diff --git a/sparsify/cmdline.ml b/sparsify/cmdline.ml > index 523d612..2a9dd48 100644 > --- a/sparsify/cmdline.ml > +++ b/sparsify/cmdline.ml > @@ -90,7 +90,7 @@ A short summary of the
Re: [Libguestfs] [PATCH 2/3] mllib: expose disk decrypt functionalities
On Mon, Sep 19, 2016 at 07:12:45PM +0200, Pino Toscano wrote: > +let inspect_decrypt g = > + (* Note we pass original 'g' even though it is not used by the > + * callee. This is so that 'g' is kept as a root on the stack, and > + * so cannot be garbage collected while we are in the c_edit_file I'm guessing you mean "the c_inspect_decrypt function." > + * function. > + *) > + c_inspect_decrypt g#ocaml_handle (Guestfs.c_pointer g#ocaml_handle) ACK with that small comment fix. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com Fedora Windows cross-compiler. Compile Windows programs, test, and build Windows installers. Over 100 libraries supported. http://fedoraproject.org/wiki/MinGW ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
Re: [Libguestfs] [PATCH 1/3] fish: move disk decryption helpers in own file
On Mon, Sep 19, 2016 at 07:12:44PM +0200, Pino Toscano wrote: > This way it is easier to use them outside the rest of the code in > guestfish for inspection & mount. > > Just code motion, no behaviour changes. > --- > align/Makefile.am | 1 + > cat/Makefile.am | 1 + > df/Makefile.am| 1 + > diff/Makefile.am | 1 + > edit/Makefile.am | 1 + > fish/Makefile.am | 1 + > fish/decrypt.c| 102 > ++ > fish/inspect.c| 68 - > fish/options.h| 4 +- > format/Makefile.am| 1 + > fuse/Makefile.am | 1 + > inspector/Makefile.am | 1 + > rescue/Makefile.am| 1 + > 13 files changed, 115 insertions(+), 69 deletions(-) > create mode 100644 fish/decrypt.c > > diff --git a/align/Makefile.am b/align/Makefile.am > index 1eccf28..eb44263 100644 > --- a/align/Makefile.am > +++ b/align/Makefile.am > @@ -33,6 +33,7 @@ SHARED_SOURCE_FILES = \ > ../df/parallel.c \ > ../df/parallel.h \ > ../fish/config.c \ > + ../fish/decrypt.c \ > ../fish/display-options.h \ > ../fish/display-options.c \ > ../fish/domain.c \ > diff --git a/cat/Makefile.am b/cat/Makefile.am > index 38faa94..5e55742 100644 > --- a/cat/Makefile.am > +++ b/cat/Makefile.am > @@ -31,6 +31,7 @@ EXTRA_DIST = \ > bin_PROGRAMS = virt-cat virt-filesystems virt-log virt-ls > > SHARED_SOURCE_FILES = \ > + ../fish/decrypt.c \ > ../fish/display-options.h \ > ../fish/display-options.c \ > ../fish/domain.c \ > diff --git a/df/Makefile.am b/df/Makefile.am > index ce1686a..6efc1dc 100644 > --- a/df/Makefile.am > +++ b/df/Makefile.am > @@ -28,6 +28,7 @@ bin_PROGRAMS = virt-df > > SHARED_SOURCE_FILES = \ > ../fish/config.c \ > + ../fish/decrypt.c \ > ../fish/display-options.h \ > ../fish/display-options.c \ > ../fish/domain.c \ > diff --git a/diff/Makefile.am b/diff/Makefile.am > index cdbe05c..7dfe2cd 100644 > --- a/diff/Makefile.am > +++ b/diff/Makefile.am > @@ -27,6 +27,7 @@ bin_PROGRAMS = virt-diff > SHARED_SOURCE_FILES = \ > ../cat/visit.h \ > ../cat/visit.c \ > + ../fish/decrypt.c \ > ../fish/display-options.h \ > ../fish/display-options.c \ > ../fish/domain.c \ > diff --git a/edit/Makefile.am b/edit/Makefile.am > index 4ac4f08..dc9fbb0 100644 > --- a/edit/Makefile.am > +++ b/edit/Makefile.am > @@ -26,6 +26,7 @@ bin_PROGRAMS = virt-edit > > SHARED_SOURCE_FILES = \ > ../fish/config.c \ > + ../fish/decrypt.c \ > ../fish/display-options.h \ > ../fish/display-options.c \ > ../fish/domain.c \ > diff --git a/fish/Makefile.am b/fish/Makefile.am > index e1bc210..8fdcd27 100644 > --- a/fish/Makefile.am > +++ b/fish/Makefile.am > @@ -73,6 +73,7 @@ EXTRA_DIST = \ > # files must not include other guestfish files. > SHARED_SOURCE_FILES = \ > config.c \ > + decrypt.c \ > display-options.h \ > display-options.c \ > domain.c \ > diff --git a/fish/decrypt.c b/fish/decrypt.c > new file mode 100644 > index 000..d6e041d > --- /dev/null > +++ b/fish/decrypt.c > @@ -0,0 +1,102 @@ > +/* libguestfs - shared disk decryption > + * Copyright (C) 2010 Red Hat Inc. > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation; either version 2 of the License, or > + * (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 > USA. > + */ > + > +/** > + * This file implements the decryption of disk images, usually done > + * before mounting their partitions. > + */ > + > +#include > + > +#include > +#include > +#include > + > +#include "c-ctype.h" > + > +#include "guestfs.h" > + > +#include "options.h" > + > +/** > + * Make a LUKS map name from the partition name, > + * eg. C<"/dev/vda2" =E "luksvda2"> > + */ > +static void > +make_mapname (const char *device, char *mapname, size_t len) > +{ > + size_t i = 0; > + > + if (len < 5) > +abort (); > + strcpy (mapname, "luks"); > + mapname += 4; > + len -= 4; > + > + if (STRPREFIX (device, "/dev/")) > +i = 5; > + > + for (; device[i] != '\0' && len >= 1; ++i) { > +if (c_isalnum (device[i])) { > + *mapname++ = device[i]; > + len--; > +} > + } > + > + *mapname = '\0'; > +} > + > +/** > + * Simple implementation of decryption: look for any C > + * partitions and decrypt them,
[Libguestfs] [PATCH 2/3] mllib: expose disk decrypt functionalities
Expose via Common_utils the C functions & variables (part of guestfish) that handle decryption of LUKS partitions, and the additional command line arguments to tune the way they work. This way it will be easy to provide (basic) crypto support also in OCaml-based tools. Related to: RHBZ#1362649 --- mllib/Makefile.am | 3 ++ mllib/common_utils-c.c | 75 ++ mllib/common_utils.ml | 22 ++- mllib/common_utils.mli | 10 ++- 4 files changed, 108 insertions(+), 2 deletions(-) create mode 100644 mllib/common_utils-c.c diff --git a/mllib/Makefile.am b/mllib/Makefile.am index e93771e..489529a 100644 --- a/mllib/Makefile.am +++ b/mllib/Makefile.am @@ -63,8 +63,11 @@ SOURCES_ML = \ exit.ml SOURCES_C = \ + ../fish/decrypt.c \ + ../fish/keys.c \ ../fish/progress.c \ ../fish/uri.c \ + common_utils-c.c \ dev_t-c.c \ exit-c.c \ fsync-c.c \ diff --git a/mllib/common_utils-c.c b/mllib/common_utils-c.c new file mode 100644 index 000..d674377 --- /dev/null +++ b/mllib/common_utils-c.c @@ -0,0 +1,75 @@ +/* libguestfs OCaml tools common code + * Copyright (C) 2016 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifdef HAVE_CAML_UNIXSUPPORT_H +#include +#else +#define Nothing ((value) 0) +extern void unix_error (int errcode, char * cmdname, value arg) Noreturn; +#endif + +#include + +#include "options.h" + +extern value guestfs_int_mllib_inspect_decrypt (value gv, value gpv); +extern value guestfs_int_mllib_set_echo_keys (value unitv); +extern value guestfs_int_mllib_set_keys_from_stdin (value unitv); + +/* Interface with the guestfish inspection and decryption code. */ +int echo_keys = 0; +int keys_from_stdin = 0; + +value +guestfs_int_mllib_inspect_decrypt (value gv, value gpv) +{ + CAMLparam2 (gv, gpv); + guestfs_h *g = (guestfs_h *) (intptr_t) Int64_val (gpv); + + inspect_do_decrypt (g); + + CAMLreturn (Val_unit); +} + +/* NB: This is a "noalloc" call. */ +value +guestfs_int_mllib_set_echo_keys (value unitv) +{ + echo_keys = 1; + return Val_unit; +} + +/* NB: This is a "noalloc" call. */ +value +guestfs_int_mllib_set_keys_from_stdin (value unitv) +{ + keys_from_stdin = 1; + return Val_unit; +} diff --git a/mllib/common_utils.ml b/mllib/common_utils.ml index 4e36d50..7cb8198 100644 --- a/mllib/common_utils.ml +++ b/mllib/common_utils.ml @@ -21,6 +21,10 @@ open Printf open Common_gettext.Gettext open Getopt.OptionName +external c_inspect_decrypt : Guestfs.t -> int64 -> unit = "guestfs_int_mllib_inspect_decrypt" +external c_set_echo_keys : unit -> unit = "guestfs_int_mllib_set_echo_keys" "noalloc" +external c_set_keys_from_stdin : unit -> unit = "guestfs_int_mllib_set_keys_from_stdin" "noalloc" + module Char = struct include Char @@ -591,7 +595,7 @@ let human_size i = ) ) -let create_standard_options argspec ?anon_fun usage_msg = +let create_standard_options argspec ?anon_fun ?(key_opts = false) usage_msg = (** Install an exit hook to check gc consistency for --debug-gc *) let set_debug_gc () = at_exit (fun () -> Gc.compact()) in @@ -604,6 +608,14 @@ let create_standard_options argspec ?anon_fun usage_msg = [ L"color"; L"colors"; L"colour"; L"colours" ], Getopt.Unit set_colours, s_"Use ANSI colour sequences even if not tty"; ] @ argspec in + let argspec = +argspec @ + (if key_opts then + [ +[ L"echo-keys" ], Getopt.Unit c_set_echo_keys, s_"Don't turn off echo for passphrases"; +[ L"keys-from-stdin" ], Getopt.Unit c_set_keys_from_stdin, s_"Read passphrases from stdin"; + ] + else []) in Getopt.create argspec ?anon_fun usage_msg (* Compare two version strings intelligently. *) @@ -998,3 +1010,11 @@ let is_btrfs_subvolume g fs = with Guestfs.Error msg as exn -> if g#last_errno () = Guestfs.Errno.errno_EINVAL then false else raise exn + +let inspect_decrypt g = + (* Note we pass original 'g' even though it is not used by the + * callee. This is so that 'g' is kept as a root on the stack, and + * so cannot be garbage collected while we are in the
[Libguestfs] [PATCH 3/3] OCaml tools: add crypto support (RHBZ#1362649)
Make use of the additional command line arguments, and API needed to decrypt LUKS partitions. This affects only virt-customize, virt-get-kernel, virt-sparsify, and virt-sysprep, as they are the main OCaml tools interacting with user-provided images. --- customize/customize_main.ml| 5 - customize/virt-customize.pod | 12 get-kernel/get_kernel.ml | 5 - get-kernel/virt-get-kernel.pod | 12 sparsify/cmdline.ml| 2 +- sparsify/copying.ml| 3 +++ sparsify/in_place.ml | 3 +++ sparsify/virt-sparsify.pod | 12 sysprep/main.ml| 5 - sysprep/virt-sysprep.pod | 12 10 files changed, 67 insertions(+), 4 deletions(-) diff --git a/customize/customize_main.ml b/customize/customize_main.ml index 07fd790..5613277 100644 --- a/customize/customize_main.ml +++ b/customize/customize_main.ml @@ -102,7 +102,7 @@ A short summary of the options is given below. For detailed help please read the man page virt-customize(1). ") prog in - let opthandle = create_standard_options argspec usage_msg in + let opthandle = create_standard_options argspec ~key_opts:true usage_msg in Getopt.parse opthandle; if not !format_consumed then @@ -175,6 +175,9 @@ read the man page virt-customize(1). g#launch (); g in + (* Decrypt the disks. *) + inspect_decrypt g; + (* Inspection. *) (match Array.to_list (g#inspect_os ()) with | [] -> diff --git a/customize/virt-customize.pod b/customize/virt-customize.pod index e594f61..a0ca9c9 100644 --- a/customize/virt-customize.pod +++ b/customize/virt-customize.pod @@ -107,6 +107,13 @@ used instead of names. Perform a read-only "dry run" on the guest. This runs the sysprep operation, but throws away any changes to the disk at the end. +=item B<--echo-keys> + +When prompting for keys and passphrases, virt-customize normally turns +echoing off so you cannot see what you are typing. If you are not +worried about Tempest attacks and there is no one else in the room +you can specify this flag to see what you are typing. + =item B<--format> raw|qcow2|.. =item B<--format> auto @@ -131,6 +138,11 @@ If you have untrusted raw-format guest disk images, you should use this option to specify the disk format. This avoids a possible security problem with malicious guests (CVE-2010-3851). +=item B<--keys-from-stdin> + +Read key or passphrase parameters from stdin. The default is +to try to read passphrases from the user by opening F. + =item B<-m> MB =item B<--memsize> MB diff --git a/get-kernel/get_kernel.ml b/get-kernel/get_kernel.ml index f83a940..adf9649 100644 --- a/get-kernel/get_kernel.ml +++ b/get-kernel/get_kernel.ml @@ -70,7 +70,7 @@ A short summary of the options is given below. For detailed help please read the man page virt-get-kernel(1). ") prog in - let opthandle = create_standard_options argspec usage_msg in + let opthandle = create_standard_options argspec ~key_opts:true usage_msg in Getopt.parse opthandle; (* Machine-readable mode? Print out some facts about what @@ -174,6 +174,9 @@ let main () = add g; g#launch (); + (* Decrypt the disks. *) + inspect_decrypt g; + let roots = g#inspect_os () in if Array.length roots = 0 then error (f_"no operating system found"); diff --git a/get-kernel/virt-get-kernel.pod b/get-kernel/virt-get-kernel.pod index 97a159c..8298fe5 100644 --- a/get-kernel/virt-get-kernel.pod +++ b/get-kernel/virt-get-kernel.pod @@ -70,6 +70,13 @@ not used at all. Add all the disks from the named libvirt guest. Domain UUIDs can be used instead of names. +=item B<--echo-keys> + +When prompting for keys and passphrases, virt-get-kernel normally turns +echoing off so you cannot see what you are typing. If you are not +worried about Tempest attacks and there is no one else in the room +you can specify this flag to see what you are typing. + =item B<--format> raw|qcow2|.. =item B<--format> auto @@ -82,6 +89,11 @@ If you have untrusted raw-format guest disk images, you should use this option to specify the disk format. This avoids a possible security problem with malicious guests (CVE-2010-3851). +=item B<--keys-from-stdin> + +Read key or passphrase parameters from stdin. The default is +to try to read passphrases from the user by opening F. + =item B<--machine-readable> This option is used to make the output more machine friendly diff --git a/sparsify/cmdline.ml b/sparsify/cmdline.ml index 523d612..2a9dd48 100644 --- a/sparsify/cmdline.ml +++ b/sparsify/cmdline.ml @@ -90,7 +90,7 @@ A short summary of the options is given below. For detailed help please read the man page virt-sparsify(1). ") prog in - let opthandle = create_standard_options argspec ~anon_fun usage_msg in + let opthandle = create_standard_options argspec ~anon_fun ~key_opts:true usage_msg in Getopt.parse opthandle; (* Dereference the rest of the
[Libguestfs] [PATCH 0/3] add crypto/LUKS support in some OCaml-based tools
Hi, this series refactors some guestfish code (not much), and exposes it via Common_utils, so it is possible to decrypt LUKS partitions when using virt-customize, virt-get-kernel, virt-sparsify, and virt-sysprep. This brings them closer in features with C tools. Most probably a couple more of other OCaml-based tools (virt-v2v to convert encrypted guests, and virt-builder to use encrypted templates), but that is left for implementation at a later time. Thanks, Pino Toscano (3): fish: move disk decryption helpers in own file mllib: expose disk decrypt functionalities OCaml tools: add crypto support (RHBZ#1362649) align/Makefile.am | 1 + cat/Makefile.am| 1 + customize/customize_main.ml| 5 +- customize/virt-customize.pod | 12 + df/Makefile.am | 1 + diff/Makefile.am | 1 + edit/Makefile.am | 1 + fish/Makefile.am | 1 + fish/decrypt.c | 102 + fish/inspect.c | 68 --- fish/options.h | 4 +- format/Makefile.am | 1 + fuse/Makefile.am | 1 + get-kernel/get_kernel.ml | 5 +- get-kernel/virt-get-kernel.pod | 12 + inspector/Makefile.am | 1 + mllib/Makefile.am | 3 ++ mllib/common_utils-c.c | 75 ++ mllib/common_utils.ml | 22 - mllib/common_utils.mli | 10 +++- rescue/Makefile.am | 1 + sparsify/cmdline.ml| 2 +- sparsify/copying.ml| 3 ++ sparsify/in_place.ml | 3 ++ sparsify/virt-sparsify.pod | 12 + sysprep/main.ml| 5 +- sysprep/virt-sysprep.pod | 12 + 27 files changed, 290 insertions(+), 75 deletions(-) create mode 100644 fish/decrypt.c create mode 100644 mllib/common_utils-c.c -- 2.7.4 ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
[Libguestfs] [PATCH 1/3] fish: move disk decryption helpers in own file
This way it is easier to use them outside the rest of the code in guestfish for inspection & mount. Just code motion, no behaviour changes. --- align/Makefile.am | 1 + cat/Makefile.am | 1 + df/Makefile.am| 1 + diff/Makefile.am | 1 + edit/Makefile.am | 1 + fish/Makefile.am | 1 + fish/decrypt.c| 102 ++ fish/inspect.c| 68 - fish/options.h| 4 +- format/Makefile.am| 1 + fuse/Makefile.am | 1 + inspector/Makefile.am | 1 + rescue/Makefile.am| 1 + 13 files changed, 115 insertions(+), 69 deletions(-) create mode 100644 fish/decrypt.c diff --git a/align/Makefile.am b/align/Makefile.am index 1eccf28..eb44263 100644 --- a/align/Makefile.am +++ b/align/Makefile.am @@ -33,6 +33,7 @@ SHARED_SOURCE_FILES = \ ../df/parallel.c \ ../df/parallel.h \ ../fish/config.c \ + ../fish/decrypt.c \ ../fish/display-options.h \ ../fish/display-options.c \ ../fish/domain.c \ diff --git a/cat/Makefile.am b/cat/Makefile.am index 38faa94..5e55742 100644 --- a/cat/Makefile.am +++ b/cat/Makefile.am @@ -31,6 +31,7 @@ EXTRA_DIST = \ bin_PROGRAMS = virt-cat virt-filesystems virt-log virt-ls SHARED_SOURCE_FILES = \ + ../fish/decrypt.c \ ../fish/display-options.h \ ../fish/display-options.c \ ../fish/domain.c \ diff --git a/df/Makefile.am b/df/Makefile.am index ce1686a..6efc1dc 100644 --- a/df/Makefile.am +++ b/df/Makefile.am @@ -28,6 +28,7 @@ bin_PROGRAMS = virt-df SHARED_SOURCE_FILES = \ ../fish/config.c \ + ../fish/decrypt.c \ ../fish/display-options.h \ ../fish/display-options.c \ ../fish/domain.c \ diff --git a/diff/Makefile.am b/diff/Makefile.am index cdbe05c..7dfe2cd 100644 --- a/diff/Makefile.am +++ b/diff/Makefile.am @@ -27,6 +27,7 @@ bin_PROGRAMS = virt-diff SHARED_SOURCE_FILES = \ ../cat/visit.h \ ../cat/visit.c \ + ../fish/decrypt.c \ ../fish/display-options.h \ ../fish/display-options.c \ ../fish/domain.c \ diff --git a/edit/Makefile.am b/edit/Makefile.am index 4ac4f08..dc9fbb0 100644 --- a/edit/Makefile.am +++ b/edit/Makefile.am @@ -26,6 +26,7 @@ bin_PROGRAMS = virt-edit SHARED_SOURCE_FILES = \ ../fish/config.c \ + ../fish/decrypt.c \ ../fish/display-options.h \ ../fish/display-options.c \ ../fish/domain.c \ diff --git a/fish/Makefile.am b/fish/Makefile.am index e1bc210..8fdcd27 100644 --- a/fish/Makefile.am +++ b/fish/Makefile.am @@ -73,6 +73,7 @@ EXTRA_DIST = \ # files must not include other guestfish files. SHARED_SOURCE_FILES = \ config.c \ + decrypt.c \ display-options.h \ display-options.c \ domain.c \ diff --git a/fish/decrypt.c b/fish/decrypt.c new file mode 100644 index 000..d6e041d --- /dev/null +++ b/fish/decrypt.c @@ -0,0 +1,102 @@ +/* libguestfs - shared disk decryption + * Copyright (C) 2010 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/** + * This file implements the decryption of disk images, usually done + * before mounting their partitions. + */ + +#include + +#include +#include +#include + +#include "c-ctype.h" + +#include "guestfs.h" + +#include "options.h" + +/** + * Make a LUKS map name from the partition name, + * eg. C<"/dev/vda2" =E "luksvda2"> + */ +static void +make_mapname (const char *device, char *mapname, size_t len) +{ + size_t i = 0; + + if (len < 5) +abort (); + strcpy (mapname, "luks"); + mapname += 4; + len -= 4; + + if (STRPREFIX (device, "/dev/")) +i = 5; + + for (; device[i] != '\0' && len >= 1; ++i) { +if (c_isalnum (device[i])) { + *mapname++ = device[i]; + len--; +} + } + + *mapname = '\0'; +} + +/** + * Simple implementation of decryption: look for any C + * partitions and decrypt them, then rescan for VGs. This only works + * for Fedora whole-disk encryption. WIP to make this work for other + * encryption schemes. + */ +void +inspect_do_decrypt (guestfs_h *g) +{ + CLEANUP_FREE_STRING_LIST char **partitions = guestfs_list_partitions (g); + if (partitions == NULL) +exit (EXIT_FAILURE); + + int need_rescan
[Libguestfs] [PATCH v7 1/4] lib: logic refactoring
Code changes in preparation for new APIs. Signed-off-by: Matteo Cafasso--- src/tsk.c | 39 +-- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/src/tsk.c b/src/tsk.c index 90177ab..ecafcb7 100644 --- a/src/tsk.c +++ b/src/tsk.c @@ -34,44 +34,43 @@ #include "guestfs-internal-all.h" #include "guestfs-internal-actions.h" -static struct guestfs_tsk_dirent_list *parse_filesystem_walk (guestfs_h *, FILE *); +static struct guestfs_tsk_dirent_list *parse_dirent_file (guestfs_h *, const char *); static int deserialise_dirent_list (guestfs_h *, FILE *, struct guestfs_tsk_dirent_list *); +static char *make_temp_file (guestfs_h *, const char *); struct guestfs_tsk_dirent_list * guestfs_impl_filesystem_walk (guestfs_h *g, const char *mountable) { int ret = 0; - CLEANUP_FCLOSE FILE *fp = NULL; CLEANUP_UNLINK_FREE char *tmpfile = NULL; - ret = guestfs_int_lazy_make_tmpdir (g); - if (ret < 0) + tmpfile = make_temp_file (g, "filesystem_walk"); + if (tmpfile == NULL) return NULL; - tmpfile = safe_asprintf (g, "%s/filesystem_walk%d", g->tmpdir, ++g->unique); - ret = guestfs_internal_filesystem_walk (g, mountable, tmpfile); if (ret < 0) return NULL; - fp = fopen (tmpfile, "r"); - if (fp == NULL) { -perrorf (g, "fopen: %s", tmpfile); -return NULL; - } - - return parse_filesystem_walk (g, fp); /* caller frees */ + return parse_dirent_file (g, tmpfile); /* caller frees */ } /* Parse the file content and return dirents list. * Return a list of tsk_dirent on success, NULL on error. */ static struct guestfs_tsk_dirent_list * -parse_filesystem_walk (guestfs_h *g, FILE *fp) +parse_dirent_file (guestfs_h *g, const char *tmpfile) { int ret = 0; + CLEANUP_FCLOSE FILE *fp = NULL; struct guestfs_tsk_dirent_list *dirents = NULL; + fp = fopen (tmpfile, "r"); + if (fp == NULL) { +perrorf (g, "fopen: %s", tmpfile); +return NULL; + } + /* Initialise results array. */ dirents = safe_malloc (g, sizeof (*dirents)); dirents->len = 8; @@ -126,3 +125,15 @@ deserialise_dirent_list (guestfs_h *g, FILE *fp, return ret ? 0 : -1; } + +static char * +make_temp_file (guestfs_h *g, const char *name) +{ + int ret = 0; + + ret = guestfs_int_lazy_make_tmpdir (g); + if (ret < 0) +return NULL; + + return safe_asprintf (g, "%s/%s%d", g->tmpdir, name, ++g->unique); +} -- 2.9.3 ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
[Libguestfs] [PATCH v7 2/4] New API: internal_find_inode
The internal_find_inode command searches all entries referring to the given inode and returns a tsk_dirent structure for each of them. The command is able to retrieve information regarding deleted or unaccessible files where other commands such as stat or find would fail. The gathered list of tsk_dirent structs is serialised into XDR format and written to a file by the appliance. Signed-off-by: Matteo Cafasso--- daemon/tsk.c | 52 generator/actions.ml | 9 + src/MAX_PROC_NR | 2 +- 3 files changed, 62 insertions(+), 1 deletion(-) diff --git a/daemon/tsk.c b/daemon/tsk.c index e5669da..af803d7 100644 --- a/daemon/tsk.c +++ b/daemon/tsk.c @@ -44,6 +44,7 @@ enum tsk_dirent_flags { static int open_filesystem (const char *, TSK_IMG_INFO **, TSK_FS_INFO **); static TSK_WALK_RET_ENUM fswalk_callback (TSK_FS_FILE *, const char *, void *); +static TSK_WALK_RET_ENUM findino_callback (TSK_FS_FILE *, const char *, void *); static int send_dirent_info (TSK_FS_FILE *, const char *); static char file_type (TSK_FS_FILE *); static int file_flags (TSK_FS_FILE *fsfile); @@ -79,6 +80,35 @@ do_internal_filesystem_walk (const mountable_t *mountable) return ret; } +int +do_internal_find_inode (const mountable_t *mountable, int64_t inode) +{ + int ret = -1; + TSK_FS_INFO *fs = NULL; + TSK_IMG_INFO *img = NULL; /* Used internally by tsk_fs_dir_walk */ + const int flags = +TSK_FS_DIR_WALK_FLAG_ALLOC | TSK_FS_DIR_WALK_FLAG_UNALLOC | +TSK_FS_DIR_WALK_FLAG_RECURSE | TSK_FS_DIR_WALK_FLAG_NOORPHAN; + + ret = open_filesystem (mountable->device, , ); + if (ret < 0) +return ret; + + reply (NULL, NULL); /* Reply message. */ + + ret = tsk_fs_dir_walk (fs, fs->root_inum, flags, + findino_callback, (void *) ); + if (ret == 0) +ret = send_file_end (0); /* File transfer end. */ + else +send_file_end (1); /* Cancel file transfer. */ + + fs->close (fs); + img->close (img); + + return ret; +} + /* Inspect the device and initialises the img and fs structures. * Return 0 on success, -1 on error. */ @@ -120,6 +150,28 @@ fswalk_callback (TSK_FS_FILE *fsfile, const char *path, void *data) return (ret == 0) ? TSK_WALK_CONT : TSK_WALK_ERROR; } +/* Find inode, it gets called on every FS node. + * If the FS node address is the given one, parse it, + * encode it into an XDR structure and send it to the library. + * Return TSK_WALK_CONT on success, TSK_WALK_ERROR on error. + */ +static TSK_WALK_RET_ENUM +findino_callback (TSK_FS_FILE *fsfile, const char *path, void *data) +{ + int ret = 0; + uint64_t *inode = (uint64_t *) data; + + if (*inode != fsfile->name->meta_addr) +return TSK_WALK_CONT; + + if (entry_is_dot (fsfile)) +return TSK_WALK_CONT; + + ret = send_dirent_info (fsfile, path); + + return (ret == 0) ? TSK_WALK_CONT : TSK_WALK_ERROR; +} + /* Extract the information from the entry, serialize and send it out. * Return 0 on success, -1 on error. */ diff --git a/generator/actions.ml b/generator/actions.ml index 68ecee3..4e6627b 100644 --- a/generator/actions.ml +++ b/generator/actions.ml @@ -13232,6 +13232,15 @@ handle C. If C is true (C by default), then the transformation is removed." }; + { defaults with +name = "internal_find_inode"; added = (1, 35, 6); +style = RErr, [Mountable "device"; Int64 "inode"; FileOut "filename";], []; +proc_nr = Some 470; +visibility = VInternal; +optional = Some "libtsk"; +shortdesc = "search the entries associated to the given inode"; +longdesc = "Internal function for find_inode." }; + ] (* Non-API meta-commands available only in guestfish. diff --git a/src/MAX_PROC_NR b/src/MAX_PROC_NR index 5ef9d24..5f476b6 100644 --- a/src/MAX_PROC_NR +++ b/src/MAX_PROC_NR @@ -1 +1 @@ -469 +470 -- 2.9.3 ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
[Libguestfs] [PATCH v7 4/4] find_inode: added API tests
NTFS file system always has the MFT file at inode 0. This reliable information helps testing the API. Signed-off-by: Matteo Cafasso--- tests/tsk/Makefile.am| 3 +- tests/tsk/test-find-inode.sh | 66 2 files changed, 68 insertions(+), 1 deletion(-) create mode 100755 tests/tsk/test-find-inode.sh diff --git a/tests/tsk/Makefile.am b/tests/tsk/Makefile.am index 0b50839..07c74f9 100644 --- a/tests/tsk/Makefile.am +++ b/tests/tsk/Makefile.am @@ -20,7 +20,8 @@ include $(top_srcdir)/subdir-rules.mk TESTS = \ test-download-inode.sh \ test-download-blocks.sh \ - test-filesystem-walk.sh + test-filesystem-walk.sh \ + test-find-inode.sh TESTS_ENVIRONMENT = $(top_builddir)/run --test diff --git a/tests/tsk/test-find-inode.sh b/tests/tsk/test-find-inode.sh new file mode 100755 index 000..f69fcf6 --- /dev/null +++ b/tests/tsk/test-find-inode.sh @@ -0,0 +1,66 @@ +#!/bin/bash - +# libguestfs +# Copyright (C) 2016 Red Hat Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +# Test the find-inode command. + +if [ -n "$SKIP_TEST_FIND_INODE_SH" ]; then +echo "$0: test skipped because environment variable is set." +exit 77 +fi + +# Skip if TSK is not supported by the appliance. +if ! guestfish add /dev/null : run : available "libtsk"; then +echo "$0: skipped because TSK is not available in the appliance" +exit 77 +fi + +if [ ! -s ../../test-data/phony-guests/windows.img ]; then +echo "$0: skipped because windows.img is zero-sized" +exit 77 +fi + +output=$( +guestfish --ro -a ../../test-data/phony-guests/windows.img
[Libguestfs] [PATCH v7 3/4] New API: find_inode
Library's counterpart of the daemon's internal_find_inode command. It writes the daemon's command output on a temporary file and parses it, deserialising the XDR formatted tsk_dirent structs. It returns to the caller the list of tsk_dirent structs generated by the internal_find_inode command. Signed-off-by: Matteo Cafasso--- generator/actions.ml | 12 src/tsk.c| 17 + 2 files changed, 29 insertions(+) diff --git a/generator/actions.ml b/generator/actions.ml index 4e6627b..91a1819 100644 --- a/generator/actions.ml +++ b/generator/actions.ml @@ -3717,6 +3717,18 @@ Unknown file type =back" }; + { defaults with +name = "find_inode"; added = (1, 35, 6); +style = RStructList ("dirents", "tsk_dirent"), [Mountable "device"; Int64 "inode";], []; +optional = Some "libtsk"; +progress = true; cancellable = true; +shortdesc = "search the entries associated to the given inode"; +longdesc = "\ +Searches all the entries associated with the given inode. + +For each entry, a C structure is returned. +See C for more information about C structures." }; + ] (* daemon_functions are any functions which cause some action diff --git a/src/tsk.c b/src/tsk.c index ecafcb7..1def9c9 100644 --- a/src/tsk.c +++ b/src/tsk.c @@ -55,6 +55,23 @@ guestfs_impl_filesystem_walk (guestfs_h *g, const char *mountable) return parse_dirent_file (g, tmpfile); /* caller frees */ } +struct guestfs_tsk_dirent_list * +guestfs_impl_find_inode (guestfs_h *g, const char *mountable, int64_t inode) +{ + int ret = 0; + CLEANUP_UNLINK_FREE char *tmpfile = NULL; + + tmpfile = make_temp_file (g, "find_inode"); + if (tmpfile == NULL) +return NULL; + + ret = guestfs_internal_find_inode (g, mountable, inode, tmpfile); + if (ret < 0) +return NULL; + + return parse_dirent_file (g, tmpfile); /* caller frees */ +} + /* Parse the file content and return dirents list. * Return a list of tsk_dirent on success, NULL on error. */ -- 2.9.3 ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
[Libguestfs] [PATCH v7 0/4] New API - find_inode
v7: - Merge src/tsk.c refactoring patch with #4 of find_block series Matteo Cafasso (4): lib: logic refactoring New API: internal_find_inode New API: find_inode find_inode: added API tests daemon/tsk.c | 52 ++ generator/actions.ml | 21 ++ src/MAX_PROC_NR | 2 +- src/tsk.c| 52 ++ tests/tsk/Makefile.am| 3 +- tests/tsk/test-find-inode.sh | 66 6 files changed, 182 insertions(+), 14 deletions(-) create mode 100755 tests/tsk/test-find-inode.sh -- 2.9.3 ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
Re: [Libguestfs] [PATCH 0/4] New API - find_block
On Saturday, 17 September 2016 18:18:52 CEST Matteo Cafasso wrote: > This series is ready for review but requires the previous one to be merged > first: > https://www.redhat.com/archives/libguestfs/2016-September/msg00101.html > > The find_block API allows the User to search all the filesystem entries > referring to a given data block and returns a tsk_dirent structure > for each of them. > > Use case examples: > > - Check whether a block containing a deleted file has been re-used to store > a new one. > - Map a certain area of a disk with the contained files. > > Matteo Cafasso (4): > New API: internal_find_block > New API: find_block > find_block: added API tests > TSK: small refactoring Minus the small note in patch #1, patches #1-#3 LGTM. Thanks, -- Pino Toscano signature.asc Description: This is a digitally signed message part. ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
Re: [Libguestfs] [PATCH 4/4] TSK: small refactoring
On Saturday, 17 September 2016 18:18:56 CEST Matteo Cafasso wrote: > Removed duplicated code. > > Signed-off-by: Matteo Cafasso> --- As mentioned in another email, I'd like this to be a single change with the return parse_filesystem_walk -> parse_dirent_file rename. > struct guestfs_tsk_dirent_list * > guestfs_impl_filesystem_walk (guestfs_h *g, const char *mountable) > { >int ret = 0; > - CLEANUP_FCLOSE FILE *fp = NULL; >CLEANUP_UNLINK_FREE char *tmpfile = NULL; > > - ret = guestfs_int_lazy_make_tmpdir (g); > - if (ret < 0) > -return NULL; > - > - tmpfile = safe_asprintf (g, "%s/filesystem_walk%d", g->tmpdir, > ++g->unique); > + tmpfile = make_temp_file (g, "filesystem_walk"); Note you are not checking the return value of make_temp_file, which can still fail (when guestfs_int_lazy_make_tmpdir fails, for example). So you still need to check tmpfile, otherwise tmpfile may be used as null pointer. Thanks, -- Pino Toscano signature.asc Description: This is a digitally signed message part. ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
Re: [Libguestfs] [PATCH 1/4] New API: internal_find_block
On Saturday, 17 September 2016 18:18:53 CEST Matteo Cafasso wrote: > The internal_find_block command searches all entries referring to the > given filesystem data block and returns a tsk_dirent structure > for each of them. > > For filesystems such as NTFS which do not delete the block mapping > when removing files, it is possible to get multiple non-allocated > entries for the same block. > > The gathered list of tsk_dirent structs is serialised into XDR format > and written to a file by the appliance. > > Signed-off-by: Matteo Cafasso> --- LGTM, just one small note below. > +typedef struct { > + int found; This can be a simple bool (including to use it). > + uint64_t block; > +} findblk_data; Thanks, -- Pino Toscano signature.asc Description: This is a digitally signed message part. ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs
Re: [Libguestfs] [PATCH v6 0/6] New API - find_inode
On Saturday, 17 September 2016 00:04:22 CEST Matteo Cafasso wrote: > This series should be ready for merge > > v6: > > - rebase on master > > - changes according to last comments The series looks much better now -- thanks. I just pushed patches #1 and #2, as they are fine. Regarding patch #3, IMHO you could merge in it the work done in patch #4 of the other find_block series [1], as both are simple refactoring works. [1] https://www.redhat.com/archives/libguestfs/2016-September/msg00108.html Thanks, -- Pino Toscano signature.asc Description: This is a digitally signed message part. ___ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs