From d279ea84aa33ebb0ecb2e540a7ff06ab25400a05 Mon Sep 17 00:00:00 2001 From: "Guilherme G. Piccoli" Date: Wed, 23 Feb 2022 16:25:13 -0300 Subject: [PATCH] kdump.etc, submit-report.sh: Enhance Steam ID/Account obtaining Currently we hardcode the account-related VDF file path in kdump, and expose it in "/etc/default/kdump" - this is unnecessary since this path is not expected to change nor users to mess with it; thanks Emil (@xexaxo) for this suggestion. So, this patch improves things in some ways: (a) Do not expose VDF path or Valve's server URL in user configurable file - no reasons for users to mess with that. (b) Generate "/home" mount point based on DEVNODE, also determine the username based on "getent'ing" the passwd database. See CAVEAT below. (c) Move the VDF parsing to a separate function to clean up the submit log path on submit-report.sh . No functional change is expected after this commit. CAVEAT: Notice that "getent passwd" is *VERY* slow, and if we follow a generic approach of doing it for UID_MIN..UID_MAX, it takes quite some time. So, instead we simplify and just query the user 1000; this might be a bit incomplete, but it's still better than hardcoding a username as it's done until now. Signed-off-by: Guilherme G. Piccoli --- README.md | 3 +- kdump.etc | 6 ---- submit-report.sh | 73 ++++++++++++++++++++++++++++++++---------------- 3 files changed, 50 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index 382c363..cdc6801 100644 --- a/README.md +++ b/README.md @@ -161,8 +161,7 @@ # => The API details: it works by a first POST request to Valve servers, # which, when succeed, returns 3 main components in the response. We use # these values to perform a PUT request with the ZIP compressed file, and -# finally a last POST request is necessary to finish the transaction. The -# POST requests' URL is present in "/etc/default/kdump". +# finally a last POST request is necessary to finish the transaction. # Below, the specific format of such requests: # # The first POST takes the following fields: diff --git a/kdump.etc b/kdump.etc index 6c8e0a3..7369e64 100644 --- a/kdump.etc +++ b/kdump.etc @@ -43,9 +43,3 @@ USE_PSTORE_RAM=1 # Setting LOG_SUBMISSION to '0' will disable this behavior; but notice that # even with the log submission disabled, the logs are saved locally. LOG_SUBMISSION=1 - -# Below some log submission settings, based on Steam config files and Valve -# URLs. These settings *should not* be changed, or else the log sending -# mechanism will be impaired. -LOGINVDF="/home/doorstop/.local/share/Steam/config/loginusers.vdf" -POST_URL="https://api.steampowered.com/ICrashReportService/ACTIONCrashUpload/v1" diff --git a/submit-report.sh b/submit-report.sh index e0f9ca1..8a159e5 100644 --- a/submit-report.sh +++ b/submit-report.sh @@ -22,6 +22,50 @@ save_locally_and_bail() { exit 0 } +# Next function is used to get Steam Account/ID from the VDF file for +# the current user; in case it fails, STEAM_ID and STEAM_ACCOUNT vars +# aren't updated. +# Arg1: devnode information to determine the /home mount point. + +get_steam_account_id() { + # Step 1: get the /home mount point. + HOMEFLD="$(findmnt "$1" -fno TARGET)" + + # Step 2: determine the username; notice that + # UID_MIN = 1000, UID_MAX = 60000 from "/etc/login.defs", but + # getent takes long time to check all of them, so we restrict + # to UID = 1000 only. + USERN="$(getent passwd 1000 | cut -f1 -d:)" + + # Let's determine the VDF file location using the above info. + LOGINVDF="${HOMEFLD}/${USERN}/.local/share/Steam/config/loginusers.vdf" + if [ ! -s "${LOGINVDF}" ]; then # bail if no valid VDF is found. + return + fi + + # Step 3: Parse the VDF file to obtain Account/ID; the following AWK + # command was borrowed from: https://unix.stackexchange.com/a/663959. + NUMREG=$(grep -c AccountName "${LOGINVDF}") + IDX=1 + while [ ${IDX} -le "${NUMREG}" ]; do + MR=$(awk -v n=${IDX} -v RS='}' 'NR==n{gsub(/.*\{\n|\n$/,""); print}' "${LOGINVDF}" | grep "MostRecent" | cut -f4 -d\") + if [ "$MR" -ne 1 ]; then + IDX=$((IDX + 1)) + continue + fi + + STEAM_ACCOUNT=$(awk -v n=${IDX} -v RS='}' 'NR==n{gsub(/.*\{\n|\n$/,""); print}' "${LOGINVDF}" | grep "AccountName" | cut -f4 -d\") + + # Get also the Steam ID, used in the POST request to Valve servers; this + # is a bit fragile, but there's no proper VDF parse tooling it seems... + LN=$(grep -n "AccountName.*${STEAM_ACCOUNT}\"" "${LOGINVDF}" | cut -f1 -d:) + LN=$((LN - 2)) + STEAM_ID=$(sed -n "${LN}p" "${LOGINVDF}" | cut -f2 -d\") + break + done +} + + # We do some validation to be sure KDUMP_MNT pointed path is valid... # That and having a valid /etc/default/kdump are essential conditions. if [ ! -s "/etc/default/kdump" ]; then @@ -128,28 +172,7 @@ if [ ${LOGS_FOUND} -ne 0 ]; then STEAM_ACCOUNT=0 STEAM_ID=0 - if [ -s "${LOGINVDF}" ]; then - # The following awk command was borrowed from: - # https://unix.stackexchange.com/a/663959 - NUMREG=$(grep -c AccountName "${LOGINVDF}") - IDX=1 - while [ ${IDX} -le "${NUMREG}" ]; do - MR=$(awk -v n=${IDX} -v RS='}' 'NR==n{gsub(/.*\{\n|\n$/,""); print}' "${LOGINVDF}" | grep "MostRecent" | cut -f4 -d\") - if [ "$MR" -ne 1 ]; then - IDX=$((IDX + 1)) - continue - fi - - STEAM_ACCOUNT=$(awk -v n=${IDX} -v RS='}' 'NR==n{gsub(/.*\{\n|\n$/,""); print}' "${LOGINVDF}" | grep "AccountName" | cut -f4 -d\") - - # Get also the Steam ID, used in the POST request to Valve servers; this - # is a bit fragile, but there's no proper VDF parse tooling it seems... - LN=$(grep -n "AccountName.*${STEAM_ACCOUNT}\"" "${LOGINVDF}" | cut -f1 -d:) - LN=$((LN - 2)) - STEAM_ID=$(sed -n "${LN}p" "${LOGINVDF}" | cut -f2 -d\") - break - done - fi + get_steam_account_id "${MOUNT_DEVNODE}" # Here we collect some more info, like DMI data, os-release, etc; # TODO: Add Steam application / Proton / Games logs collection... @@ -237,9 +260,11 @@ if [ ${LOGS_FOUND} -ne 0 ]; then save_locally_and_bail "${NOT_SENT_FLD}" "${LOG_FNAME}" fi + # These URLs are hardcoded based on Valve's server information. + START_URL="https://api.steampowered.com/ICrashReportService/StartCrashUpload/v1" + FINISH_URL="https://api.steampowered.com/ICrashReportService/FinishCrashUpload/v1" + CURL_ERR="${KDUMP_MAIN_FOLDER}/.curl_err" - START_URL="$(echo "${POST_URL}" | sed 's/ACTION/Start/g')" - FINISH_URL="$(echo "${POST_URL}" | sed 's/ACTION/Finish/g')" RESPONSE_FILE="${KDUMP_MAIN_FOLDER}/.curl_response" if ! curl -X POST -d "${POST_REQ}" "${START_URL}" 1>"${RESPONSE_FILE}" 2>"${CURL_ERR}"; then