public/tools/rmt-client-setup

Summary

Maintainability
Test Coverage
#! /bin/sh

CURL=/usr/bin/curl
OPENSSL=/usr/bin/openssl
CP=/bin/cp
CAT=/bin/cat
CHMOD=/bin/chmod
CUT=/usr/bin/cut
GREP=/usr/bin/grep
RM=/bin/rm
SUSECONNECT=/usr/sbin/SUSEConnect
GPG=/usr/bin/gpg
SUPPORTCONFIG=/etc/supportconfig.conf
SUPPORTCONFIGENTRY=VAR_OPTION_UPLOAD_TARGET
SED=/usr/bin/sed

CA_TRUSTSTORE="/etc/ssl/certs/"
CA_GEN_TRUSTSTORE_CMD="/usr/bin/c_rehash"

if [ -d "/etc/pki/trust/anchors/" ] && [ -x "/usr/sbin/update-ca-certificates" ]; then
    CA_TRUSTSTORE="/etc/pki/trust/anchors/"
    CA_GEN_TRUSTSTORE_CMD="/usr/sbin/update-ca-certificates"
elif [ -d "/etc/pki/ca-trust/source/anchors/" ] && [ -x "/usr/bin/update-ca-trust" ]; then
    # this path is used on RES8
    CA_TRUSTSTORE="/etc/pki/ca-trust/source/anchors/"
    CA_GEN_TRUSTSTORE_CMD="/usr/bin/update-ca-trust"
elif [ -d $CA_TRUSTSTORE ] && [ -x $CA_GEN_TRUSTSTORE_CMD ]; then
    CA_GEN_TRUSTSTORE_CMD="$CA_GEN_TRUSTSTORE_CMD $CA_TRUSTSTORE"
fi

function usage()
{
    cat << EOT >&2

  Usage: $0 <registration URL> [--regcert <url>] [--regdata <filename>] [--de-register]
  Usage: $0 --host <hostname of the RMT server> [--regcert <url>] [--regdata <filename>] [--de-register]
  Usage: $0 --host <hostname of the RMT server> [--fingerprint <fingerprint of server cert>] [--yes] [--regdata <filename>] [--de-register]
         configures a SLE client to register against a different registration server

  Example: $0 https://rmt.example.com/
  Example: $0 --host rmt.example.com --regcert http://rmt.example.com/certs/rmt.crt
EOT

exit 1
}

function http_get_signing_keys_index_html()
{
    local index_html_url=`echo "$REGURL" | awk -F/ '{print "https://" $3 "/repo/keys/"}'`

    $CURL --insecure --silent --fail --output $TMPDIR/index.html $index_html_url

    return $?
}

function parse_index_html()
{
    KEY_FILES=()

    while read line; do
        # This is no substitute for a HTML parser, and probably only works on the index.html generated by RMT
        KEY_FILES+=(`echo $line | sed -n "/href/ s/.*href=['\"]\([^'\"]*\)['\"].*/\1/gp"`)
    done < $TMPDIR/index.html
}

function http_get_key_file()
{
    local key_file_url=`echo "$REGURL/$1" | awk -F/ '{print "https://" $3 "/repo/keys/" $4}'`

    $CURL --silent --fail --output "$TMPDIR/$1" $key_file_url

    return $?
}

function import_key
{
    if [ "$1" == "res-signingkeys.key" ]; then
        # this is no RES system, so we do not need this key
        return
    fi

    local key=$TMPDIR/$1

    mkdir $TMPDIR/.gnupg

    $GPG --no-default-keyring --quiet --no-greeting --no-permission-warning --homedir  $TMPDIR/.gnupg --import $key

    if [ $? -ne 0 ]; then
      rm -rf $TMPDIR/.gnupg/
      return 1
    fi

    $GPG --no-default-keyring --no-greeting --no-permission-warning --homedir $TMPDIR/.gnupg --list-public-keys --with-fingerprint

    if [ "$AUTOACCEPT" = "Y" ]; then
        echo "Accepting key"
    else
        read -p "Trust and import this key? [y/n] " YN
        if [ "$YN" != "Y" -a "$YN" != "y" ]; then
            continue ;
        fi
    fi

    rm -rf $TMPDIR/.gnupg/

    rpm --import $key
}

function import_signing_keys()
{
    TMPDIR=`mktemp -d /tmp/rmtsetup-XXXXXXXX`;

    if [ -z $TMPDIR ]; then
        echo "Cannot create tmpdir for key import in /tmp. Abort."
        exit 1
    fi

    http_get_signing_keys_index_html
    local retcode=$?
    if [ $retcode -eq 0 ]; then
        parse_index_html
        for i in "${KEY_FILES[@]}"; do
            if [[ $i == *.key ]]; then
                http_get_key_file $i
                if [ $? -eq 22 ]; then
                    echo "Custom key '$i' on RMT server is not accessible. Check permissions."
                    continue
                else
                    import_key $i
                fi
            fi
        done
    elif [ $retcode -ne 22 ]; then
      local key_file_url=`echo "$REGURL/$1" | awk -F/ '{print "https://" $3 "/repo/keys/" $4}'`
      echo "An error occurred reading the custom rpm key directory $key_file_url. Please ensure this directory exists, is readable to RMT and contains rpm signing keys if you wish to import custom rpm signing keys."
    fi

    rm -rf $TMPDIR/
}

AUTOACCEPT=""
FINGERPRINT=""
REGDATA=""
REGURL=""
VARIABLE=""
DE_REGISTER=""
while true ; do
    case "$1" in
        --fingerprint) VARIABLE=FINGERPRINT;;
        --host) VARIABLE=S_HOSTNAME;;
        --regcert) VARIABLE=REGCERT;;
        --regdata) VARIABLE=REGDATA;;
        --de-register) DE_REGISTER="Y";;
        --yes) AUTOACCEPT="Y";;
        "") break ;;
        -h|--help) usage;;
        https*) REGURL=$1;;
        *) usage "Unknown option $1";;
    esac
    if [ -n "$VARIABLE" ] ; then
        test -z "$2" && usage "Option $1 needs an argument"
        eval $VARIABLE=\$2
        shift
        VARIABLE=""
    fi
    shift
done

if [ `id -u` != 0 ]; then
    echo "You must be root. Abort."
    exit 1;
fi

if [ -n "$S_HOSTNAME" -a -e $SUSECONNECT ]; then
    REGURL="https://$S_HOSTNAME/"
fi

if [ -z "$REGURL" ]; then
    echo "Missing registration URL. Abort."
    usage
fi

if ! echo $REGURL | grep "^https" > /dev/null ; then
    echo "The registration URL must be a HTTPS URL. Abort."
    exit 1
fi

# BNC #516495: Changing supportconfig URL for uploading tarbals
if [ "${S_HOSTNAME}" != "" ]; then
    if [ -e "${SUPPORTCONFIG}" ]; then
        S_ENTRY="http://${S_HOSTNAME}/upload?appname=supportconfig\&file={tarball}"

        ${SED} --in-place "s|${SUPPORTCONFIGENTRY}[ \t]*=.*$|${SUPPORTCONFIGENTRY}='${S_ENTRY}'|" ${SUPPORTCONFIG}
    fi
fi

if [ -z "$REGCERT" ]; then
    CERTURL=`echo "$REGURL" | awk -F/ '{print "https://" $3 "/rmt.crt"}'`
else
    CERTURL="$REGCERT"
fi

if [ "$AUTOACCEPT" = "Y" ] && [ -z "$FINGERPRINT" ]; then
    echo "Must specify fingerprint with auto accept and auto registration. Abort."
    exit 1
fi

if [ ! -z "$REGDATA" ] && [ ! -f "$REGDATA" ]; then
    echo "Specified file $REGDATA not found."
    exit 1
fi


if [ ! -x $OPENSSL ]; then
    echo "openssl command not found. Abort."
    exit 1
fi

if [ ! -x $CP ]; then
    echo "cp command not found. Abort."
    exit 1
fi

if [ ! -x $CAT ]; then
    echo "cat command not found. Abort."
    exit 1
fi

if [ "$AUTOACCEPT" = "Y" ] && [ ! -x $CUT ]; then
    echo "cut command not found. Abort."
    exit 1
fi

if [ ! -x $GREP ]; then
    if [ -x "/bin/grep" ]; then
        GREP=/bin/grep
    else
        echo "grep command not found. Abort."
        exit 1
    fi
fi

if [ ! -x $RM ]; then
    echo "rm command not found. Abort."
    exit 1
fi

if [ ! -x $CHMOD ]; then
    echo "chmod command not found. Abort."
    exit 1
fi

if [ ! -x $SUSECONNECT ]; then
    echo "registration command not found. Abort."
    exit 1
fi

if [ -x "$SUSECONNECT" ] && [ -e /etc/zypp/credentials.d/SCCcredentials ]; then
    if [ -n "$DE_REGISTER" ]; then
        echo "De-registering system..."
        $SUSECONNECT --de-register
        $SUSECONNECT --cleanup
    else
        echo "The system is already registered. Please de-register first by calling:"
        echo "$> SUSEConnect --de-register"
        echo "$> SUSEConnect --cleanup"
        exit 1
    fi
fi

if [ ! -x $GPG ]; then
    echo "gpg command not found. Abort."
    exit 1
fi


TEMPFILE=`mktemp /tmp/rmt.crt.XXXXXX`

if [ -x $CURL ]; then
    $CURL --tlsv1.2 --silent --insecure --connect-timeout 10 --output $TEMPFILE $CERTURL
    if [ $? -ne 0 ]; then
        echo "Download failed. Abort."
        exit 1
    fi
else
    download_tool_basename=$(basename $CURL)
    echo "Binary to download the certificate not found. Please install $download_tool_basename. Abort."
    exit 1
fi

if [ "$AUTOACCEPT" = "Y" ]; then
    SFPRINT=`/usr/bin/openssl x509 -in $TEMPFILE -noout -fingerprint | /usr/bin/cut -d= -f2`
    MATCH=`/usr/bin/awk -vs1="$SFPRINT" -vs2="$FINGERPRINT" 'BEGIN { if ( tolower(s1) == tolower(s2) ){ print 1 } }'`
    if [ "$MATCH" != "1" ]; then
        echo "Server fingerprint: $SFPRINT and given fingerprint:  $FINGERPRINT do not match, not accepting cert. Abort."
        exit 1
    fi
else

    $OPENSSL x509 -in $TEMPFILE -text -noout

    read -p "Do you accept this certificate? [y/n] " YN

    if [ "$YN" != "Y" -a "$YN" != "y" ]; then
        echo "Abort."
        exit 1
    fi
fi

if [ -d $CA_TRUSTSTORE ]; then
    $CP $TEMPFILE $CA_TRUSTSTORE/rmt-server.pem
    $CHMOD 0644 $CA_TRUSTSTORE/rmt-server.pem

    $CA_GEN_TRUSTSTORE_CMD > /dev/null
fi

rm -f $TEMPFILE

import_signing_keys

echo "Client setup finished."

if [ -z "$AUTOACCEPT" ]; then
    read -p "Start the registration now? [y/n] " YN

    if [ "$YN" != "Y" -a "$YN" != "y" ]; then
        exit 0;
    fi
fi

if [ -x "$SUSECONNECT" ]; then
    echo "$SUSECONNECT --write-config --url $REGURL $NAMESPACE"
    $SUSECONNECT --write-config --url $REGURL $NAMESPACE
else
    echo "No SUSEConnect registration client found."
    exit 1
fi