Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow resuming OSPd-based OpenVAS tasks (9.0) #869

Merged
merged 11 commits into from
Dec 3, 2019
Merged
90 changes: 90 additions & 0 deletions src/alert_methods/SCP/alert.orig
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#!/bin/sh
# Copyright (C) 2016-2018 Greenbone Networks GmbH
#
# SPDX-License-Identifier: GPL-2.0-or-later
#
# 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 St, Fifth Floor, Boston, MA 02110-1301 USA.

# Escalator method script: SCP.

USERNAME=$1
HOST=$2
DEST=$3
KNOWN_HOSTS=$4
PRIVATE_KEY_FILE=$5
PASSWORD_FILE=$6
REPORT_FILE=$7
<<<<<<< Updated upstream
mattmundell marked this conversation as resolved.
Show resolved Hide resolved
=======

echo "$REPORT_FILE" > /tmp/xyz
>>>>>>> Stashed changes

KNOWN_HOSTS_FILE=`mktemp` || exit 1
echo $KNOWN_HOSTS > $KNOWN_HOSTS_FILE

ERROR_FILE=`mktemp` || exit 1

log_error() {
logger "SCP alert: $1"
echo "$1" >&2
}

# Escape destination twice because it is also expanded on the remote end.
if [ -z "$PRIVATE_KEY_FILE" ]
then
sshpass -f ${PASSWORD_FILE} scp -o BatchMode=yes -o HashKnownHosts=no -o UserKnownHostsFile="${KNOWN_HOSTS_FILE} ~/.ssh/known_hosts ~/.ssh/known_hosts2 /etc/ssh/ssh_known_hosts" "${REPORT_FILE}" "${USERNAME}@${HOST}:'${DEST}'" 2>$ERROR_FILE
else
sshpass -f ${PASSWORD_FILE} scp -i "$PRIVATE_KEY_FILE" -o PasswordAuthentication=no -o BatchMode=yes -o HashKnownHosts=no -o UserKnownHostsFile="${KNOWN_HOSTS_FILE} ~/.ssh/known_hosts ~/.ssh/known_hosts2 /etc/ssh/ssh_known_hosts" "${REPORT_FILE}" "${USERNAME}@${HOST}:'${DEST}'" 2>$ERROR_FILE
fi
<<<<<<< Updated upstream

=======
>>>>>>> Stashed changes
EXIT_CODE=$?

ERROR_SHORT=`head -n 3 $ERROR_FILE`

if [ $EXIT_CODE -eq 1 ]
then
log_error "sshpass failed with exit code ${EXIT_CODE}: Invalid command line argument: $ERROR_SHORT"
elif [ $EXIT_CODE -eq 2 ]
then
log_error "sshpass failed with exit code ${EXIT_CODE}: Conflicting arguments given: $ERROR_SHORT"
elif [ $EXIT_CODE -eq 3 ]
then
log_error "sshpass failed with exit code ${EXIT_CODE}: General runtime error: $ERROR_SHORT"
elif [ $EXIT_CODE -eq 4 ]
then
log_error "sshpass failed with exit code ${EXIT_CODE}: Unrecognized response from ssh (parse error): $ERROR_SHORT"
elif [ $EXIT_CODE -eq 5 ]
then
log_error "sshpass failed with exit code ${EXIT_CODE}: Invalid/incorrect password: $ERROR_SHORT"
elif [ $EXIT_CODE -eq 6 ]
then
log_error "sshpass failed with exit code ${EXIT_CODE}: Host public key is unknown."
elif [ $EXIT_CODE -eq 127 ]
then
log_error "sshpass failed with exit code ${EXIT_CODE}: Command not found."
elif [ $EXIT_CODE -ne 0 ]
then
log_error "sshpass failed with exit code ${EXIT_CODE}: $ERROR_SHORT"
fi

rm $KNOWN_HOSTS_FILE
rm $PASSWORD_FILE
rm $ERROR_FILE

exit $EXIT_CODE
101 changes: 90 additions & 11 deletions src/manage.c
Original file line number Diff line number Diff line change
Expand Up @@ -3955,12 +3955,91 @@ target_osp_snmp_credential (target_t target)
return NULL;
}

/**
* @brief Prepare a report for resuming an OSP scan
*
* @param[in] task The task of the scan.
* @param[in] scan_id The scan uuid.
* @param[out] error Error return.
*
* @return 0 scan finished or still running,
* 1 scan must be started,
* -1 error
*/
static int
prepare_osp_scan_for_resume (task_t task, const char *scan_id, char **error)
{
osp_connection_t *connection;
osp_get_scan_status_opts_t status_opts;
osp_scan_status_t status;

assert (task);
assert (scan_id);
assert (global_current_report);
assert (error);

status_opts.scan_id = scan_id;

connection = osp_scanner_connect (task_scanner (task));
if (!connection)
{
*error = g_strdup ("Could not connect to Scanner");
return -1;
}
status = osp_get_scan_status_ext (connection, status_opts, error);

if (status == OSP_SCAN_STATUS_ERROR)
{
if (g_str_has_prefix (*error, "Failed to find scan"))
{
g_debug ("%s: Scan %s not found", __func__, scan_id);
g_free (*error);
*error = NULL;
osp_connection_close (connection);
trim_report (global_current_report);
return 1;
}
else
{
g_warning ("%s: Error getting status of scan %s: %s",
__func__, scan_id, *error);
osp_connection_close (connection);
return -1;
}
}
else if (status == OSP_SCAN_STATUS_RUNNING
|| status == OSP_SCAN_STATUS_FINISHED)
{
g_debug ("%s: Scan %s running or finished", __func__, scan_id);
osp_connection_close (connection);
return 0;
}
else if (status == OSP_SCAN_STATUS_STOPPED)
{
g_debug ("%s: Scan %s stopped", __func__, scan_id);
if (osp_delete_scan (connection, scan_id))
{
*error = g_strdup ("Failed to delete old report");
osp_connection_close (connection);
return -1;
}
osp_connection_close (connection);
trim_report (global_current_report);
return 1;
}

g_warning ("%s: Unexpected scanner status %d", __func__, status);
*error = g_strdup_printf ("Unexpected scanner status %d", status);
osp_connection_close (connection);
return -1;
}

/**
* @brief Launch an OpenVAS via OSP task.
*
* @param[in] task The task.
* @param[in] target The target.
* @param[in] scan_id The new scan uuid.
* @param[in] scan_id The scan uuid.
* @param[in] from 0 start from beginning, 1 continue from stopped,
* 2 continue if stopped else start from beginning.
* @param[out] error Error return.
Expand Down Expand Up @@ -3988,6 +4067,16 @@ launch_osp_openvas_task (task_t task, target_t target, const char *scan_id,

connection = NULL;

/* Prepare the report */
if (from)
{
ret = prepare_osp_scan_for_resume (task, scan_id, error);
if (ret == 0)
return 0;
else if (ret == -1)
return -1;
}

/* Set up target(s) */
hosts_str = target_hosts (target);
ports_str = target_port_range (target);
Expand Down Expand Up @@ -4115,16 +4204,6 @@ launch_osp_openvas_task (task_t task, target_t target, const char *scan_id,
}
cleanup_iterator (&prefs);

/* Clean up the report */
if (from)
{
// FIXME: Try to recover as much of the scan progress as possible.
connection = osp_scanner_connect (task_scanner (task));
osp_delete_scan (connection, scan_id);
osp_connection_close (connection);
trim_report (global_current_report);
}

/* Start the scan */
connection = osp_scanner_connect (task_scanner (task));
if (!connection)
Expand Down