#!/bin/sh
#
# greenbone-scap-sync
# This script synchronizes an OpenVAS installation with the Greenbone SCAP
# data directory.
#
# Authors:
# Henri Doreau <henri.doreau@greenbone.net>
# Michael Wiegand <michael.wiegand@greenbone.net>
# Timo Pollmeier <timo.pollmeier@greenbone.net>
#
# Copyright:
# Copyright (C) 2011, 2012, 2013 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.

VERSION=20130314
RESTRICTED=1

# SETTINGS
# ========

# Path prefix for installation location
PREFIX=

# PRIVATE_SUBDIR defines a subdirectory of the CERT data directory
# where files not part of the feed or database will not be deleted by rsync.
if [ -z "$PRIVATE_SUBDIR" ]
then
  PRIVATE_SUBDIR="private"
fi

# RSYNC_DELETE controls whether files which are not part of the repository will
# be removed from the local directory after synchronization. The default value
# for this setting is
# "--delete --exclude scap.db --exclude $PRIVATE_SUBDIR/",
# which means that files which are not part of the feed, database or private
# directory will be deleted.
RSYNC_DELETE="--delete --exclude scap.db --exclude $PRIVATE_SUBDIR/"

# PORT controls the outgoing TCP port for updates. If PAT/Port-Translation is
# not used, this should be "24". For some application layer firewalls or gates
# the value 22 (Standard SSH) is useful. Only change if you know what you are
# doing.
PORT=24

# LOGDIR and LOGFILE specify the location of the greenbone-scapdata-sync logfile.
# The default value for LOGDIR is  "/var/log/", the default value for
# LOGFILE is "greenbone-scapdata-sync.log". Please make sure this script has
# sufficient right to access the logfile.
LOGDIR="$PREFIX/var/log/openvas/"
LOGFILE="greenbone-scapdata-sync.log"

# If ENABLED is set to 0, the sync script will not perform a synchronization.
ENABLED=1

# If REFRESH_ONLY is set to 1, the sync script will only update the OpenVAS
# Manager database. This can be controlled via the --refresh parameter.
REFRESH_ONLY=0
# If REFRESH_PRIVATE_ONLY is set to 1, the sync script will only update
# private data in the OpenVAS Manager database.
# This can be controlled via the --refresh-private parameter.
REFRESH_PRIVATE_ONLY=0
# When set to 1, all OVAL definitions will be updated, not just new ones.
# This is usually done by database migrations.
REBUILD_OVAL=0
# Setting this to 1 enables verbose mode, which outputs additional data.
# This is usually done with the option --verbose
VERBOSE=0

SQLITE3="sqlite3 -noheader"

[ -r $PREFIX/etc/openvas/greenbone-scapdata-sync.conf ] && . $PREFIX/etc/openvas/greenbone-scapdata-sync.conf

BASE_SYNC_DIR="$PREFIX/var/lib/openvas"
SCAP_DIR="$BASE_SYNC_DIR/scap-data"

if [ -z "$PREFIX" ] ; then
  SCAP_RES_DIR="/usr/share/openvas/scap"
else
  SCAP_RES_DIR="$PREFIX/share/openvas/scap"
fi

SCAP_DB="$SCAP_DIR/scap.db"

ACCESSKEY="$PREFIX/etc/openvas/gsf-access-key"

SCRIPT_NAME="greenbone-scapdata-sync"

TIMESTAMP="$SCAP_DIR/timestamp"

if [ -z "$FEED_NAME" ] ; then
  FEED_NAME="Greenbone SCAP Feed"
fi

if [ -z "$FEED_VENDOR" ] ; then
  FEED_VENDOR="Greenbone Networks GmbH"
fi

if [ -z "$FEED_HOME" ] ; then
  FEED_HOME="http://www.greenbone.net/solutions/gbn_feed.html"
fi

do_describe () {
  echo "This script synchronizes a SCAP collection with the '$FEED_NAME'."
  echo "The '$FEED_NAME' is provided by '$FEED_VENDOR'."
  echo "Online information about this feed: '$FEED_HOME'."
}

do_feedversion () {
  if [ -r $TIMESTAMP ] ; then
      echo `cat $TIMESTAMP`
  fi
}

if [ ! -w $LOGDIR ]
then
  NOLOG=1
  echo
  echo "== greenbone-scapdata-sync $VERSION ================================================"
  echo "Warning: The logfile directory"
  echo "  ($LOGDIR)"
  echo "does not exist or is not writeable. Please make sure this directory exists and"
  echo "is writable."
  echo "Please be aware that logging is not possible during this script run!"
  echo "==============================================================================="
  echo
fi

log_write(){
  if [ 1 = "$NOLOG" ]
  then
    echo "LOG: [`date -R`] $1"
  else
    echo "[`date -R`] $1" >> $LOGDIR$LOGFILE
  fi
}

if [ $ENABLED -ne 1 ]
then
  log_write "SCAP synchronization is disabled, exiting."
  exit 0
fi

RSYNC=`command -v rsync`
if [ -z $RSYNC ]
then
  echo
  echo "== greenbone-scapdata-sync $VERSION ================================================"
  echo "Could not find tools necessary for synchronization."
  echo "Please make sure that the tool"
  echo "  rsync"
  echo "is installed and available in your PATH variable."
  echo "If you are still not able to continue, please contact Greenbone Support at"
  echo "support@greenbone.net and include the error messages displayed above (if any)"
  echo "and your customer ID."
  echo "==============================================================================="
  echo
  log_write "rsync not found, aborting synchronization."
  logger "SCAP synchronization: rsync not found, aborting synchronization."
  exit 1
fi

SQLITE=`command -v sqlite3`
if [ -z $SQLITE ]
then
  echo
  echo "== greenbone-scapdata-sync $VERSION ================================================"
  echo "Could not find tools necessary for synchronization."
  echo "Please make sure that the tool"
  echo "  sqlite3"
  echo "is installed and available in your PATH variable."
  echo "If you are still not able to continue, please contact Greenbone Support at"
  echo "support@greenbone.net and include the error messages displayed above (if any)"
  echo "and your customer ID."
  echo "==============================================================================="
  echo
  log_write "sqlite3 not found, aborting synchronization."
  logger "SCAP synchronization: sqlite3 not found, aborting synchronization."
  exit 1
fi

if [ -z $BASE_SYNC_DIR ]
then
  echo
  echo "BASE_SYNC_DIR ($BASE_SYNC_DIR) not found!"
  echo
  exit 1
fi

reinit () {
  log_write " Reinitialization of the database necessary."
  rm -f $SCAP_DB
  $SQLITE3 $SCAP_DB < $SCAP_RES_DIR/scap_db_init.sql
}

db_migrate_9 () {
  log_write "Migrating database to version 9."
  $SQLITE3 "$SCAP_DB" "DROP INDEX IF EXISTS afp_idx;
                       CREATE INDEX afp_cpe_idx ON affected_products (cpe);
                       CREATE INDEX afp_cve_idx ON affected_products (cve);
                       UPDATE meta SET value = '9' WHERE name = 'database_version';"
  log_write "Migration done."
}

db_migrate_10 () {
  log_write "Migrating database to version 10."
  $SQLITE3 "$SCAP_DB" "DROP TRIGGER affected_delete;
                       CREATE TRIGGER affected_delete AFTER DELETE ON affected_products
                       BEGIN
                         UPDATE cpes set max_cvss = 0.0 WHERE id = old.cpe;
                         UPDATE cpes set cve_refs = cve_refs -1 WHERE id = old.cpe;
                       END;
                       UPDATE meta
                         SET value = '10'
                         WHERE name = 'database_version';"
  log_write "Migration done."
}

db_migrate_11 () {
  log_write "Migrating database to version 11."
  if [ 1 != "$REFRESH_PRIVATE_ONLY" ]
  then
    sqlite3 "$SCAP_DB"  "ALTER TABLE ovaldefs
                          ADD COLUMN status TEXT;
                        UPDATE meta
                          SET value = '11'
                          WHERE name = 'database_version';
                      "
    REBUILD_OVAL=1
    log_write "Migration done."
  else
    log_write "Warning: Migration to version 11 requires refresh of all SCAP data. Aborting."
    exit 1
  fi
}

check_db_version () {
  DB_VERSION=`$SQLITE3 $SCAP_DB "select value from meta where name = 'database_version';" 2>/dev/null || echo 0`
  case "$DB_VERSION" in
    0) reinit;;
    1) reinit;;
    2) reinit;;
    3) reinit;;
    4) reinit;;
    5) reinit;;
    6) reinit;;
    7) reinit;;
    8) db_migrate_9
       db_migrate_10
       db_migrate_11;;
    9) db_migrate_10
       db_migrate_11;;
   10) db_migrate_11;;
  esac
}

list_oval_files_sorted () {
for line in `list_oval_files_sortable "$1" | sort`
  do
    echo ${line#????????}
  done
}

list_oval_files_sortable () {
for ovalfile in `find "$1" -name "*.xml" -type f`
  do
    timestamp_raw=""
    timestamp_raw=`xsltproc "$SCAP_RES_DIR/oval_timestamp.xsl" "$ovalfile" 2>/dev/null`

    if [ -n "$timestamp_raw" ] \
       && [ -n `echo "$timestamp_raw" | egrep -x "[0-9]{4}\-(0[0-9]|1[012])\-([0-2][0-9]|3[01])[:alnum:]*"` ]
    then
      timestamp="`echo "$timestamp_raw" | sed -e 's/T.*//' | tr -d "-"`"
      echo "$timestamp$ovalfile"
    fi
  done
}

do_help () {
  echo "$0: Sync SCAP data"
  echo " --describe        display current feed info"
  echo " --feedversion     display version of this feed"
  echo " --help            display this help"
  echo " --identify        display information"
  echo " --refresh         update database without downloading new state"
  echo " --refresh-private update database using only user data"
  echo " --selftest        perform self-test"
  echo " --version         display version"
  echo " --verbose         enable verbose log messages"
  echo ""
  exit 0
}

init_scap_db_update () {
  if [ ! -f $SCAP_DB ]
  then
    log_write "Initializing SCAP database."
    $SQLITE3 $SCAP_DB < $SCAP_RES_DIR/scap_db_init.sql
    CVE_REFDATE=0
  else
    check_db_version
    CVE_REFDATE=`$SQLITE3 $SCAP_DB "select date(max(modification_time),'unixepoch') from cves;" | sed -e 's/T.*//' | tr -d "-"`
  fi

  DB_LASTUPDATE=`$SQLITE3 $SCAP_DB "select value from meta where name = 'last_update';"`

  if [ -z "$CVE_REFDATE" ]
  then
    CVE_REFDATE=0
  fi

  if [ -z "$DB_LASTUPDATE" ];
  then
    # Happens when initial sync was aborted
    log_write "Error: Inconsistent data. Resetting SCAP database."
    rm -f $SCAP_DB
    $SQLITE3 $SCAP_DB < $SCAP_RES_DIR/scap_db_init.sql
    CVE_REFDATE=0
    DB_LASTUPDATE=0
  fi

}

update_scap_db_private () {
  SCAP_PRIVATE_DIR="$SCAP_DIR/$PRIVATE_SUBDIR"
  if [ -d "$SCAP_PRIVATE_DIR" ]
  then
    log_write "Updating user defined data"

    log_write "Updating user OVAL definitions"
    xmlcount=0
    xmlcount=$(find "$SCAP_PRIVATE_DIR/oval/" -name "*.xml" -type f 2> /dev/null | wc -l)
    if [ -n "$xmlcount" ] && [ $xmlcount -ne 0 ]
    then
      if [ -z "$oval_files_sorted" ]
      then
        oval_files_sorted=`list_oval_files_sorted "$SCAP_DIR/oval/"`
        ovaldir_xml_files=`find "$SCAP_DIR/oval/" -name "*.xml" -type f 2> /dev/null`

        for xml_file in $ovaldir_xml_files
        do
          if [ -z `echo "$oval_files_sorted" | grep -x "$xml_file"` ]
          then
            log_write "Warning: Cannot find valid OVAL timestamp in '$xml_file'."
          fi
        done
      fi

      oval_files_sorted_private=`list_oval_files_sorted "$SCAP_PRIVATE_DIR/oval/"`
      ovaldir_xml_files=`find "$SCAP_PRIVATE_DIR/oval/" -name "*.xml" -type f 2> /dev/null`

      for xml_file in $ovaldir_xml_files
      do
        if [ -z `echo "$oval_files_sorted_private" | grep -x "$xml_file"` ]
        then
          log_write "Warning: Cannot find valid OVAL timestamp in '$xml_file'."
        fi
      done

      for non_xml_file in `find "$SCAP_PRIVATE_DIR/oval/" -type f -and -not -name "*.xml" 2> /dev/null`
      do
        if [ "${non_xml_file%%.asc}" = "${non_xml_file}" ] || ! [ -f "${non_xml_file%%.asc}" ]
        then
          log_write "Warning: Found non-XML and non-signature file '$non_xml_file'."
        fi
      done

      if [ -n "$oval_files_sorted" ]
      then
        for ovalfile in $oval_files_sorted_private
        do
          if [ `stat -c "%Y" "$ovalfile" | cut -d " " -f 1 | tr -d "-"` -ge $DB_LASTUPDATE ] || [ 1 = $REBUILD_OVAL ]
          then
            oval_timestamp=`xsltproc "$SCAP_RES_DIR/oval_timestamp.xsl" "$ovalfile" | sed -e 's/T.*//' | tr -d "-"`

            if [ 1 = "$REBUILD_OVAL" ]
            then
              OVAL_REFDATE=0
            else
              OVAL_REFDATE=`$SQLITE3 $SCAP_DB "SELECT date(max(modification_time),'unixepoch') FROM ovaldefs WHERE xml_file = '${ovalfile##$SCAP_DIR/}';" | tr -d "-"`
              if [ -z "$OVAL_REFDATE" ]
              then
                OVAL_REFDATE=0
              fi
            fi

            if [ $oval_timestamp -ge $OVAL_REFDATE ]
            then
              validation_message=`xsltproc "$SCAP_RES_DIR/oval_verify.xsl" "$ovalfile" 2>/dev/null`
              validation_return="$?"
              if [ 0 -ne $validation_return ] && [ -n "$validation_message" ]
              then
                if [ 10 -eq $validation_return ]
                then
                  log_write "Warning: Validation of file '$ovalfile' failed: $validation_message"
                else
                  log_write "Warning: Error parsing '$ovalfile'."
                fi
              else
                if ! [ "$validation_message" = "file valid" ]
                then
                  log_write "Warning: Validation of file '$ovalfile' failed: $validation_message"
                else
                  for feedfile in $oval_files_sorted
                  do
                    compare=`xsltproc "$SCAP_RES_DIR/ovaldef_list_ids.xsl" "$ovalfile"`
                    duplicates=`xsltproc "$SCAP_RES_DIR/ovaldef_list_ids.xsl" "$feedfile" | grep -Fx "$compare"`
                    duplicates_count=`echo "$duplicates" | wc -l`
                    if [ -n "$duplicates" ]
                    then
                      log_write "Warning: Skipping '$ovalfile', found $duplicates_count definition(s) that are duplicates of one(s) in '$feedfile'"
                      if [ 0 -ne $VERBOSE ]
                      then
                        for duplicate in $duplicates
                        do
                          log_write "Duplicate ID: $duplicate"
                        done
                      fi
                    fi
                  done
                  if [ 0 -eq $duplicates_count ]
                  then
                    log_write "Updating $ovalfile"
                    xsltproc --stringparam filename "${ovalfile##$SCAP_DIR/}" --stringparam refdate "$OVAL_REFDATE" "$SCAP_RES_DIR/oval_update.xsl" "$ovalfile" | \
                    $SQLITE3 $SCAP_DB
                  fi
                fi
              fi
            else
              log_write "Skipping $ovalfile, file has older timestamp than latest OVAL definition in database. (This is not an error)"
            fi
          else
            log_write "Skipping $ovalfile, file is older than last revision. (This is not an error)"
          fi
        done
      fi
    else
      log_write "No user defined OVAL files found"
    fi

    log_write "Cleaning up user OVAL data"
    DIR_STR_LENGTH=$((`echo "$SCAP_DIR" | wc -c` + 1))

    oval_files_shortened=""
    if [ 0 != "$xmlcount" ]
    then
      for ovalfile in $oval_files_sorted_private
      do
        oval_files_shortened=$oval_files_shortened"', '"`echo $ovalfile | cut -c ${DIR_STR_LENGTH}- `
      done
      oval_files_shortened=${oval_files_shortened##"', "}"'"
    fi

    deleted=`$SQLITE3 "$SCAP_DB" "SELECT DISTINCT xml_file FROM ovaldefs WHERE (xml_file NOT LIKE 'oval/%') AND (xml_file NOT IN ($oval_files_shortened));"`
    if [ -n "$deleted" ]
    then
      log_write "Removing definitions formerly inserted from:"
      log_write "$deleted"
      $SQLITE3 "$SCAP_DB" "DELETE FROM ovaldefs WHERE (xml_file NOT LIKE 'oval/%') AND (xml_file NOT IN ($oval_files_shortened));"
    fi

    $SQLITE3 $SCAP_DB "update meta set value ='`date +%s`' where name = 'last_update';"
  else
    log_write "No user data directory '$SCAP_PRIVATE_DIR' found."
  fi
}

update_scap_db() {
  init_scap_db_update

  if [ 0 = "$REFRESH_PRIVATE_ONLY" ]
  then
    CPEBASE="$SCAP_DIR/official-cpe-dictionary_v2.2.xml"
    if [ -e $CPEBASE ]
    then
      if [ `stat -c "%Y" $CPEBASE | cut -d " " -f 1 | tr -d "-"` -ge $DB_LASTUPDATE ]
      then
        log_write "Updating CPEs"
        sed 's/&/&amp;/g' $CPEBASE | \
          xsltproc --stringparam refdate $CVE_REFDATE $SCAP_RES_DIR/cpe_youngerthan.xsl - | \
          xsltproc $SCAP_RES_DIR/cpe_update.xsl - | \
          $SQLITE3 $SCAP_DB
      else
        log_write " Skipping CPEs, file is older than last revision (this is not an error)."
      fi
    else
      echo " Warning: No CPE dictionary found in $SCAP_DIR"
    fi

    updated_cves=0
    xmlcount=$(ls $SCAP_DIR/nvdcve-2.0-*.xml 2> /dev/null | wc -l)
    if [ $xmlcount -ne 0 ]
    then
      for cvefile in `ls $SCAP_DIR/nvdcve-2.0-*.xml`
      do
        if [ `stat -c "%Y" $cvefile | cut -d " " -f 1 | tr -d "-"` -ge $DB_LASTUPDATE ]
        then
          updated_cves=1
          log_write "Updating $cvefile"
          xsltproc --stringparam refdate $CVE_REFDATE $SCAP_RES_DIR/cve_youngerthan.xsl $cvefile | \
            xsltproc $SCAP_RES_DIR/cve_update.xsl - | \
            $SQLITE3 $SCAP_DB
        else
          log_write "Skipping $cvefile, file is older than last revision (this is not an error)."
        fi
      done
    else
      log_write " Warning: No CVEs found in $SCAP_DIR."
    fi

    if [ 0 -ne $updated_cves ]
    then
      log_write "Updating CVSS scores and CVE counts"
      $SQLITE3 "$SCAP_DB"  "
      PRAGMA recursive_triggers = OFF;
      UPDATE cpes
        SET max_cvss =
            (
              SELECT coalesce(max(cvss), 0.0)
              FROM cves
              WHERE id IN
                (
                  SELECT cve
                  FROM affected_products
                  WHERE cpe=cpes.id
                )
            ),
          cve_refs =
            (
              SELECT count(cve)
              FROM affected_products
              WHERE cpe=cpes.id
            );
      "
    else
      log_write "No CVEs updated, skipping CVSS and CVE recount."
    fi

    log_write " Updating OVAL data"
    xmlcount=$(find "$SCAP_DIR/oval/" -name "*.xml" -type f 2> /dev/null | wc -l)
    if [ $xmlcount -ne 0 ]
    then
      oval_files_sorted=`list_oval_files_sorted "$SCAP_DIR/oval/"`
      ovaldir_xml_files=`find "$SCAP_DIR/oval/" -name "*.xml" -type f 2> /dev/null`

      for xml_file in $ovaldir_xml_files
      do
        if [ -z `echo "$oval_files_sorted" | grep -x "$xml_file"` ]
        then
          echo "[w] Cannot find valid OVAL timestamp in '$xml_file'."
        fi
      done

      for ovalfile in $oval_files_sorted
      do
        if [ `stat -c "%Y" "$ovalfile" | cut -d " " -f 1 | tr -d "-"` -ge $DB_LASTUPDATE ] || [ 1 = $REBUILD_OVAL ]
        then
          oval_timestamp=`xsltproc "$SCAP_RES_DIR/oval_timestamp.xsl" "$ovalfile" | sed -e 's/T.*//' | tr -d "-"`

          if [ 1 = "$REBUILD_OVAL" ]
          then
            OVAL_REFDATE=0
          else
            OVAL_REFDATE=`$SQLITE3 $SCAP_DB "SELECT date(max(modification_time),'unixepoch') FROM ovaldefs WHERE xml_file = '${ovalfile##$SCAP_DIR/}';" | tr -d "-"`
            if [ -z "$OVAL_REFDATE" ]
            then
              OVAL_REFDATE=0
            fi
          fi

          if [ $oval_timestamp -ge $OVAL_REFDATE ]
          then
            log_write "Updating $ovalfile"
            xsltproc --stringparam filename "${ovalfile##$SCAP_DIR/}" --stringparam refdate "$OVAL_REFDATE" "$SCAP_RES_DIR/oval_update.xsl" "$ovalfile" | \
            $SQLITE3 $SCAP_DB
          else
            log_write "Skipping $ovalfile, file has older timestamp than latest OVAL definition in database. (This is not an error)"
          fi
        else
          log_write " Skipping $ovalfile, file is older than last revision (this is not an error)."
        fi
      done
    else
      log_write " Warning: No XML files found in $SCAP_DIR/oval/."
    fi
  fi

  update_scap_db_private

  sqlite3 $SCAP_DB "update meta set value ='`date +%s`' where name = 'last_update';"
}

sync_scapdata(){
  if [ -e $ACCESSKEY ]
  then
    echo "Found Greenbone Security Feed subscription file, trying to synchronize with Greenbone SCAP data Repository ..."
    notsynced=1
    retried=0

    if [ $REFRESH_ONLY -eq 1 ]
    then
      notsynced=0
    fi

    mkdir -p "$BASE_SYNC_DIR"
    read feeduser < $ACCESSKEY
    custid=`head -1 $ACCESSKEY | cut -d @ -f 1`
    if [ -z $feeduser ] || [ -z $custid ]
    then
      echo "== greenbone-scapdata-sync $VERSION ================================================"
      echo "Synchronization was not possible because credential information could not"
      echo "be read from your access key."
      echo "Please make sure that the key located at"
      echo "  $sysconfdir/openvas/gsf-access-key"
      echo "is intact and in a valid format."
      echo "If you are still not able to continue, please contact Greenbone Support at"
      echo "support@greenbone.net and include the error messages displayed above (if any)"
      echo "and your customer ID."
      echo "==============================================================================="
      log_write "Could not determine credentials, aborting synchronization."
      logger "SCAP synchronization: Could not determine credentials, aborting synchronization."
      exit 1
    fi
    while [ 0 -ne "$notsynced" ]
    do
      # --protocol=29 is a workaround for a known bug in rsync 3.0.3
      if [ -e /admin/ezcli.state ]
      then
        gsmproxy=`grep proxy_feed /admin/ezcli.state | sed -e 's/^.*\/\///' -e 's/:/ /' -e 's/[\t ]*$//'`
        PORT=`grep ^syncport /admin/ezcli.state | sed -e "s/^syncport\t//g"`
      fi
      if [ -z "$gsmproxy" ] || [ "$gsmproxy" = "proxy_feed" ]
      then
        rsync -e "ssh -o \"UserKnownHostsFile=/dev/null\" -o \"StrictHostKeyChecking=no\" -p $PORT -i $ACCESSKEY" -ltvrP --protocol=29 --chmod=D+x $RSYNC_DELETE $custid@feed.greenbone.net:/scap-data $BASE_SYNC_DIR
      else
        if [ -r /admin/proxyauth -a `stat -c %s /admin/proxyauth` != 0 ]; then
          rsync -e "ssh -o \"UserKnownHostsFile=/dev/null\" -o \"StrictHostKeyChecking=no\" -o \"ProxyCommand corkscrew $gsmproxy %h %p /admin/proxyauth\" -p $PORT -i $ACCESSKEY" -ltvrP --protocol=29 --chmod=D+x $RSYNC_DELETE $custid@feed.greenbone.net:/scap-data $BASE_SYNC_DIR
        else
          rsync -e "ssh -o \"UserKnownHostsFile=/dev/null\" -o \"StrictHostKeyChecking=no\" -o \"ProxyCommand corkscrew $gsmproxy %h %p\" -p $PORT -i $ACCESSKEY" -ltvrP --protocol=29 --chmod=D+x $RSYNC_DELETE $custid@feed.greenbone.net:/scap-data $BASE_SYNC_DIR
        fi
      fi
      if [ 0 != "$?" ] ; then
        echo
        echo "== greenbone-scapdata-sync $VERSION ================================================"
        echo "The synchronization with the repository failed. This may indicate a serious issue"
        echo "with either your infrastructure or the repository itself."
        echo "Your local SCAP data repository may be damaged now. Please resolve any connection"
        echo "issues and try again."
        echo "If you suspect an issue with the Greenbone SCAP data Repository, please contact"
        echo "Greenbone support at support@greenbone.net and include the error messages"
        echo "displayed above (if any) and your customer ID ($custid)."
        echo "==============================================================================="
        echo
        log_write "rsync failed, aborting synchronization."
        logger "SCAP synchronization:  failed, aborting synchronization."
        exit 1
      fi
      notsynced=0
    done
    echo "Synchronization with the Greenbone SCAP data Repository successful."
    log_write "Synchronization with the Greenbone SCAP data Repository successful."
    logger "SCAP synchronization: Synchronization with the Greenbone SCAP data Repository successful."
    echo

    update_scap_db
  else
    echo
    echo "== greenbone-scapdata-sync $VERSION ================================================"
    echo "Could not find gsf-access-key."
    echo
    echo "This access key can be obtained from Greenbone Networks GmbH,"
    echo "see http://greenbone.net/solutions/gbn_feed.html for details."
    echo
    echo "Please make sure the personal access key you obtained from"
    echo "Greenbone is placed in the following directory:"
    echo $ACCESSKEY
    echo "Please make also sure that the filename is gsf-access-key."
    echo "If you are still not able to synchronize, please contact Greenbone Support at"
    echo "support@greenbone.net and include the error messages displayed above (if any)"
    echo "and your customer ID."
    echo "==============================================================================="
    echo
    log_write "gsf-access-key not found, aborting synchronization."
    logger "SCAP synchronization: gsf-access-key not found, aborting synchronization."
    exit 1
  fi
}

do_self_test () {
  if [ -z "$SQLITE" ]; then
    echo "[e] Error: sqlite3 not found (required)";
    SELFTEST_FAIL=1
  fi
}

while test $# -gt 0; do
 case "$1" in
        --version)
          echo $VERSION
          exit 0
           ;;
        --identify)
          echo "SCAPSYNC|$SCRIPT_NAME|$VERSION|$FEED_NAME|$RESTRICTED|SCAPSYNC"
          exit 0
          ;;
        --describe)
          do_describe
          exit 0
          ;;
        --feedversion)
          do_feedversion
          exit 0
          ;;
        --help)
          do_help
          exit 0
          ;;
        --verbose)
          VERBOSE=1
          ;;
        --refresh)
          REFRESH_ONLY=1
          ;;
        --refresh-private)
          REFRESH_ONLY=1
          REFRESH_PRIVATE_ONLY=1
          ;;
        --selftest)
          SELFTEST_FAIL=0
          do_self_test
          exit $SELFTEST_FAIL
          ;;
 esac
 shift
done

sync_scapdata

exit 0
