New API: Deprecate hivex_value_utf8 and replace with hivex_value_string.

hivex has a function hivex_value_string.  We were not calling it under
the mistaken belief that because hivex implements this using iconv,
the function wouldn't work inside the daemon.  Instead we
reimplemented the functionality in the library.

This commit deprecates hivex_value_utf8 and removes the library side
code.  It replaces it with a plain wrapper around hivex_value_string.

Thanks: Pino Toscano
This commit is contained in:
Richard W.M. Jones
2017-08-09 15:53:23 +01:00
parent 11b8a5db19
commit 19940fc2bd
16 changed files with 124 additions and 149 deletions

View File

@@ -335,6 +335,29 @@ do_hivex_value_value (int64_t valueh, size_t *size_r)
return r;
}
char *
do_hivex_value_string (int64_t valueh)
{
char *r;
NEED_HANDLE (NULL);
r = hivex_value_string (h, valueh);
if (r == NULL) {
reply_with_perror ("failed");
return NULL;
}
return r;
}
/* Deprecated alias for hivex_value_string. */
char *
do_hivex_value_utf8 (int64_t valueh)
{
return do_hivex_value_string (valueh);
}
int
do_hivex_commit (const char *filename)
{

View File

@@ -310,7 +310,6 @@ lib/guestfs-internal.h
lib/guestfs.h
lib/guid.c
lib/handle.c
lib/hivex.c
lib/info.c
lib/inspect-apps.c
lib/inspect-fs-unix.c

View File

@@ -266,7 +266,7 @@ print_dhcp_address_windows (guestfs_h *g, char *root_fs)
/* Get the string and use libguestfs's auto-conversion to convert it
* to UTF-8 for output.
*/
p = guestfs_hivex_value_utf8 (g, value);
p = guestfs_hivex_value_string (g, value);
if (!p)
exit (EXIT_FAILURE);

View File

@@ -31,6 +31,8 @@ sources = \
actions_debug.mli \
actions_hivex.ml \
actions_hivex.mli \
actions_hivex_deprecated.ml \
actions_hivex_deprecated.mli \
actions_inspection.ml \
actions_inspection.mli \
actions_inspection_deprecated.ml \
@@ -122,6 +124,7 @@ objects = \
actions_core_deprecated.cmo \
actions_debug.cmo \
actions_hivex.cmo \
actions_hivex_deprecated.cmo \
actions_inspection.cmo \
actions_inspection_deprecated.cmo \
actions_internal_tests.cmo \

View File

@@ -33,7 +33,6 @@ let non_daemon_functions =
Actions_core.non_daemon_functions @
Actions_core_deprecated.non_daemon_functions @
Actions_debug.non_daemon_functions @
Actions_hivex.non_daemon_functions @
Actions_inspection.non_daemon_functions @
Actions_inspection_deprecated.non_daemon_functions @
Actions_properties.non_daemon_functions @
@@ -51,6 +50,7 @@ let daemon_functions =
Actions_core_deprecated.daemon_functions @
Actions_debug.daemon_functions @
Actions_hivex.daemon_functions @
Actions_hivex_deprecated.daemon_functions @
Actions_tsk.daemon_functions @
Actions_yara.daemon_functions

View File

@@ -22,25 +22,6 @@ open Types
(* Hivex APIs. *)
let non_daemon_functions = [
{ defaults with
name = "hivex_value_utf8"; added = (1, 19, 35);
style = RString (RPlainString, "databuf"), [Int64 "valueh"], [];
optional = Some "hivex";
shortdesc = "return the data field from the (key, datatype, data) tuple";
longdesc = "\
This calls C<guestfs_hivex_value_value> (which returns the
data field from a hivex value tuple). It then assumes that
the field is a UTF-16LE string and converts the result to
UTF-8 (or if this is not possible, it returns an error).
This is useful for reading strings out of the Windows registry.
However it is not foolproof because the registry is not
strongly-typed and fields can contain arbitrary or unexpected
data." };
]
let daemon_functions = [
{ defaults with
name = "hivex_open"; added = (1, 19, 35);
@@ -178,6 +159,22 @@ This is a wrapper around the L<hivex(3)> call of the same name.
See also: C<guestfs_hivex_value_utf8>." };
{ defaults with
name = "hivex_value_string"; added = (1, 37, 22);
style = RString (RPlainString, "databuf"), [Int64 "valueh"], [];
optional = Some "hivex";
shortdesc = "return the data field as a UTF-8 string";
longdesc = "\
This calls C<guestfs_hivex_value_value> (which returns the
data field from a hivex value tuple). It then assumes that
the field is a UTF-16LE string and converts the result to
UTF-8 (or if this is not possible, it returns an error).
This is useful for reading strings out of the Windows registry.
However it is not foolproof because the registry is not
strongly-typed and fields can contain arbitrary or unexpected
data." };
{ defaults with
name = "hivex_commit"; added = (1, 19, 35);
style = RErr, [OptString "filename"], [];

View File

@@ -18,5 +18,4 @@
(* Please read generator/README first. *)
val non_daemon_functions : Types.action list
val daemon_functions : Types.action list

View File

@@ -0,0 +1,43 @@
(* libguestfs
* Copyright (C) 2009-2017 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
*)
(* Please read generator/README first. *)
open Types
(* Deprecated hivex APIs. *)
let daemon_functions = [
{ defaults with
name = "hivex_value_utf8"; added = (1, 19, 35);
style = RString (RPlainString, "databuf"), [Int64 "valueh"], [];
optional = Some "hivex";
deprecated_by = Replaced_by "hivex_value_string";
shortdesc = "return the data field as a UTF-8 string";
longdesc = "\
This calls C<guestfs_hivex_value_value> (which returns the
data field from a hivex value tuple). It then assumes that
the field is a UTF-16LE string and converts the result to
UTF-8 (or if this is not possible, it returns an error).
This is useful for reading strings out of the Windows registry.
However it is not foolproof because the registry is not
strongly-typed and fields can contain arbitrary or unexpected
data." };
]

View File

@@ -0,0 +1,21 @@
(* libguestfs
* Copyright (C) 2009-2017 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
*)
(* Please read generator/README first. *)
val daemon_functions : Types.action list

View File

@@ -485,6 +485,8 @@ let proc_nr = [
475, "file_architecture";
476, "list_filesystems";
477, "part_resize";
478, "hivex_value_utf8";
479, "hivex_value_string";
]
(* End of list. If adding a new entry, add it at the end of the list

View File

@@ -1 +1 @@
477
479

View File

@@ -92,7 +92,6 @@ libguestfs_la_SOURCES = \
fuse.c \
guid.c \
handle.c \
hivex.c \
info.c \
inspect.c \
inspect-apps.c \

View File

@@ -1,111 +0,0 @@
/* libguestfs
* Copyright (C) 2010-2012 Red Hat Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <iconv.h>
#include "guestfs.h"
#include "guestfs-internal.h"
#include "guestfs-internal-actions.h"
/* Read the data from 'valueh', assume it is UTF16LE and convert it to
* UTF8. This is copied from hivex_value_string which doesn't work in
* the appliance because it uses iconv_open which doesn't work because
* we delete all the i18n databases.
*/
static char *utf16_to_utf8 (/* const */ char *input, size_t len);
char *
guestfs_impl_hivex_value_utf8 (guestfs_h *g, int64_t valueh)
{
char *ret;
size_t buflen;
CLEANUP_FREE char *buf = guestfs_hivex_value_value (g, valueh, &buflen);
if (buf == NULL)
return NULL;
ret = utf16_to_utf8 (buf, buflen);
if (ret == NULL) {
perrorf (g, "hivex: conversion of registry value to UTF8 failed");
return NULL;
}
return ret;
}
static char *
utf16_to_utf8 (/* const */ char *input, size_t len)
{
iconv_t ic = iconv_open ("UTF-8", "UTF-16LE");
if (ic == (iconv_t) -1)
return NULL;
/* iconv(3) has an insane interface ... */
/* Mostly UTF-8 will be smaller, so this is a good initial guess. */
size_t outalloc = len;
again:;
size_t inlen = len;
size_t outlen = outalloc;
char *out = malloc (outlen + 1);
if (out == NULL) {
int err = errno;
iconv_close (ic);
errno = err;
return NULL;
}
char *inp = input;
char *outp = out;
const size_t r =
iconv (ic, (ICONV_CONST char **) &inp, &inlen, &outp, &outlen);
if (r == (size_t) -1) {
if (errno == E2BIG) {
const int err = errno;
const size_t prev = outalloc;
/* Try again with a larger output buffer. */
free (out);
outalloc *= 2;
if (outalloc < prev) {
iconv_close (ic);
errno = err;
return NULL;
}
goto again;
}
else {
/* Else some conversion failure, eg. EILSEQ, EINVAL. */
const int err = errno;
iconv_close (ic);
free (out);
errno = err;
return NULL;
}
}
*outp = '\0';
iconv_close (ic);
return out;
}

View File

@@ -919,23 +919,23 @@ list_applications_windows_from_path (guestfs_h *g,
value = guestfs_hivex_node_get_value (g, child, "DisplayName");
if (value) {
display_name = guestfs_hivex_value_utf8 (g, value);
display_name = guestfs_hivex_value_string (g, value);
if (display_name) {
value = guestfs_hivex_node_get_value (g, child, "DisplayVersion");
if (value)
version = guestfs_hivex_value_utf8 (g, value);
version = guestfs_hivex_value_string (g, value);
value = guestfs_hivex_node_get_value (g, child, "InstallLocation");
if (value)
install_path = guestfs_hivex_value_utf8 (g, value);
install_path = guestfs_hivex_value_string (g, value);
value = guestfs_hivex_node_get_value (g, child, "Publisher");
if (value)
publisher = guestfs_hivex_value_utf8 (g, value);
publisher = guestfs_hivex_value_string (g, value);
value = guestfs_hivex_node_get_value (g, child, "URLInfoAbout");
if (value)
url = guestfs_hivex_value_utf8 (g, value);
url = guestfs_hivex_value_string (g, value);
value = guestfs_hivex_node_get_value (g, child, "Comments");
if (value)
comments = guestfs_hivex_value_utf8 (g, value);
comments = guestfs_hivex_value_string (g, value);
add_application (g, apps, name, display_name, 0,
version ? : "",

View File

@@ -355,7 +355,7 @@ check_windows_software_registry (guestfs_h *g, struct inspect_fs *fs)
goto out;
if (STRCASEEQ (key, "ProductName")) {
fs->product_name = guestfs_hivex_value_utf8 (g, value);
fs->product_name = guestfs_hivex_value_string (g, value);
if (!fs->product_name)
goto out;
}
@@ -396,7 +396,7 @@ check_windows_software_registry (guestfs_h *g, struct inspect_fs *fs)
ignore_currentversion = true;
}
else if (!ignore_currentversion && STRCASEEQ (key, "CurrentVersion")) {
CLEANUP_FREE char *version = guestfs_hivex_value_utf8 (g, value);
CLEANUP_FREE char *version = guestfs_hivex_value_string (g, value);
if (!version)
goto out;
if (guestfs_int_version_from_x_y_re (g, &fs->version, version,
@@ -404,7 +404,7 @@ check_windows_software_registry (guestfs_h *g, struct inspect_fs *fs)
goto out;
}
else if (STRCASEEQ (key, "InstallationType")) {
fs->product_variant = guestfs_hivex_value_utf8 (g, value);
fs->product_variant = guestfs_hivex_value_string (g, value);
if (!fs->product_variant)
goto out;
}
@@ -568,7 +568,7 @@ check_windows_system_registry (guestfs_h *g, struct inspect_fs *fs)
goto out;
if (STRCASEEQ (key, "Hostname")) {
fs->hostname = guestfs_hivex_value_utf8 (g, v);
fs->hostname = guestfs_hivex_value_string (g, v);
if (!fs->hostname)
goto out;
}

View File

@@ -145,7 +145,7 @@ let convert (g : G.guestfs) inspect source output rcaps =
if valueh = 0L then
raise Not_found;
let dispname = g#hivex_value_utf8 valueh in
let dispname = g#hivex_value_string valueh in
if not (Str.string_match (Str.regexp ".*\\(Parallels\\|Virtuozzo\\) Tools.*")
dispname 0) then
raise Not_found;
@@ -159,7 +159,7 @@ let convert (g : G.guestfs) inspect source output rcaps =
raise Not_found
);
let uninst = (g#hivex_value_utf8 valueh) ^
let uninst = (g#hivex_value_string valueh) ^
" /quiet /norestart /l*v+ \"%~dpn0.log\"" ^
" REBOOT=ReallySuppress REMOVE=ALL" ^
(* without these custom Parallels-specific MSI properties the
@@ -570,7 +570,7 @@ if errorlevel 3010 exit /b 0
match Registry.get_node reg path with
| None -> raise Not_found
| Some node -> node in
let current_boot_entry = g#hivex_value_utf8 (
let current_boot_entry = g#hivex_value_string (
g#hivex_node_get_value boot_mgr_default_link "Element") in
let path = ["Objects"; current_boot_entry; "Elements"; "16000046"] in
match Registry.get_node reg path with