[Libguestfs] [PATCH v2 3/3] find_block: added API tests

2016-09-19 Thread Matteo Cafasso
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

2016-09-19 Thread Matteo Cafasso
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

2016-09-19 Thread Matteo Cafasso
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

2016-09-19 Thread Matteo Cafasso
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

2016-09-19 Thread Pino Toscano
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)

2016-09-19 Thread Richard W.M. Jones
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

2016-09-19 Thread Richard W.M. Jones
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

2016-09-19 Thread Richard W.M. Jones
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

2016-09-19 Thread Pino Toscano
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)

2016-09-19 Thread Pino Toscano
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

2016-09-19 Thread Pino Toscano
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

2016-09-19 Thread Pino Toscano
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

2016-09-19 Thread Matteo Cafasso
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

2016-09-19 Thread Matteo Cafasso
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

2016-09-19 Thread Matteo Cafasso
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

2016-09-19 Thread Matteo Cafasso
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

2016-09-19 Thread Matteo Cafasso
 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

2016-09-19 Thread Pino Toscano
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

2016-09-19 Thread Pino Toscano
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

2016-09-19 Thread Pino Toscano
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

2016-09-19 Thread Pino Toscano
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