[Openvas-commits] r5669 - in trunk/openvas-manager: . src
scm-commit@wald.intevation.org
scm-commit at wald.intevation.org
Thu Oct 22 00:34:15 CEST 2009
Author: mattm
Date: 2009-10-22 00:34:13 +0200 (Thu, 22 Oct 2009)
New Revision: 5669
Added:
trunk/openvas-manager/src/lsc_user.c
trunk/openvas-manager/src/lsc_user.h
Modified:
trunk/openvas-manager/ChangeLog
trunk/openvas-manager/src/CMakeLists.txt
trunk/openvas-manager/src/manage.h
trunk/openvas-manager/src/omp.c
trunk/openvas-manager/src/openvasmd.c
trunk/openvas-manager/src/tasks_sql.h
Log:
Add generation of LSC user keys and packages (RPM and Debian). Extend OMP
GET_LSC_CREDENTIALS for retrieving packages.
* src/lsc_user.c, src/lsc_user.h: New files. Key and package generation.
* src/CMakeLists.txt (manage): Add lsc_user.c.
* src/openvasmd.c (main): Enable SIGCHLD. Neaten some formatting.
(serve_client): Goto fail case if read_protocol failed completely.
(cleanup): Neaten some formatting.
* src/tasks_sql.h (DATABASE_VERSION): Increase to 3 for changes to
lsc_credentials table.
(init_manage): Add password column to table lsc_credentials, rename column
dog to exe, make the package columns of type text.
(clude): Change sqlite3_bind_text free function to SQLITE_TRANSIENT.
(create_lsc_credential): Create keys and packages.
(init_lsc_credential_iterator): New function.
(lsc_credential_iterator_password, lsc_credential_iterator_public_key)
(lsc_credential_iterator_private_key, lsc_credential_iterator_rpm)
(lsc_credential_iterator_deb, lsc_credential_iterator_exe): New functions.
(lsc_credential_iterator_comment): Update column number.
* src/manage.h: Update headers.
* src/omp.c (omp_xml_handle_start_element, omp_xml_handle_end_element):
Add name and format flags to GET_LSC_CREDENTIALS.
Modified: trunk/openvas-manager/ChangeLog
===================================================================
--- trunk/openvas-manager/ChangeLog 2009-10-21 18:58:55 UTC (rev 5668)
+++ trunk/openvas-manager/ChangeLog 2009-10-21 22:34:13 UTC (rev 5669)
@@ -1,3 +1,33 @@
+2009-10-22 Matthew Mundell <matthew.mundell at intevation.de>
+
+ Add generation of LSC user keys and packages (RPM and Debian). Extend OMP
+ GET_LSC_CREDENTIALS for retrieving packages.
+
+ * src/lsc_user.c, src/lsc_user.h: New files. Key and package generation.
+
+ * src/CMakeLists.txt (manage): Add lsc_user.c.
+
+ * src/openvasmd.c (main): Enable SIGCHLD. Neaten some formatting.
+ (serve_client): Goto fail case if read_protocol failed completely.
+ (cleanup): Neaten some formatting.
+
+ * src/tasks_sql.h (DATABASE_VERSION): Increase to 3 for changes to
+ lsc_credentials table.
+ (init_manage): Add password column to table lsc_credentials, rename column
+ dog to exe, make the package columns of type text.
+ (clude): Change sqlite3_bind_text free function to SQLITE_TRANSIENT.
+ (create_lsc_credential): Create keys and packages.
+ (init_lsc_credential_iterator): New function.
+ (lsc_credential_iterator_password, lsc_credential_iterator_public_key)
+ (lsc_credential_iterator_private_key, lsc_credential_iterator_rpm)
+ (lsc_credential_iterator_deb, lsc_credential_iterator_exe): New functions.
+ (lsc_credential_iterator_comment): Update column number.
+
+ * src/manage.h: Update headers.
+
+ * src/omp.c (omp_xml_handle_start_element, omp_xml_handle_end_element):
+ Add name and format flags to GET_LSC_CREDENTIALS.
+
2009-10-21 Jan-Oliver Wagner <jan-oliver.wagner at greenbone.net>
* src/openvasmd.c (cleanup, main): Factored out pidfile management.
Modified: trunk/openvas-manager/src/CMakeLists.txt
===================================================================
--- trunk/openvas-manager/src/CMakeLists.txt 2009-10-21 18:58:55 UTC (rev 5668)
+++ trunk/openvas-manager/src/CMakeLists.txt 2009-10-21 22:34:13 UTC (rev 5669)
@@ -68,7 +68,7 @@
add_library (ovas-mngr-comm ovas-mngr-comm.c)
set_target_properties (ovas-mngr-comm PROPERTIES COMPILE_FLAGS "${GLIB_CFLAGS}")
-add_library (manage manage.c)
+add_library (manage manage.c lsc_user.c)
set_target_properties (manage PROPERTIES COMPILE_FLAGS "${HEADER_TEMP} ${TASKS_CFLAG} ${OPENVAS_CFLAGS} ${GLIB_CFLAGS}")
add_library (omp omp.c)
Added: trunk/openvas-manager/src/lsc_user.c
===================================================================
--- trunk/openvas-manager/src/lsc_user.c 2009-10-21 18:58:55 UTC (rev 5668)
+++ trunk/openvas-manager/src/lsc_user.c 2009-10-21 22:34:13 UTC (rev 5669)
@@ -0,0 +1,999 @@
+/* OpenVAS Manager
+ * $Id$
+ * Description: LSC user credentials package generation.
+ *
+ * Authors:
+ * Matthew Mundell <matthew.mundell at intevation.de>
+ * Michael Wiegand <michael.wiegand at intevation.de>
+ * Felix Wolfsteller <felix.wolfsteller at intevation.de>
+ *
+ * Copyright:
+ * Copyright (C) 2009 Greenbone Networks GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * or, at your option, any later version as published by the Free
+ * Software Foundation
+ *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <glib/gstdio.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <openvas/openvas_ssh_login.h>
+#include <openvas/system.h>
+
+#undef G_LOG_DOMAIN
+/**
+ * @brief GLib log domain.
+ */
+#define G_LOG_DOMAIN "md manage"
+
+
+// FIX Munge helpers.
+
+#define show_error g_debug
+#define _(string) string
+
+/** @todo Copied check_is_file and check_is_dir from administrator. */
+
+/**
+ * @brief Checks whether a file is a directory or not.
+ *
+ * This is a replacement for the g_file_test functionality which is reported
+ * to be unreliable under certain circumstances, for example if this
+ * application and glib are compiled with a different libc.
+ *
+ * @todo FIXME: handle symbolic links
+ * @todo Move to libs?
+ *
+ * @return 1 if parameter is directory, 0 if it is not, -1 if it does not
+ * exist or could not be accessed.
+ */
+static int
+check_is_file (const char* name)
+{
+ struct stat sb;
+
+ if (stat (name, &sb))
+ {
+ return -1;
+ }
+ else
+ {
+ return (S_ISREG (sb.st_mode));
+ }
+}
+
+/**
+ * @brief Checks whether a file is a directory or not.
+ *
+ * This is a replacement for the g_file_test functionality which is reported
+ * to be unreliable under certain circumstances, for example if this
+ * application and glib are compiled with a different libc.
+ *
+ * @todo FIXME: handle symbolic links
+ * @todo Move to libs?
+ *
+ * @return 1 if parameter is directory, 0 if it is not, -1 if it does not
+ * exist or could not be accessed.
+ */
+static int
+check_is_dir (const char* name)
+{
+ struct stat sb;
+
+ if (stat (name, &sb))
+ {
+ return -1;
+ }
+ else
+ {
+ return (S_ISDIR (sb.st_mode));
+ }
+}
+
+
+/** @todo Copied verbatim from openvas-client/src/util/file_utils.c. */
+
+/**
+ * @brief Recursively removes files and directories.
+ *
+ * This function will recursively call itself to delete a path and any
+ * contents of this path.
+ *
+ * @param pathname The name of the file to be deleted from the filesystem.
+ *
+ * @return 0 if the name was successfully deleted, -1 if an error occurred.
+ * Please note that errno is currently not guaranteed to contain the correct
+ * value if -1 is returned.
+ */
+static int
+file_utils_rmdir_rf (const gchar * pathname)
+{
+ if (check_is_dir (pathname) == 1)
+ {
+ GError *error = NULL;
+ GDir *directory = g_dir_open (pathname, 0, &error);
+
+ if (directory == NULL)
+ {
+ g_warning ("g_dir_open(%s) failed - %s\n", pathname, error->message);
+ g_error_free (error);
+ // errno should be set when we return -1 to maintain remove()
+ // compatibility.
+ return -1;
+ }
+ else
+ {
+ int ret = 0;
+ const gchar *entry = NULL;
+
+ while ((entry = g_dir_read_name (directory)) && (ret == 0))
+ {
+ ret = file_utils_rmdir_rf (g_build_filename (pathname, entry, NULL));
+ if (ret != 0)
+ {
+ g_warning ("Failed to remove %s from %s!", entry, pathname);
+ g_dir_close (directory);
+ return ret;
+ }
+ }
+ g_dir_close (directory);
+ }
+ }
+
+ return g_remove (pathname);
+}
+
+/**
+ * @brief Reads contents from a source file into a destination file.
+ *
+ * The source file is read into memory, so it is inefficient and likely to fail
+ * for really big files.
+ * If the destination file does exist already, it will be overwritten.
+ *
+ * @returns TRUE if successfull, FALSE otherwise (displays error but does not
+ * clean up).
+ */
+static gboolean
+file_utils_copy_file (const gchar* source_file, const gchar* dest_file)
+{
+ gchar* src_file_content = NULL;
+ gsize src_file_size = 0;
+ int bytes_written = 0;
+ FILE* fd = NULL;
+ GError *error;
+
+ // Read file content into memory
+ error = NULL;
+ g_file_get_contents (source_file, &src_file_content, &src_file_size, &error);
+ if (error)
+ {
+ show_error (_("Error reading file %s: %s"), source_file, error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+
+ // Open destination file
+ fd = fopen (dest_file, "wb");
+ if (fd == NULL)
+ {
+ show_error (_("Error opening file %s."), dest_file);
+ g_free (src_file_content);
+ return FALSE;
+ }
+
+ // Write content of src to dst and close it
+ bytes_written = fwrite (src_file_content, 1, src_file_size, fd);
+ fclose (fd);
+
+ if (bytes_written != src_file_size)
+ {
+ show_error (_("Error writing to file %s. (%d/%d)"), dest_file, bytes_written, src_file_size);
+ g_free (src_file_content);
+ return FALSE;
+ }
+ g_free (src_file_content);
+
+ return TRUE;
+}
+
+/**
+ * @brief Reads contents from a source file into a destination file
+ * @brief and unlinks the source file.
+ *
+ * The source file is read into memory, so it is inefficient and likely to fail
+ * for really big files.
+ * If the destination file does exist already, it will be overwritten.
+ *
+ * @returns TRUE if successfull, FALSE otherwise (displays error but does not
+ * clean up).
+ */
+static gboolean
+file_utils_move_file (const gchar* source_file, const gchar* dest_file)
+{
+ // Copy file (will displays errors itself)
+ if (file_utils_copy_file (source_file, dest_file) == FALSE)
+ return FALSE;
+
+ // Remove source file
+ if (remove (source_file) != 0)
+ {
+ show_error (_("Error removing file %s."), source_file);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/* Key creation. */
+
+/**
+ * @brief Creates a private key for local checks.
+ *
+ * Forks and creates a key for local checks by calling
+ * "openssl pkcs8 -topk8 -v2 des3 -in filepath -passin pass:passphrase -out
+ * filepath.p8 -passout pass:passphrase"
+ * Directories within privkey_file will be created if they do not exist.
+ *
+ * @param pubkey_file Path to file of public key (a trailing .pub will be stripped).
+ * @param privkey_file Name of private key file to be created.
+ *
+ * @param passphrase_pub The passphrase for the public key.
+ * @param passphrase_priv Passhprase for the private key.
+ *
+ * @return TRUE if successfull, FALSE otherwise.
+ */
+static gboolean
+ssh_privkey_create (char* pubkey_file, char* privkey_file,
+ char* passphrase_pub, char* passphrase_priv)
+{
+ gchar* astdout = NULL;
+ gchar* astderr = NULL;
+ GError* err = NULL;
+ gint exit_status;
+ gchar* dir = NULL;
+ gchar* pubkey_stripped = NULL;
+
+ /* Sanity-check essential parameters */
+ if(!passphrase_pub || !passphrase_priv)
+ {
+ show_error(_("Error creating private key file:\nPlease provide all information."));
+ return FALSE;
+ }
+
+ /* Sanity check files */
+#if 0
+ if(check_exists(pubkey_file) != 1)
+ {
+ show_error(_("Error creating private key file:\nPublic key %s not found."), pubkey_file);
+ return FALSE;
+ }
+ if(check_exists(privkey_file) != 0 )
+ {
+ show_error(_("Error creating private key file:\nFile already exists."));
+ return FALSE;
+ }
+#else
+ if (g_file_test (pubkey_file, G_FILE_TEST_EXISTS) == FALSE)
+ {
+ show_error(_("Error creating private key file:\nPublic key %s not found."), pubkey_file);
+ return FALSE;
+ }
+ if (g_file_test (privkey_file, G_FILE_TEST_EXISTS))
+ {
+ show_error(_("Error creating private key file:\nFile already exists."));
+ return FALSE;
+ }
+#endif
+ dir = g_path_get_dirname(privkey_file);
+#if 0
+ if(file_utils_ensure_dir(dir) != TRUE)
+ {
+ show_error(_("Error creating private key file:\nfolder %s not accessible."), dir);
+ g_free (dir);
+ return FALSE;
+ }
+#else
+ if (g_mkdir_with_parents (dir, 0755 /* "rwxr-xr-x" */))
+ {
+ show_error(_("Error creating private key file:\nfolder %s not accessible."), dir);
+ g_free (dir);
+ return FALSE;
+ }
+#endif
+ g_free (dir);
+
+ // Strip ".pub" of public key filename, if any.
+ if (g_str_has_suffix(pubkey_file, ".pub") == TRUE)
+ {
+ pubkey_stripped = g_malloc (strlen(pubkey_file) -
+ strlen(".pub") +1); /* RATS: ignore, string literal is nul-terminated */
+ g_strlcpy (pubkey_stripped, pubkey_file, strlen(pubkey_file) -
+ strlen(".pub") + 1); /* RATS: ignore, string literal is nul-terminated */
+ }
+ else
+ pubkey_stripped = g_strdup(pubkey_file);
+
+ /* Fire openssl */
+ const gchar* command = g_strconcat ("openssl pkcs8 -topk8 -v2 des3 -in ", pubkey_stripped,
+ " -passin pass:", passphrase_pub, " -out ",
+ privkey_file, " -passout pass:",
+ passphrase_priv, NULL);
+ g_free (pubkey_stripped);
+
+ if (g_spawn_command_line_sync(command, &astdout, &astderr, &exit_status, &err) == FALSE
+ || WIFEXITED (exit_status) == 0
+ || WEXITSTATUS (exit_status))
+ {
+ show_error (_("Error creating private key file.\nFor further information consult your shell."));
+ printf ("Error creating private key file.");
+ printf ("\tSpawned openssl process returned with %d.\n", exit_status);
+ printf ("\t\t stdout: %s\n", astdout);
+ printf ("\t\t stderr: %s\n", astderr);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ * Forks and creates a key for local checks by calling
+ * "ssh-keygen -t rsa -f filepath -C comment -P passhprase -q"
+ * A directory will be created if it does not exist.
+ *
+ * @param comment Comment to use (will be freed).
+ * @param passphrase The passphrase for the key (will be freed), must be longer
+ * than 4 characters (+nul).
+ * @param filepath Path to file of public key (a trailing .pub will be stripped).
+ *
+ * @return TRUE if successfull, FALSE otherwise.
+ */
+static gboolean
+ssh_pubkey_create (const char* comment, char* passphrase, char* filepath)
+{
+ gchar* astdout = NULL;
+ gchar* astderr = NULL;
+ GError* err = NULL;
+ gint exit_status = 0;
+ gchar* dir;
+ gchar* file_pubstripped;
+
+ /* Sanity-check essential parameters */
+ if (!comment || comment[0] == '\0')
+ {
+ show_error (_("Error creating public key file:\ncomment has to be set."));
+ return FALSE;
+ }
+ if (!passphrase || strlen(passphrase) < 5)
+ {
+ show_error (_("Error creating public key file:\npassword must be longer than 4 characters."));
+ return FALSE;
+ }
+ /* Sanity check files */
+ dir = g_path_get_dirname (filepath);
+#if 0
+ if (file_utils_ensure_dir(dir) != TRUE)
+ {
+ show_error (_("Error creating public key file:\n%s is not accessable."), filepath);
+ g_free (dir);
+ return FALSE;
+ }
+#else
+ if (g_mkdir_with_parents (dir, 0755 /* "rwxr-xr-x" */))
+ {
+ show_error(_("Error creating public key file:\n %s not accessible."), dir);
+ g_free (dir);
+ return FALSE;
+ }
+#endif
+ g_free (dir);
+#if 0
+ if (check_exists(filepath) == 1)
+ {
+ show_error (_("Error creating public key file:\n%s already exists."), filepath);
+ return FALSE;
+ }
+#else
+ if (g_file_test (filepath, G_FILE_TEST_EXISTS))
+ {
+ show_error (_("Error creating public key file:\n%s already exists."), filepath);
+ return FALSE;
+ }
+#endif
+
+ // Strip ".pub" of filename, if any.
+ if (g_str_has_suffix(filepath, ".pub") == TRUE)
+ {
+ file_pubstripped = g_malloc(strlen(filepath) -
+ strlen(".pub") +1); /* RATS: ignore, string literal is nul-terminated */
+ g_strlcpy (file_pubstripped, filepath, strlen(filepath) -
+ strlen(".pub") + 1); /* RATS: ignore, string literal is nul-terminated */
+ }
+ else
+ file_pubstripped = g_strdup(filepath);
+
+ /* Fire ssh-keygen */
+ const char* command = g_strconcat("ssh-keygen -t rsa -f ", file_pubstripped, " -C ",
+ comment, " -P ", passphrase, NULL);
+ g_free (file_pubstripped);
+
+ g_debug ("command: %s", command);
+
+ if (g_spawn_command_line_sync(command, &astdout, &astderr, &exit_status, &err) == FALSE
+ || WIFEXITED (exit_status) == 0
+ || WEXITSTATUS (exit_status))
+ {
+ // FIX should free err
+ show_error (_("Error creating public key file.\nFor further information consult your shell."));
+ g_debug ("Error creating public key file.\n");
+ g_debug ("\tSpawned key-gen process returned with %d (WIF %i, WEX %i).\n",
+ exit_status, WIFEXITED (exit_status), WEXITSTATUS (exit_status));
+ g_debug ("\t\t stdout: %s", astdout);
+ g_debug ("\t\t stderr: %s", astderr);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+/**
+ * @brief Creates the public and private key files.
+ *
+ * @param loginfo.
+ * @return TRUE if things went good, FALSE if things went bad.
+ */
+static gboolean
+ssh_key_create (openvas_ssh_login* loginfo)
+{
+ /* Create pubkey */
+ gboolean success = ssh_pubkey_create (loginfo->comment,
+ loginfo->ssh_key_passphrase,
+ loginfo->public_key_path);
+
+ /* Eventually report failure */
+ if (success == FALSE)
+ return FALSE;
+
+ /* Create private key */
+ success = ssh_privkey_create (loginfo->public_key_path,
+ loginfo->private_key_path,
+ loginfo->ssh_key_passphrase,
+ loginfo->ssh_key_passphrase);
+ return success;
+}
+
+/**
+ * @brief Unlinks pub. and private key files + identity file.
+ *
+ * @param loginfo Login of which to unlink files.
+ */
+static void
+ssh_key_create_unlink_files (openvas_ssh_login* loginfo)
+{
+ char* identity_file = NULL;
+
+ if (loginfo == NULL)
+ return;
+
+ // Create identity file path
+ if (loginfo->public_key_path != NULL)
+ {
+ int len = (strlen(loginfo->public_key_path) -
+ strlen (".pub") + 1); /* RATS: ignore, string literal is nul-terminated */
+ if (len > 0)
+ {
+ identity_file = emalloc (len);
+ g_strlcpy (identity_file, loginfo->public_key_path, len);
+ }
+
+ // Delete all the files
+ unlink (identity_file);
+ unlink (loginfo->private_key_path);
+ unlink (loginfo->public_key_path);
+ }
+
+ efree (&identity_file);
+}
+
+
+/* RPM package generation. */
+
+/**
+ * @brief Returns the path to the directory where the rpm generator
+ * @brief ("openvas-ssh-client-rpm-creator.sh") is located.
+ *
+ * The search will be performed just once.
+ *
+ * @return Path to the directory with the rpm generator or NULL (shall not be
+ * freed!).
+ */
+static gchar*
+get_rpm_generator_path ()
+{
+ static gchar* rpm_generator_path = NULL;
+
+ if (rpm_generator_path == NULL)
+ {
+ // Search in two location
+ gchar* path_exec = g_build_filename ("/home/mattm/share/openvas",
+ "openvas-ssh-client-rpm-creator.sh",
+ NULL);
+ if (check_is_file (path_exec) == 0)
+ {
+ g_free (path_exec);
+ path_exec = g_build_filename ("tools", "openvas-ssh-client-rpm-creator.sh", NULL);
+ if (check_is_file (path_exec) == 0)
+ {
+ // Could not be found at all
+ g_free (path_exec);
+ }
+ else
+ g_free (path_exec);
+ // FIX indented with else, should other brn return NULL?
+ rpm_generator_path = g_strdup ("tools");
+ }
+ else
+ rpm_generator_path = g_strdup ("/home/mattm/share/openvas");
+ }
+
+ return rpm_generator_path;
+}
+
+/**
+ * @brief Attempts creation of RPM packages to install a users public key file.
+ *
+ * @param loginfo openvas_ssh_login struct to create rpm for.
+ *
+ * @return Path to rpm file if successfull, NULL otherwise.
+ */
+static gboolean
+lsc_user_rpm_create (openvas_ssh_login* loginfo, const gchar* to_filename)
+{
+ // The scripts to create rpms are currently in trunk/tools/openvas-lsc-target-preparation.
+ // Move to trunk/openvas-client/tools will be done when function is stable.
+ gchar* oltap_path;
+ gchar* rpm_path = NULL;
+ gint exit_status;
+ gchar* new_pubkey_filename = NULL;
+ gchar* pubkey_basename = NULL;
+ gchar** cmd;
+ gchar* tmpdir = NULL;
+ gboolean success = TRUE;
+
+ oltap_path = get_rpm_generator_path ();
+
+ /* Create a temporary directory. */
+
+ g_debug ("%s: create temporary directory", __FUNCTION__);
+#if 0
+ tmpdir = openvas_lsc_target_prep_create_tmp_dir();
+ if (tmpdir == NULL)
+ {
+ return FALSE;
+ }
+#else /* not 0 */
+ // FIX create unique name
+ tmpdir = g_build_filename ("/tmp/",
+ "lsc-mngt",
+ "tmp",
+ NULL);
+ if (g_mkdir_with_parents (tmpdir, 0755 /* "rwxr-xr-x" */))
+ {
+ g_free (tmpdir);
+ return FALSE;
+ }
+#endif /* not 0 */
+ g_debug ("%s: temporary directory: %s\n", __FUNCTION__, tmpdir);
+
+ /* Copy the public key into the temporary directory. */
+
+ g_debug ("%s: copy key to temporary directory\n", __FUNCTION__);
+ pubkey_basename = g_strdup_printf ("%s.pub", loginfo->username);
+ new_pubkey_filename = g_build_filename (tmpdir, pubkey_basename, NULL);
+ if (file_utils_copy_file (loginfo->public_key_path, new_pubkey_filename) == FALSE)
+ {
+ show_error ("Could not copy key file %s to %s.",
+ loginfo->public_key_path, new_pubkey_filename);
+ g_free (pubkey_basename);
+ g_free (new_pubkey_filename);
+ g_free (tmpdir);
+ return FALSE;
+ }
+
+ /* Execute create-rpm script with the temporary directory as the
+ * target and the public key in the temporary directory as the key. */
+
+ g_debug ("%s: Attempting RPM build\n", __FUNCTION__);
+ cmd = (gchar **) g_malloc (5 * sizeof (gchar *));
+ cmd[0] = g_strdup ("./openvas-ssh-client-rpm-creator.sh");
+ cmd[1] = g_strdup ("--target");
+ cmd[2] = g_strdup (tmpdir);
+ cmd[3] = g_build_filename (tmpdir, pubkey_basename, NULL);
+ cmd[4] = NULL;
+ g_debug ("%s: Spawning in %s: %s %s %s %s\n",
+ __FUNCTION__,
+ oltap_path, cmd[0], cmd[1], cmd[2], cmd[3]);
+ gchar *standard_out;
+ gchar *standard_err;
+ if (g_spawn_sync (oltap_path,
+ cmd,
+ NULL, // env
+ G_SPAWN_SEARCH_PATH,
+ NULL, // setup func
+ NULL,
+ &standard_out,
+ &standard_err,
+ &exit_status,
+ NULL ) == FALSE
+ || exit_status != 0)
+ {
+ show_error(_("Error (%d) creating the rpm.\n"
+ "For further information consult your shell."), exit_status);
+ g_debug ("%s: sout: %s\n", __FUNCTION__, standard_out);
+ g_debug ("%s: serr: %s\n", __FUNCTION__, standard_err);
+ success = FALSE;
+ }
+
+ g_free (cmd[0]);
+ g_free (cmd[1]);
+ g_free (cmd[2]);
+ g_free (cmd[3]);
+ g_free (cmd[4]);
+ g_free (cmd);
+ g_free (pubkey_basename);
+ g_free (new_pubkey_filename);
+ g_debug ("%s: cmd returned %d.\n", __FUNCTION__, exit_status);
+
+ /* Build the filename that the RPM in the temporary directory has,
+ * for example RPMS/noarch/openvas-lsc-target-example_user-0.5-1.noarch.rpm.
+ */
+
+ gchar* rpmfile = g_strconcat ("openvas-lsc-target-",
+ loginfo->username,
+ "-0.5-1.noarch.rpm",
+ NULL);
+ rpm_path = g_build_filename (tmpdir, rpmfile, NULL);
+ g_debug ("%s: new filename (rpm_path): %s\n", __FUNCTION__, rpm_path);
+
+ /* Move the RPM from the temporary directory to the given destination. */
+
+ if (file_utils_move_file (rpm_path, to_filename) == FALSE
+ && success == TRUE)
+ {
+ show_error (_("RPM- File %s couldn't be moved to %s.\nFile will be deleted."),
+ rpm_path, to_filename);
+ success = FALSE;
+ }
+
+ /* Remove the copy of the public key and the temporary directory. */
+
+ if (file_utils_rmdir_rf (tmpdir) != 0
+ && success == TRUE)
+ {
+ // FIX just make this an error
+ show_error (_("Temporary directory (%s) which contains private"
+ "information could not be deleted."),
+ tmpdir);
+ }
+
+ g_free (tmpdir);
+ g_free (rpm_path);
+ g_free (rpmfile);
+
+ return success;
+}
+
+
+/* Deb generation. */
+
+/**
+ * @brief Execute alien to create a deb package from an rpm package.
+ *
+ * @param rpmdir Directory to run the command in.
+ * @param rpmfile .rpm file to transform with alien to a .deb.
+ *
+ * @return 0 success, -1 error.
+ */
+static int
+execute_alien (const gchar* rpmdir, const gchar* rpmfile)
+{
+ gchar** cmd;
+ gint exit_status = 0;
+
+ /* FIX Why allocate all of this? */
+ cmd = (gchar **) g_malloc (7 * sizeof (gchar *));
+
+ cmd[0] = g_strdup ("fakeroot");
+ cmd[1] = g_strdup ("--");
+ cmd[2] = g_strdup ("alien");
+ cmd[3] = g_strdup ("--scripts");
+ cmd[4] = g_strdup ("--keep-version");
+ cmd[5] = g_strdup (rpmfile);
+ cmd[6] = NULL;
+ g_debug ("--- executing alien.\n");
+ g_debug ("%s: Spawning in %s: %s %s %s %s %s %s\n",
+ __FUNCTION__,
+ rpmdir, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], cmd[5]);
+ if ((g_spawn_sync (rpmdir,
+ cmd,
+ NULL, // env
+ G_SPAWN_SEARCH_PATH,
+ NULL, // setup func
+ NULL,
+ NULL,
+ NULL,
+ &exit_status,
+ NULL)
+ == FALSE)
+ || exit_status != 0)
+ {
+ exit_status = -1;
+ }
+
+ g_free (cmd[0]);
+ g_free (cmd[1]);
+ g_free (cmd[2]);
+ g_free (cmd[3]);
+ g_free (cmd[4]);
+ g_free (cmd[5]);
+ g_free (cmd[6]);
+ g_free (cmd);
+
+ g_debug ("--- alien returned %d.\n", exit_status);
+ return exit_status;
+}
+
+/**
+ * @brief Create a deb packages from an rpm package.
+ *
+ * @param loginfo openvas_ssh_login struct to create rpm for.
+ * @param rpm_file location of the rpm file.
+ *
+ * @return deb package file name on success, else NULL.
+ */
+gchar*
+lsc_user_deb_create (openvas_ssh_login* loginfo,
+ const gchar* rpm_file)
+{
+ gchar* dirname = g_path_get_dirname (rpm_file);
+ gchar* dir = g_strconcat (dirname, "/", NULL);
+ gchar* basename = g_path_get_basename (rpm_file);
+ gchar* username = g_strdup (loginfo->username ? loginfo->username : "user");
+ gchar* deb_name = g_strdup_printf ("%s/openvas-lsc-target-%s_0.5-1_all.deb",
+ dirname,
+ g_ascii_strdown (username, -1));
+
+ g_free (dirname);
+ g_free (username);
+
+ if (execute_alien (dir, basename))
+ {
+ g_free (dir);
+ g_free (basename);
+ g_free (deb_name);
+ return NULL;
+ }
+
+ g_free (dir);
+ g_free (basename);
+
+ return deb_name;
+}
+
+/**
+ * @brief Returns whether alien could be found in the path.
+ *
+ * The check itself will only be done once.
+ *
+ * @return true if alien could be found in the path, false otherwise.
+ */
+static gboolean
+alien_found ()
+{
+ static gboolean searched = FALSE;
+ static gboolean found = FALSE;
+
+ if (searched == FALSE)
+ {
+ // Check if alien is found in path
+ gchar* alien_path = g_find_program_in_path ("alien");
+ if (alien_path != NULL)
+ {
+ found = TRUE;
+ g_free (alien_path);
+ }
+ searched = TRUE;
+ }
+
+ return found;
+}
+
+
+/* Generation of all packages. */
+
+// FIX adapted from openvas-client/src/util/openvas_ssh_key_create.c
+/**
+ * @brief Create local security check (LSC) packages.
+ *
+ * @param[in] name User name.
+ * @param[in] password Password.
+ * @param[out] public_key Public key.
+ * @param[out] private_key Private key.
+ * @param[out] rpm RPM package.
+ * @param[out] rpm_size Size of RPM package, in bytes.
+ * @param[out] deb Debian package.
+ * @param[out] deb_size Size of Debian package, in bytes.
+ * @param[out] exe NSIS package.
+ * @param[out] exe_size Size of NSIS package, in bytes.
+ *
+ * @return 0 success, -1 error.
+ */
+int
+lsc_user_all_create (const gchar *name,
+ const gchar *password,
+ gchar **public_key,
+ gchar **private_key,
+ void **rpm, gsize *rpm_size,
+ void **deb, gsize *deb_size,
+ void **exe, gsize *exe_size)
+{
+ GError *error;
+ gsize length;
+ char *key_name, *comment, *key_password, *public_key_path;
+ char *private_key_path, *user_name, *user_password;
+ char rpm_dir[] = "/tmp/rpm_XXXXXX";
+ gchar *rpm_path, *deb_path;
+
+ // FIX just skip deb
+ if (alien_found () == FALSE)
+ return -1;
+
+ // FIX free?
+ key_name = estrdup ("key_name");
+ comment = estrdup ("comment");
+ key_password = estrdup ("password");
+ // FIX get temp file
+ public_key_path = estrdup ("/tmp/key.pub");
+ // FIX get temp file
+ private_key_path = estrdup ("/tmp/key.priv");
+ user_name = estrdup (name);
+ user_password = estrdup (password);
+
+ openvas_ssh_login *login = openvas_ssh_login_new (key_name,
+ public_key_path,
+ private_key_path,
+ key_password,
+ comment,
+ user_name,
+ user_password);
+
+ /* Create keys. */
+
+ ssh_key_create_unlink_files (login);
+ if (ssh_key_create (login) == FALSE)
+ {
+ openvas_ssh_login_free (login);
+ return -1;
+ }
+
+ /* Create RPM package. */
+
+ // FIX close rpm_dir?
+ if (mkdtemp (rpm_dir) == NULL) return -1;
+ rpm_path = g_build_filename (rpm_dir, "p.rpm", NULL);
+ g_debug ("%s: rpm_path: %s", __FUNCTION__, rpm_path);
+ if (lsc_user_rpm_create (login, rpm_path) == FALSE)
+ {
+ g_free (rpm_path);
+ openvas_ssh_login_free (login);
+ return -1;
+ }
+
+ /* Create Debian package. */
+
+ deb_path = lsc_user_deb_create (login, rpm_path);
+ if (deb_path == NULL)
+ {
+ g_free (rpm_path);
+ g_free (deb_path);
+ openvas_ssh_login_free (login);
+ return -1;
+ }
+ g_debug ("%s: deb_path: %s", __FUNCTION__, deb_path);
+
+#if 0
+ /* Create NSIS installer. */
+
+ exe_path = lsc_user_exe_create (login);
+ if (exe_path == NULL)
+ {
+ g_free (rpm_path);
+ g_free (deb_path);
+ g_free (exe_path);
+ openvas_ssh_login_free (login);
+ return -1;
+ }
+ g_debug ("%s: exe_path: %s", __FUNCTION__, deb_path);
+#endif
+
+ error = NULL;
+ g_file_get_contents (login->public_key_path,
+ public_key,
+ &length,
+ &error);
+ if (error)
+ {
+ g_free (rpm_path);
+ g_free (deb_path);
+ g_error_free (error);
+ openvas_ssh_login_free (login);
+ return -1;
+ }
+
+ error = NULL;
+ g_file_get_contents (login->private_key_path,
+ private_key,
+ &length,
+ &error);
+ if (error)
+ {
+ g_free (rpm_path);
+ g_free (deb_path);
+ g_error_free (error);
+ openvas_ssh_login_free (login);
+ return -1;
+ }
+
+ error = NULL;
+ g_file_get_contents (rpm_path,
+ (gchar**) rpm,
+ rpm_size,
+ &error);
+ // FIX remove rpm file
+ g_free (rpm_path);
+ if (error)
+ {
+ g_error_free (error);
+ g_free (deb_path);
+ openvas_ssh_login_free (login);
+ return -1;
+ }
+
+ error = NULL;
+ g_file_get_contents (deb_path,
+ (gchar**) deb,
+ deb_size,
+ &error);
+ // FIX remove deb file (just remove rpm dir)
+ g_free (deb_path);
+ if (error)
+ {
+ g_error_free (error);
+ openvas_ssh_login_free (login);
+ return -1;
+ }
+
+ *exe = g_strdup ("");
+ *exe_size = 0;
+
+ openvas_ssh_login_free (login);
+
+ return 0;
+}
Added: trunk/openvas-manager/src/lsc_user.h
===================================================================
--- trunk/openvas-manager/src/lsc_user.h 2009-10-21 18:58:55 UTC (rev 5668)
+++ trunk/openvas-manager/src/lsc_user.h 2009-10-21 22:34:13 UTC (rev 5669)
@@ -0,0 +1,42 @@
+/* OpenVAS Manager
+ * $Id$
+ * Description: LSC user credentials package generation.
+ *
+ * Authors:
+ * Matthew Mundell <matthew.mundell at intevation.de>
+ * Felix Wolfsteller <felix.wolfsteller at intevation.de>
+ *
+ * Copyright:
+ * Copyright (C) 2009 Greenbone Networks GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * or, at your option, any later version as published by the Free
+ * Software Foundation
+ *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _OPENVASMD_LSC_USER_H
+#define _OPENVASMD_LSC_USER_H
+
+#include <glib.h>
+#include "openvas_ssh_login.h"
+
+int
+lsc_user_all_create (const gchar *name,
+ const gchar *password,
+ gchar **public_key,
+ gchar **private_key,
+ void **rpm, gsize *rpm_size,
+ void **deb, gsize *deb_size,
+ void **exe, gsize *exe_size);
+
+#endif /* _OPENVASMD_LSC_USER_H */
Modified: trunk/openvas-manager/src/manage.h
===================================================================
--- trunk/openvas-manager/src/manage.h 2009-10-21 18:58:55 UTC (rev 5668)
+++ trunk/openvas-manager/src/manage.h 2009-10-21 22:34:13 UTC (rev 5669)
@@ -676,7 +676,7 @@
delete_lsc_credential (const char*);
void
-init_lsc_credential_iterator (iterator_t*);
+init_lsc_credential_iterator (iterator_t*, const char*);
const char*
lsc_credential_iterator_name (iterator_t*);
@@ -684,6 +684,21 @@
const char*
lsc_credential_iterator_comment (iterator_t*);
+const char*
+lsc_credential_iterator_public_key (iterator_t*);
+
+const char*
+lsc_credential_iterator_private_key (iterator_t*);
+
+const char*
+lsc_credential_iterator_rpm (iterator_t*);
+
+const char*
+lsc_credential_iterator_deb (iterator_t*);
+
+const char*
+lsc_credential_iterator_exe (iterator_t*);
+
/* Scanner messaging. */
Modified: trunk/openvas-manager/src/omp.c
===================================================================
--- trunk/openvas-manager/src/omp.c 2009-10-21 18:58:55 UTC (rev 5668)
+++ trunk/openvas-manager/src/omp.c 2009-10-21 22:34:13 UTC (rev 5669)
@@ -888,7 +888,16 @@
else if (strcasecmp ("GET_DEPENDENCIES", element_name) == 0)
set_client_state (CLIENT_GET_DEPENDENCIES);
else if (strcasecmp ("GET_LSC_CREDENTIALS", element_name) == 0)
- set_client_state (CLIENT_GET_LSC_CREDENTIALS);
+ {
+ const gchar* attribute;
+ if (find_attribute (attribute_names, attribute_values,
+ "name", &attribute))
+ openvas_append_string (¤t_uuid, attribute);
+ if (find_attribute (attribute_names, attribute_values,
+ "format", &attribute))
+ openvas_append_string (¤t_format, attribute);
+ set_client_state (CLIENT_GET_LSC_CREDENTIALS);
+ }
else if (strcasecmp ("GET_NVT_ALL", element_name) == 0)
set_client_state (CLIENT_GET_NVT_ALL);
else if (strcasecmp ("GET_NVT_FEED_CHECKSUM", element_name) == 0)
@@ -4067,21 +4076,30 @@
"CREATE_LSC_CREDENTIAL name must both be at"
" least one character long"));
}
- else if (create_lsc_credential (modify_task_name,
- modify_task_comment))
+ else switch (create_lsc_credential (modify_task_name,
+ modify_task_comment))
{
- openvas_free_string_var (&modify_task_comment);
- openvas_free_string_var (&modify_task_name);
- SEND_TO_CLIENT_OR_FAIL
- (XML_ERROR_SYNTAX ("create_lsc_credential",
- "LSC Credential exists already"));
+ case 0:
+ openvas_free_string_var (&modify_task_comment);
+ openvas_free_string_var (&modify_task_name);
+ SEND_TO_CLIENT_OR_FAIL (XML_OK_CREATED ("create_lsc_credential"));
+ break;
+ case 1:
+ openvas_free_string_var (&modify_task_comment);
+ openvas_free_string_var (&modify_task_name);
+ SEND_TO_CLIENT_OR_FAIL
+ (XML_ERROR_SYNTAX ("create_lsc_credential",
+ "LSC Credential exists already"));
+ break;
+ default:
+ assert (0);
+ case -1:
+ openvas_free_string_var (&modify_task_comment);
+ openvas_free_string_var (&modify_task_name);
+ SEND_TO_CLIENT_OR_FAIL
+ (XML_INTERNAL_ERROR ("create_lsc_credential"));
+ break;
}
- else
- {
- openvas_free_string_var (&modify_task_comment);
- openvas_free_string_var (&modify_task_name);
- SEND_TO_CLIENT_OR_FAIL (XML_OK_CREATED ("create_lsc_credential"));
- }
set_client_state (CLIENT_AUTHENTIC);
break;
}
@@ -5133,22 +5151,103 @@
case CLIENT_GET_LSC_CREDENTIALS:
{
iterator_t targets;
+ int format;
assert (strcasecmp ("GET_LSC_CREDENTIALS", element_name) == 0);
- SEND_TO_CLIENT_OR_FAIL ("<get_lsc_credentials_response"
- " status=\"" STATUS_OK "\""
- " status_text=\"" STATUS_OK_TEXT "\">");
- init_lsc_credential_iterator (&targets);
- while (next (&targets))
- SENDF_TO_CLIENT_OR_FAIL ("<lsc_credential>"
- "<name>%s</name>"
- "<comment>%s</comment>"
- "</lsc_credential>",
- lsc_credential_iterator_name (&targets),
- lsc_credential_iterator_comment
- (&targets));
- cleanup_iterator (&targets);
- SEND_TO_CLIENT_OR_FAIL ("</get_lsc_credentials_response>");
+ if (current_format)
+ {
+ if (strlen (current_format))
+ {
+ if (strcasecmp (current_format, "key") == 0)
+ format = 1;
+ else if (strcasecmp (current_format, "rpm") == 0)
+ format = 2;
+ else if (strcasecmp (current_format, "deb") == 0)
+ format = 3;
+ else if (strcasecmp (current_format, "exe") == 0)
+ format = 4;
+ else
+ format = -1;
+ }
+ else
+ format = 0;
+ openvas_free_string_var (¤t_format);
+ }
+ else
+ format = 0;
+ if (format == -1)
+ SEND_TO_CLIENT_OR_FAIL
+ (XML_ERROR_SYNTAX ("get_lsc_credentials",
+ "GET_LSC_CREDENTIALS format attribute should"
+ " be \"key\", \"rpm\", \"deb\" or \"exe\"."));
+ else
+ {
+ SEND_TO_CLIENT_OR_FAIL ("<get_lsc_credentials_response"
+ " status=\"" STATUS_OK "\""
+ " status_text=\"" STATUS_OK_TEXT "\">");
+ init_lsc_credential_iterator (&targets, current_uuid);
+ while (next (&targets))
+ {
+ switch (format)
+ {
+ case 1: /* key */
+ SENDF_TO_CLIENT_OR_FAIL
+ ("<lsc_credential>"
+ "<name>%s</name>"
+ "<comment>%s</comment>"
+ "<public_key>%s</public_key>"
+ "</lsc_credential>",
+ lsc_credential_iterator_name (&targets),
+ lsc_credential_iterator_comment (&targets),
+ lsc_credential_iterator_public_key (&targets));
+ break;
+ case 2: /* rpm */
+ SENDF_TO_CLIENT_OR_FAIL
+ ("<lsc_credential>"
+ "<name>%s</name>"
+ "<comment>%s</comment>"
+ "<package format=\"rpm\">%s</package>"
+ "</lsc_credential>",
+ lsc_credential_iterator_name (&targets),
+ lsc_credential_iterator_comment (&targets),
+ lsc_credential_iterator_rpm (&targets));
+ break;
+ case 3: /* deb */
+ SENDF_TO_CLIENT_OR_FAIL
+ ("<lsc_credential>"
+ "<name>%s</name>"
+ "<comment>%s</comment>"
+ "<package format=\"deb\">%s</package>"
+ "</lsc_credential>",
+ lsc_credential_iterator_name (&targets),
+ lsc_credential_iterator_comment (&targets),
+ lsc_credential_iterator_deb (&targets));
+ break;
+ case 4: /* exe */
+ SENDF_TO_CLIENT_OR_FAIL
+ ("<lsc_credential>"
+ "<name>%s</name>"
+ "<comment>%s</comment>"
+ "<package format=\"exe\">%s</package>"
+ "</lsc_credential>",
+ lsc_credential_iterator_name (&targets),
+ lsc_credential_iterator_comment (&targets),
+ lsc_credential_iterator_exe (&targets));
+ break;
+ default:
+ SENDF_TO_CLIENT_OR_FAIL
+ ("<lsc_credential>"
+ "<name>%s</name>"
+ "<comment>%s</comment>"
+ "</lsc_credential>",
+ lsc_credential_iterator_name (&targets),
+ lsc_credential_iterator_comment (&targets));
+ break;
+ }
+ }
+ cleanup_iterator (&targets);
+ SEND_TO_CLIENT_OR_FAIL ("</get_lsc_credentials_response>");
+ }
set_client_state (CLIENT_AUTHENTIC);
break;
}
Modified: trunk/openvas-manager/src/openvasmd.c
===================================================================
--- trunk/openvas-manager/src/openvasmd.c 2009-10-21 18:58:55 UTC (rev 5668)
+++ trunk/openvas-manager/src/openvasmd.c 2009-10-21 22:34:13 UTC (rev 5669)
@@ -325,6 +325,7 @@
break;
default:
g_warning ("%s: Failed to determine protocol\n", __FUNCTION__);
+ goto fail;
}
openvas_server_free (scanner_socket,
@@ -459,7 +460,7 @@
if (log_config) free_log_configuration (log_config);
/* Delete pidfile if this process is the parent. */
- if (is_parent == 1) pidfile_remove("openvasmd");
+ if (is_parent == 1) pidfile_remove ("openvasmd");
}
/**
@@ -882,7 +883,13 @@
if (signal (SIGTERM, handle_sigterm) == SIG_ERR /* RATS: ignore */
|| signal (SIGINT, handle_sigint) == SIG_ERR /* RATS: ignore */
|| signal (SIGHUP, handle_sighup) == SIG_ERR /* RATS: ignore */
- || signal (SIGCHLD, SIG_IGN) == SIG_ERR) /* RATS: ignore */
+#if 0
+ /**
+ * @todo lsc_user_all_create needs this signal to get child return
+ * statuses. */
+ || signal (SIGCHLD, SIG_IGN) == SIG_ERR /* RATS: ignore */
+#endif
+ )
{
g_critical ("%s: failed to register signal handler\n", __FUNCTION__);
exit (EXIT_FAILURE);
@@ -986,8 +993,9 @@
}
/* Set our pidfile. */
- if (pidfile_create("openvasmd")) exit (EXIT_FAILURE);
+ if (pidfile_create ("openvasmd")) exit (EXIT_FAILURE);
+
/* Loop waiting for connections and passing the work to
* `accept_and_maybe_fork'.
*
Modified: trunk/openvas-manager/src/tasks_sql.h
===================================================================
--- trunk/openvas-manager/src/tasks_sql.h 2009-10-21 18:58:55 UTC (rev 5668)
+++ trunk/openvas-manager/src/tasks_sql.h 2009-10-21 22:34:13 UTC (rev 5669)
@@ -26,11 +26,12 @@
#include <sqlite3.h>
#include <openvas/openvas_logging.h>
+#include "lsc_user.h"
/**
* @brief Version of the database schema.
*/
-#define DATABASE_VERSION 2
+#define DATABASE_VERSION 3
/**
* @brief NVT selector type for "all" rule.
@@ -1089,7 +1090,7 @@
sql ("CREATE TABLE IF NOT EXISTS report_results (report INTEGER, result INTEGER);");
sql ("CREATE TABLE IF NOT EXISTS nvts (oid, version, name, summary, description, copyright, cve, bid, xref, tag, sign_key_ids, category INTEGER, family);");
sql ("CREATE TABLE IF NOT EXISTS nvt_preferences (name, value);");
- sql ("CREATE TABLE IF NOT EXISTS lsc_credentials (name, comment, rpm, deb, dog);");
+ sql ("CREATE TABLE IF NOT EXISTS lsc_credentials (name, password, comment, public_key TEXT, private_key TEXT, rpm TEXT, deb TEXT, exe TEXT);");
/* Ensure the version is set. */
@@ -3710,6 +3711,7 @@
g_warning ("%s: sqlite3_prepare failed: %s\n",
__FUNCTION__,
sqlite3_errmsg (task_db));
+ /** @todo END if in transaction. */
abort ();
}
@@ -3722,7 +3724,7 @@
while (1)
{
- ret = sqlite3_bind_text (stmt, 1, id, -1, SQLITE_STATIC);
+ ret = sqlite3_bind_text (stmt, 1, id, -1, SQLITE_TRANSIENT);
if (ret == SQLITE_BUSY) continue;
if (ret == SQLITE_OK) break;
g_warning ("%s: sqlite3_prepare failed: %s\n",
@@ -4813,13 +4815,19 @@
* @param[in] name Name of LSC credential.
* @param[in] comment Comment on LSC credential.
*
- * @return 0 success, 1 LSC credential exists already.
+ * @return 0 success, 1 LSC credential exists already, -1 error.
*/
int
create_lsc_credential (const char* name, const char* comment)
{
gchar *quoted_name = sql_nquote (name, strlen (name));
- gchar *quoted_comment;
+ gchar *quoted_comment, *public_key, *private_key, *base64;
+ void *rpm, *deb, *exe;
+ gsize rpm_size, deb_size, exe_size;
+ int i;
+ GRand *rand;
+#define PASSWORD_LENGTH 10
+ gchar password[PASSWORD_LENGTH];
sql ("BEGIN IMMEDIATE;");
@@ -4831,21 +4839,240 @@
return 1;
}
- if (comment)
+ /* Create the keys and packages. */
+
+ rand = g_rand_new ();
+ for (i = 0; i < PASSWORD_LENGTH - 1; i++)
+ password[i] = (gchar) g_rand_int_range (rand, '0', 'z');
+ password[PASSWORD_LENGTH - 1] = '\0';
+
+ if (lsc_user_all_create (name,
+ password,
+ &public_key,
+ &private_key,
+ &rpm, &rpm_size,
+ &deb, &deb_size,
+ &exe, &exe_size))
{
- quoted_comment = sql_nquote (comment, strlen (comment));
- sql ("INSERT INTO lsc_credentials (name, comment)"
- " VALUES ('%s', '%s');",
- quoted_name, quoted_comment);
- g_free (quoted_comment);
+ g_free (quoted_name);
+ sql ("END;");
+ return -1;
}
- else
- sql ("INSERT INTO lsc_credentials (name, comment)"
- " VALUES ('%s', '');",
- quoted_name);
- g_free (quoted_name);
+ /* Insert the packages. */
+ {
+ const char* tail;
+ int ret;
+ sqlite3_stmt* stmt;
+ gchar* formatted, *quoted_password;
+
+ quoted_password = sql_nquote (password, strlen (password));
+ if (comment)
+ {
+ quoted_comment = sql_nquote (comment, strlen (comment));
+ formatted = g_strdup_printf ("INSERT INTO lsc_credentials"
+ " (name, password, comment,"
+ " public_key, private_key, rpm, deb, exe)"
+ " VALUES"
+ " ('%s', '%s', '%s',"
+ " $public_key, $private_key,"
+ " $rpm, $deb, $exe);",
+ quoted_name,
+ quoted_password,
+ quoted_comment);
+ g_free (quoted_comment);
+ }
+ else
+ {
+ formatted = g_strdup_printf ("INSERT INTO lsc_credentials"
+ " (name, password, comment,"
+ " public_key, private_key, rpm, deb, exe)"
+ " VALUES"
+ " ('%s', '%s', '',"
+ " $public_key, $private_key,"
+ " $rpm, $deb, $exe);",
+ quoted_name,
+ quoted_password);
+ }
+
+ g_free (quoted_name);
+ g_free (quoted_password);
+
+ tracef (" sql: %s\n", formatted);
+
+ /* Prepare statement. */
+
+ while (1)
+ {
+ ret = sqlite3_prepare (task_db, (char*) formatted, -1, &stmt, &tail);
+ if (ret == SQLITE_BUSY) continue;
+ if (ret == SQLITE_OK)
+ {
+ if (stmt == NULL)
+ {
+ g_warning ("%s: sqlite3_prepare failed with NULL stmt: %s\n",
+ __FUNCTION__,
+ sqlite3_errmsg (task_db));
+ sql ("END;");
+ g_free (public_key);
+ g_free (private_key);
+ g_free (rpm);
+ g_free (deb);
+ g_free (exe);
+ return -1;
+ }
+ break;
+ }
+ g_warning ("%s: sqlite3_prepare failed: %s\n",
+ __FUNCTION__,
+ sqlite3_errmsg (task_db));
+ sql ("END;");
+ g_free (public_key);
+ g_free (private_key);
+ g_free (rpm);
+ g_free (deb);
+ g_free (exe);
+ return -1;
+ }
+
+ /* Bind the keys to the "$values" in the SQL statement. */
+
+ while (1)
+ {
+ ret = sqlite3_bind_text (stmt,
+ 1,
+ public_key,
+ strlen (public_key),
+ SQLITE_TRANSIENT);
+ if (ret == SQLITE_BUSY) continue;
+ if (ret == SQLITE_OK) break;
+ g_warning ("%s: sqlite3_prepare failed: %s\n",
+ __FUNCTION__,
+ sqlite3_errmsg (task_db));
+ sql ("END;");
+ g_free (public_key);
+ g_free (private_key);
+ g_free (rpm);
+ g_free (deb);
+ g_free (exe);
+ return -1;
+ }
+ g_free (public_key);
+
+ while (1)
+ {
+ ret = sqlite3_bind_text (stmt,
+ 2,
+ private_key,
+ strlen (private_key),
+ SQLITE_TRANSIENT);
+ if (ret == SQLITE_BUSY) continue;
+ if (ret == SQLITE_OK) break;
+ g_warning ("%s: sqlite3_prepare failed: %s\n",
+ __FUNCTION__,
+ sqlite3_errmsg (task_db));
+ sql ("END;");
+ g_free (private_key);
+ g_free (rpm);
+ g_free (deb);
+ g_free (exe);
+ return -1;
+ }
+ g_free (private_key);
+
+ /* Bind the packages to the "$values" in the SQL statement. */
+
+ base64 = (rpm && strlen (rpm))
+ ? g_base64_encode (rpm, rpm_size)
+ : g_strdup ("");
+ g_free (rpm);
+ while (1)
+ {
+ ret = sqlite3_bind_text (stmt,
+ 3,
+ base64,
+ strlen (base64),
+ SQLITE_TRANSIENT);
+ if (ret == SQLITE_BUSY) continue;
+ if (ret == SQLITE_OK) break;
+ g_warning ("%s: sqlite3_prepare failed: %s\n",
+ __FUNCTION__,
+ sqlite3_errmsg (task_db));
+ sql ("END;");
+ g_free (base64);
+ g_free (deb);
+ g_free (exe);
+ return -1;
+ }
+ g_free (base64);
+
+ base64 = (deb && strlen (deb))
+ ? g_base64_encode (deb, deb_size)
+ : g_strdup ("");
+ g_free (deb);
+ while (1)
+ {
+ ret = sqlite3_bind_text (stmt,
+ 4,
+ base64,
+ strlen (base64),
+ SQLITE_TRANSIENT);
+ if (ret == SQLITE_BUSY) continue;
+ if (ret == SQLITE_OK) break;
+ g_warning ("%s: sqlite3_prepare failed: %s\n",
+ __FUNCTION__,
+ sqlite3_errmsg (task_db));
+ sql ("END;");
+ g_free (base64);
+ g_free (exe);
+ return -1;
+ }
+ g_free (base64);
+
+ base64 = (exe && strlen (exe))
+ ? g_base64_encode (exe, exe_size)
+ : g_strdup ("");
+ g_free (exe);
+ while (1)
+ {
+ ret = sqlite3_bind_blob (stmt,
+ 5,
+ base64,
+ strlen (base64),
+ SQLITE_TRANSIENT);
+ if (ret == SQLITE_BUSY) continue;
+ if (ret == SQLITE_OK) break;
+ g_warning ("%s: sqlite3_prepare failed: %s\n",
+ __FUNCTION__,
+ sqlite3_errmsg (task_db));
+ sql ("END;");
+ g_free (base64);
+ return -1;
+ }
+ g_free (base64);
+
+ /* Run the statement. */
+
+ while (1)
+ {
+ ret = sqlite3_step (stmt);
+ if (ret == SQLITE_BUSY) continue;
+ if (ret == SQLITE_DONE) break;
+ if (ret == SQLITE_ERROR || ret == SQLITE_MISUSE)
+ {
+ if (ret == SQLITE_ERROR) ret = sqlite3_reset (stmt);
+ g_warning ("%s: sqlite3_step failed: %s\n",
+ __FUNCTION__,
+ sqlite3_errmsg (task_db));
+ sql ("END;");
+ return -1;
+ }
+ }
+
+ sqlite3_finalize (stmt);
+ }
+
sql ("COMMIT;");
return 0;
@@ -4885,19 +5112,62 @@
* @param[in] iterator Iterator.
*/
void
-init_lsc_credential_iterator (iterator_t* iterator)
+init_lsc_credential_iterator (iterator_t* iterator, const char *name)
{
- init_table_iterator (iterator, "lsc_credentials");
+ int ret;
+ const char* tail;
+ gchar* formatted;
+ sqlite3_stmt* stmt;
+
+ iterator->done = FALSE;
+ if (name && strlen (name))
+ {
+ gchar* quoted_name = sql_quote (name);
+ formatted = g_strdup_printf ("SELECT * FROM lsc_credentials"
+ " WHERE name = '%s';",
+ quoted_name);
+ g_free (quoted_name);
+ }
+ else
+ formatted = g_strdup_printf ("SELECT * FROM lsc_credentials;");
+ while (1)
+ {
+ ret = sqlite3_prepare (task_db, (char*) formatted, -1, &stmt, &tail);
+ if (ret == SQLITE_BUSY) continue;
+ g_free (formatted);
+ iterator->stmt = stmt;
+ if (ret == SQLITE_OK)
+ {
+ if (stmt == NULL)
+ {
+ g_warning ("%s: sqlite3_prepare failed with NULL stmt: %s\n",
+ __FUNCTION__,
+ sqlite3_errmsg (task_db));
+ abort ();
+ }
+ break;
+ }
+ g_warning ("%s: sqlite3_prepare failed: %s\n",
+ __FUNCTION__,
+ sqlite3_errmsg (task_db));
+ abort ();
+ }
}
DEF_ACCESS (lsc_credential_iterator_name, 0);
+DEF_ACCESS (lsc_credential_iterator_password, 1);
+DEF_ACCESS (lsc_credential_iterator_public_key, 3);
+DEF_ACCESS (lsc_credential_iterator_private_key, 4);
+DEF_ACCESS (lsc_credential_iterator_rpm, 5);
+DEF_ACCESS (lsc_credential_iterator_deb, 6);
+DEF_ACCESS (lsc_credential_iterator_exe, 7);
const char*
lsc_credential_iterator_comment (iterator_t* iterator)
{
const char *ret;
if (iterator->done) return "";
- ret = (const char*) sqlite3_column_text (iterator->stmt, 1);
+ ret = (const char*) sqlite3_column_text (iterator->stmt, 2);
return ret ? ret : "";
}
More information about the Openvas-commits
mailing list