From 26c51824c8330b026f261a3205f94958d4b1bc5c Mon Sep 17 00:00:00 2001 From: Antonio Aversa Date: Tue, 17 Dec 2024 09:19:42 +0100 Subject: [PATCH] SQSCANGHA-76 Support self-hosted runners not clearing truststore after run (#165) --- .github/workflows/qa-main.yml | 136 ++++++++++++++++++++++++++++++- README.md | 2 +- scripts/run-sonar-scanner-cli.sh | 52 ++++++++++-- 3 files changed, 179 insertions(+), 11 deletions(-) diff --git a/.github/workflows/qa-main.yml b/.github/workflows/qa-main.yml index 6427f00..65f3558 100644 --- a/.github/workflows/qa-main.yml +++ b/.github/workflows/qa-main.yml @@ -619,9 +619,9 @@ jobs: - name: Assert failure of previous step if: steps.wrong_ssl_certificate.outcome == 'success' run: exit 1 - overridesScannerLocalFolderWhenPresent: + overridesScannerLocalFolderWhenPresent: # can happen in uncleaned self-hosted runners name: > - 'SCANNER_LOCAL_FOLDER' is overridden with warning when present + 'SCANNER_LOCAL_FOLDER' is cleaned with warning when present runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -643,9 +643,9 @@ jobs: - name: Run action with SONAR_SCANNER_TEMP uses: ./ env: + NO_CACHE: true # force install-sonar-scanner-cli.sh execution SONAR_SCANNER_TEMP: /tmp/sonar-scanner SONAR_HOST_URL: http://not_actually_used - NO_CACHE: true # force install-sonar-scanner-cli.sh execution with: args: -Dsonar.scanner.internal.dumpToFile=./output.properties scannerVersion: ${{ env.SCANNER_VERSION }} @@ -653,4 +653,132 @@ jobs: run: | [ -d "$SCANNER_LOCAL_FOLDER" ] || exit 1 [ ! -f "$SCANNER_LOCAL_FOLDER/some_content.txt" ] || exit 1 - + updateTruststoreWhenPresent: # can happen in uncleaned self-hosted runners + name: > + truststore.p12 is updated when present + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} + - name: Create SONAR_SSL_FOLDER with a file in it (not-truststore.p12) + run: | + SONAR_SSL_FOLDER=~/.sonar/ssl + mkdir -p "$SONAR_SSL_FOLDER" + touch "$SONAR_SSL_FOLDER/not-truststore.p12" + # emit SONAR_SSL_FOLDER to be able to read it in the next steps + echo "SONAR_SSL_FOLDER=$SONAR_SSL_FOLDER" >> $GITHUB_ENV + - name: Assert truststore.p12 does not file exists + run: | + [ ! -f "$SONAR_SSL_FOLDER/truststore.p12" ] || exit 1 + - name: Run action with SONAR_ROOT_CERT + uses: ./ + env: + # NO_CACHE not needed, as SONAR_SSL_FOLDER is setup when the Sonar Scanner is run, not installed + SONAR_HOST_URL: http://not_actually_used + SONAR_ROOT_CERT: | + -----BEGIN CERTIFICATE----- + MIIFlTCCA32gAwIBAgIUXK4LyGUFe4ZVL93StPXCoJzmnLMwDQYJKoZIhvcNAQEL + BQAwTzELMAkGA1UEBhMCQ0gxDzANBgNVBAgMBkdlbmV2YTEPMA0GA1UEBwwGR2Vu + ZXZhMQ8wDQYDVQQKDAZTZXJ2ZXIxDTALBgNVBAsMBERlcHQwHhcNMjQxMTAxMDgx + MzM3WhcNMzQxMDMwMDgxMzM3WjBPMQswCQYDVQQGEwJDSDEPMA0GA1UECAwGR2Vu + ZXZhMQ8wDQYDVQQHDAZHZW5ldmExDzANBgNVBAoMBlNlcnZlcjENMAsGA1UECwwE + RGVwdDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK5m0V6IFFykib77 + nmlN7weS9q3D6YGEj+8hRNQViL9KduUoLjoKpONIihU5kfIg+5SkGygjHRkBvIp3 + b0HQqhkwtGln3/FxxaSfGEguLHgzXR8JDQSyJ8UKIGOPCH93n1rUip5Ok1iExVup + HtkiVDRoCC9cRjZXbGOKrO6VBT4RvakpkaqCdXYikV244B5ElM7kdFdz8fso78Aq + xekb9dM0f21uUaDBKCIhRcxWeafp0CJIoejTq0+PF7qA2qIY5UHqWElWO5NsvQ8+ + MqKkIdsOa1pYNuH/5eQ59k9KSE92ps1xTKweW000GfPqxx8IQ/e4aAd2SaMTKvN6 + aac6piWBeJ7AssgWwkg/3rnZB5seQIrWjIUePmxJ4c0g0eL9cnVpYF0K/Dldle/G + wg0zi1g709rBI1TYj9xwrivxSwEQupz8OdKqOmgqrKHJJ/CCLl+JdFYjgwl3NWLH + wsU639H1bMXIJoQujg9U47e9fXbwiqdkMQzt7rPGkOBBaAkSctAReiXnWy+CbVEM + QFHDrnD5YUJRd5t/DUuWuqhR2QhfUvRClPUKoVqB/iOu2IumlgDEDA8jb1dxEW+W + iaYokQCS94OpxOJ8aeReSt9bghT0vc9ifCLWvuE1iBjujdK32ekKSY9DCZyBHXsG + J9N1nt1qd/k7QqWOkuPjr1JrTIMbAgMBAAGjaTBnMB0GA1UdDgQWBBQw4ESReEk+ + AIxwjHRqPkESzMv1bTAfBgNVHSMEGDAWgBQw4ESReEk+AIxwjHRqPkESzMv1bTAP + BgNVHRMBAf8EBTADAQH/MBQGA1UdEQQNMAuCCWxvY2FsaG9zdDANBgkqhkiG9w0B + AQsFAAOCAgEAE8WefoZN23aOSe79ZN7zRBWP8DdPgFAqg5XUhfc9bCIVfJ4XMpEe + 3lzRhgjwDm4naEs35QWOhPZH2vx8XrEKnZNI6vKO8JzaCsivgngk8bsWnvhwSXy5 + eFdc99K+FOmOHevDmeiimoQnikffnSULRhQYzE2Qwyo9iky8703/+D3IKEC/8exC + rlyGMUV/Nqj+4M+57DiZ6OXeFuunfoFB7vmcDZygqDhKoHhVRyu8qN6PeK2fvUFK + EjeRtvA0GkdlOtLIF2g5yBTK2ykkt/oLUoAolfYUTKcoV2/FS0gVR5ovmEpKyBcP + H9hzr16a8dtrEqOf/oKHQSLwxn8afmS354HJ75sq9SujOtIWpHfyH5IgqtUpiBN/ + bzvKs/QZjtGlqvquOTkdh9L4oxTXqG7zEStZyo/v9g5jf1Tq195b2DNFwVUZIcbb + u2d4CvAZ1yNr+8ax/kTwBSY8WU+mCtmvowFstdvsJXVXJKnUO6EZOdbg0GxTBVyE + zMsnPcnkOwV5TJIKKhonrgrwmPmQ9IOV9BrThVxujjjEbAdA6jM9PMiXzuDukldm + QBRwNbczGbdsHkMKHmQnrTqOyQyI4KCXF08kcOm4C1P+Whrvi0DXkqHnyKvBE0td + dciInBoeHwUs2eclz7gP7pMBJUlFUkKfQxwxGLIqZSXnlAFBfW6hHLI= + -----END CERTIFICATE----- + with: + args: -Dsonar.scanner.internal.dumpToFile=./output.properties + - name: Assert not-truststore.p12 file still exists + run: | + [ -f "$SONAR_SSL_FOLDER/not-truststore.p12" ] || exit 1 + - name: Assert truststore.p12 file now exists and take note of modification time + run: | + [ -f "$SONAR_SSL_FOLDER/truststore.p12" ] || exit 1 + # emit the modification time of the truststore.p12 file to be able to read it in the next steps + TRUSTSTORE_P12_MOD_TIME_T1=$(stat -c %Y "$SONAR_SSL_FOLDER/truststore.p12") + echo "TRUSTSTORE_P12_MOD_TIME_T1=$TRUSTSTORE_P12_MOD_TIME_T1" >> $GITHUB_ENV + - name: Run action a second time with a different SONAR_ROOT_CERT + uses: ./ + env: + # NO_CACHE not needed, as SONAR_SSL_FOLDER is setup when the Sonar Scanner is run, not installed + SONAR_HOST_URL: http://not_actually_used + SONAR_ROOT_CERT: | + -----BEGIN CERTIFICATE----- + MIICgTCCAeoCCQCbOlrWDdX7FTANBgkqhkiG9w0BAQUFADCBhDELMAkGA1UEBhMC + Tk8xGDAWBgNVBAgTD0FuZHJlYXMgU29sYmVyZzEMMAoGA1UEBxMDRm9vMRAwDgYD + VQQKEwdVTklORVRUMRgwFgYDVQQDEw9mZWlkZS5lcmxhbmcubm8xITAfBgkqhkiG + 9w0BCQEWEmFuZHJlYXNAdW5pbmV0dC5ubzAeFw0wNzA2MTUxMjAxMzVaFw0wNzA4 + MTQxMjAxMzVaMIGEMQswCQYDVQQGEwJOTzEYMBYGA1UECBMPQW5kcmVhcyBTb2xi + ZXJnMQwwCgYDVQQHEwNGb28xEDAOBgNVBAoTB1VOSU5FVFQxGDAWBgNVBAMTD2Zl + aWRlLmVybGFuZy5ubzEhMB8GCSqGSIb3DQEJARYSYW5kcmVhc0B1bmluZXR0Lm5v + MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDivbhR7P516x/S3BqKxupQe0LO + NoliupiBOesCO3SHbDrl3+q9IbfnfmE04rNuMcPsIxB161TdDpIesLCn7c8aPHIS + KOtPlAeTZSnb8QAu7aRjZq3+PbrP5uW3TcfCGPtKTytHOge/OlJbo078dVhXQ14d + 1EDwXJW1rRXuUt4C8QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBACDVfp86HObqY+e8 + BUoWQ9+VMQx1ASDohBjwOsg2WykUqRXF+dLfcUH9dWR63CtZIKFDbStNomPnQz7n + bK+onygwBspVEbnHuUihZq3ZUdmumQqCw4Uvs/1Uvq3orOo/WJVhTyvLgFVK2Qar + Q4/67OZfHd7R+POBXhophSMv1ZOo + -----END CERTIFICATE----- + with: + args: -Dsonar.scanner.internal.dumpToFile=./output.properties + - name: Assert truststore.p12 still exists, but it has been updated, and take note of modification time + run: | + [ -f "$SONAR_SSL_FOLDER/truststore.p12" ] || exit 1 + TRUSTSTORE_P12_MOD_TIME_T2=$(stat -c %Y "$SONAR_SSL_FOLDER/truststore.p12") + [ "$TRUSTSTORE_P12_MOD_TIME_T1" != "$TRUSTSTORE_P12_MOD_TIME_T2" ] || exit 1 + # emit the modification time of the truststore.p12 file to be able to read it in the next steps + echo "TRUSTSTORE_P12_MOD_TIME_T2=$TRUSTSTORE_P12_MOD_TIME_T2" >> $GITHUB_ENV + - name: Remove sonar alias from truststore.p12 + run: keytool -delete -alias sonar -keystore "$SONAR_SSL_FOLDER/truststore.p12" -storepass changeit + - name: Run action a third time + uses: ./ + env: + # NO_CACHE not needed, as SONAR_SSL_FOLDER is setup when the Sonar Scanner is run, not installed + SONAR_HOST_URL: http://not_actually_used + SONAR_ROOT_CERT: | + -----BEGIN CERTIFICATE----- + MIICgTCCAeoCCQCbOlrWDdX7FTANBgkqhkiG9w0BAQUFADCBhDELMAkGA1UEBhMC + Tk8xGDAWBgNVBAgTD0FuZHJlYXMgU29sYmVyZzEMMAoGA1UEBxMDRm9vMRAwDgYD + VQQKEwdVTklORVRUMRgwFgYDVQQDEw9mZWlkZS5lcmxhbmcubm8xITAfBgkqhkiG + 9w0BCQEWEmFuZHJlYXNAdW5pbmV0dC5ubzAeFw0wNzA2MTUxMjAxMzVaFw0wNzA4 + MTQxMjAxMzVaMIGEMQswCQYDVQQGEwJOTzEYMBYGA1UECBMPQW5kcmVhcyBTb2xi + ZXJnMQwwCgYDVQQHEwNGb28xEDAOBgNVBAoTB1VOSU5FVFQxGDAWBgNVBAMTD2Zl + aWRlLmVybGFuZy5ubzEhMB8GCSqGSIb3DQEJARYSYW5kcmVhc0B1bmluZXR0Lm5v + MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDivbhR7P516x/S3BqKxupQe0LO + NoliupiBOesCO3SHbDrl3+q9IbfnfmE04rNuMcPsIxB161TdDpIesLCn7c8aPHIS + KOtPlAeTZSnb8QAu7aRjZq3+PbrP5uW3TcfCGPtKTytHOge/OlJbo078dVhXQ14d + 1EDwXJW1rRXuUt4C8QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBACDVfp86HObqY+e8 + BUoWQ9+VMQx1ASDohBjwOsg2WykUqRXF+dLfcUH9dWR63CtZIKFDbStNomPnQz7n + bK+onygwBspVEbnHuUihZq3ZUdmumQqCw4Uvs/1Uvq3orOo/WJVhTyvLgFVK2Qar + Q4/67OZfHd7R+POBXhophSMv1ZOo + -----END CERTIFICATE----- + with: + args: -Dsonar.scanner.internal.dumpToFile=./output.properties + - name: Assert truststore.p12 still exists, and it has been updated again + run: | + [ -f "$SONAR_SSL_FOLDER/truststore.p12" ] || exit 1 + TRUSTSTORE_P12_MOD_TIME_T3=$(stat -c %Y "$SONAR_SSL_FOLDER/truststore.p12") + [ "$TRUSTSTORE_P12_MOD_TIME_T2" != "$TRUSTSTORE_P12_MOD_TIME_T3" ] || exit 1 diff --git a/README.md b/README.md index 7ac12c6..b568645 100644 --- a/README.md +++ b/README.md @@ -294,7 +294,7 @@ If your source code file names contain special characters that are not covered b LC_ALL: "ru_RU.UTF-8" ``` -## Alternatives for Java, .NET, and C/C++ projects +## Alternatives for Java and .NET This GitHub Action will not work for all technologies. If you are in one of the following situations, you should use the following alternatives: diff --git a/scripts/run-sonar-scanner-cli.sh b/scripts/run-sonar-scanner-cli.sh index 14caadc..1a77f07 100755 --- a/scripts/run-sonar-scanner-cli.sh +++ b/scripts/run-sonar-scanner-cli.sh @@ -21,16 +21,56 @@ if [[ -n "${INPUT_PROJECTBASEDIR}" ]]; then scanner_args+=("-Dsonar.projectBaseDir=${INPUT_PROJECTBASEDIR}") fi +# The SSL folder may exist on an uncleaned self-hosted runner +SONAR_SSL_FOLDER=~/.sonar/ssl +# Use keytool for now, as SonarQube 10.6 and below doesn't support openssl generated keystores +# keytool requires a password > 6 characters, so we won't use the default password 'sonar' +KEYTOOL_MAIN_CLASS=sun.security.tools.keytool.Main +SONAR_SSL_TRUSTSTORE_FILE="$SONAR_SSL_FOLDER/truststore.p12" +SONAR_SSL_TRUSTSTORE_PASSWORD=changeit + +if [ -f "$SONAR_SSL_TRUSTSTORE_FILE" ]; then + ALIAS_SONAR_IS_PRESENT=true + + "$SONAR_SCANNER_JRE/bin/java" "$KEYTOOL_MAIN_CLASS" \ + -storetype PKCS12 \ + -keystore "$SONAR_SSL_TRUSTSTORE_FILE" \ + -storepass "$SONAR_SSL_TRUSTSTORE_PASSWORD" \ + -noprompt \ + -trustcacerts \ + -list -v -alias sonar > /dev/null 2>&1 || { + ALIAS_SONAR_IS_PRESENT=false + echo "Existing Scanner truststore $SONAR_SSL_TRUSTSTORE_FILE does not contain 'sonar' alias" + } + + if [[ $ALIAS_SONAR_IS_PRESENT == "true" ]]; then + echo "Removing 'sonar' alias from already existing Scanner truststore: $SONAR_SSL_TRUSTSTORE_FILE" + "$SONAR_SCANNER_JRE/bin/java" "$KEYTOOL_MAIN_CLASS" \ + -storetype PKCS12 \ + -keystore "$SONAR_SSL_TRUSTSTORE_FILE" \ + -storepass "$SONAR_SSL_TRUSTSTORE_PASSWORD" \ + -noprompt \ + -trustcacerts \ + -delete \ + -alias sonar + fi +fi + if [[ -n "${SONAR_ROOT_CERT}" ]]; then echo "Adding SSL certificate to the Scanner truststore" rm -f $RUNNER_TEMP/tmpcert.pem echo "${SONAR_ROOT_CERT}" > $RUNNER_TEMP/tmpcert.pem - # Use keytool for now, as SonarQube 10.6 and below doesn't support openssl generated keystores - # keytool require a password > 6 characters, so we wan't use the default password 'sonar' - store_pass=changeit - mkdir -p ~/.sonar/ssl - $SONAR_SCANNER_JRE/bin/java sun.security.tools.keytool.Main -storetype PKCS12 -keystore ~/.sonar/ssl/truststore.p12 -storepass $store_pass -noprompt -trustcacerts -importcert -alias sonar -file $RUNNER_TEMP/tmpcert.pem - scanner_args+=("-Dsonar.scanner.truststorePassword=$store_pass") + mkdir -p "$SONAR_SSL_FOLDER" + "$SONAR_SCANNER_JRE/bin/java" "$KEYTOOL_MAIN_CLASS" \ + -storetype PKCS12 \ + -keystore "$SONAR_SSL_TRUSTSTORE_FILE" \ + -storepass "$SONAR_SSL_TRUSTSTORE_PASSWORD" \ + -noprompt \ + -trustcacerts \ + -importcert \ + -alias sonar \ + -file "$RUNNER_TEMP/tmpcert.pem" + scanner_args+=("-Dsonar.scanner.truststorePassword=$SONAR_SSL_TRUSTSTORE_PASSWORD") fi scanner_args+=("$@")