Skip to content

Instantly share code, notes, and snippets.

@catchdave
Last active November 5, 2024 01:02
Show Gist options
  • Select an option

  • Save catchdave/ff9c7d7a396a3201cfb14f912d3e5cda to your computer and use it in GitHub Desktop.

Select an option

Save catchdave/ff9c7d7a396a3201cfb14f912d3e5cda to your computer and use it in GitHub Desktop.

Revisions

  1. catchdave revised this gist Nov 5, 2024. 1 changed file with 6 additions and 7 deletions.
    13 changes: 6 additions & 7 deletions find_all_certs.sh
    Original file line number Diff line number Diff line change
    @@ -24,7 +24,6 @@ HEAD_COL="\033[0;97m\033[0;100m"
    # Initialize variables
    NOW_TS=$(date +%s)
    BASE_DIR=/usr/
    #BASE_DIR=/usr/lib/python3.8/site-packages/certifi
    WARNINGS=()
    PREV_DIR=""
    valid_count=0
    @@ -97,8 +96,8 @@ get_line_format() {
    local start=$1
    local mid=$2
    local end=$3
    local color_line=$4
    local color_status=$5
    local color_line="${4:-}"
    local color_status="${5:-}"

    local line_format="__START__LINE_COLOR %-44s __MID__ STATUS_COLOR%-28s${NC}LINE_COLOR __MID__ \
    STATUS_COLOR%-28s${NC}LINE_COLOR __MID__ %-20s __MID__ %-20s __MID__ STATUS_COLOR%-7s ${NC}__END__\n"
    @@ -115,7 +114,7 @@ STATUS_COLOR%-28s${NC}LINE_COLOR __MID__ %-20s __MID__ %-20s __MID__ STATUS_COLO
    # Skip files that are not valid certificates
    check_valid_cert() {
    local cert=$1
    if [[ ! "$(head -n 1 "$cert")" == "-----BEGIN CERTIFICATE-----" ]]; then
    if [[ "$(head -n 1 "$cert")" != "-----BEGIN CERTIFICATE-----" ]]; then
    return 1
    fi
    return 0
    @@ -138,10 +137,10 @@ print_cert_line() {
    }

    print_dir_warn() {
    [[ "$count" -ne 0 && "$valid_count" -eq 0 ]] && {
    if [[ "${count:-0}" -ne 0 && "${valid_count:-0}" -eq 0 ]]; then
    WARNINGS+=("$(echo -e "${RED}${BOLD}[WARN] No Valid Certs in: ${NC}${RED}$1/${NC}")")
    ((total_dirs_no_valid++))
    }
    fi
    }

    print_header() {
    @@ -225,4 +224,4 @@ parse_cert_info() {
    }

    ### Run main program ###
    main "$@"
    main "$@"
  2. catchdave revised this gist Nov 4, 2024. 1 changed file with 94 additions and 53 deletions.
    147 changes: 94 additions & 53 deletions find_all_certs.sh
    Original file line number Diff line number Diff line change
    @@ -19,12 +19,14 @@ YELLOW="\033[0;33m"
    BLUE="\033[0;95m"
    NC="\033[0m" # No Color
    BOLD="\033[1m"
    HEAD_COL="\033[1;97m\033[1;100m"
    HEAD_COL="\033[0;97m\033[0;100m"

    # Initialize variables
    NOW_TS=$(date +%s)
    BASE_DIR=/usr/
    prev_dir=""
    #BASE_DIR=/usr/lib/python3.8/site-packages/certifi
    WARNINGS=()
    PREV_DIR=""
    valid_count=0
    count=0
    total_count=0
    @@ -34,19 +36,35 @@ total_dirs_no_valid=0
    total_dirs=0
    valid_status=
    mode=all
    color=1

    main() {
    parse_args "$@"

    print_header
    while read -r cert; do
    cert_dir=$(dirname "$cert")
    cert_file=$(basename "$cert")

    if parse_cert_info "$cert"; then # Sets vars: $from, $to, $subject, $issuer, $validity_color & $valid_status
    process_dir_change "$cert_dir" "$cert_file"
    ((count++))
    ((total_count++))

    check_filter "$valid_status" || continue
    print_cert_line "$validity_color" "$cert_file" "$from" "$to" "$subject" "$issuer" "$valid_status"
    fi
    done < <(find "$BASE_DIR" -type f -name "*.pem" -not -path "/volume*" 2>/dev/null)

    printf "$(get_line_format "\u2517" "\u2537" "\u251B")" | sed 's/ /━/g'
    print_summary
    }

    parse_args() {
    while [[ $# -gt 0 ]]; do
    case "$1" in
    --no-color)
    GREEN=
    RED=
    YELLOW=
    BLUE=
    NC=
    BOLD=
    HEAD_COL=

    color=0
    shift
    ;;
    --valid-only)
    @@ -63,32 +81,35 @@ parse_args() {
    ;;
    esac
    done
    }

    main() {
    parse_args "$@"

    print_header
    while read -r cert; do
    cert_dir=$(dirname "$cert")
    cert_file=$(basename "$cert")
    if [[ "$color" == "0" ]]; then
    GREEN=
    RED=
    YELLOW=
    BLUE=
    NC=
    BOLD=
    HEAD_COL=
    fi
    }

    check_valid_cert "$cert" || continue
    get_line_format() {
    local start=$1
    local mid=$2
    local end=$3
    local color_line=$4
    local color_status=$5

    # Print the directory heading if it's new
    if [[ "$cert_dir" != "$prev_dir" ]]; then
    process_dir_change
    fi
    ((count++))
    ((total_count++))
    local line_format="__START__LINE_COLOR %-44s __MID__ STATUS_COLOR%-28s${NC}LINE_COLOR __MID__ \
    STATUS_COLOR%-28s${NC}LINE_COLOR __MID__ %-20s __MID__ %-20s __MID__ STATUS_COLOR%-7s ${NC}__END__\n"
    line_format="${line_format//__START__/${start}}"
    line_format="${line_format//__MID__/${mid}}"
    line_format="${line_format//__END__/${end}}"

    parse_cert_info "$cert" # Sets the vars: $from, $to, $subject, $issuer, $validity_color & $valid_status
    check_filter "$valid_status" || continue
    print_cert_line "$validity_color" "$cert_file" "$from" "$to" "$subject" "$issuer"
    done < <(find "$BASE_DIR" -type f -name "*.pem" -not -path "/volume*" 2>/dev/null)
    line_format="${line_format//STATUS_COLOR/${color_status}}"
    line_format="${line_format//LINE_COLOR/${color_line}}"

    print_dir_warn "$cert_dir"
    print_summary
    echo "$line_format"
    }

    # Skip files that are not valid certificates
    @@ -103,61 +124,77 @@ check_valid_cert() {
    # Execute filtering based on mode
    check_filter() {
    local valid_status=$1
    if [[ "$mode" == "valid_only" && "$valid_status" == "invalid" ]]; then
    if [[ "$mode" == "valid_only" && "$valid_status" != "active" ]]; then
    return 1
    elif [[ "$mode" == "invalid_only" && "$valid_status" == "valid" ]]; then
    elif [[ "$mode" == "invalid_only" && "$valid_status" == "active" ]]; then
    return 1
    fi
    return 0
    }

    print_cert_line() {
    local color=$1
    LINE_FORMAT="| %-44s | COLOR%-28s${NC} | COLOR%-28s${NC} | %-20s | %-30s |\n"

    cur_format="${LINE_FORMAT//COLOR/${color}}"
    printf "$cur_format" "$2" "$3" "$4" "$5" "$6"
    print_cert_line() {
    printf "$(get_line_format "\u2503" "\u2502" "\u2503" "" "$1")" "$2" "$3" "$4" "$5" "$6" "$7"
    }

    print_dir_warn() {
    [[ "$count" -ne 0 && "$valid_count" -eq 0 ]] && {
    echo -e "${RED}${BOLD}[WARN] No Valid Certs in: ${NC}${RED}$1/${NC}"
    WARNINGS+=("$(echo -e "${RED}${BOLD}[WARN] No Valid Certs in: ${NC}${RED}$1/${NC}")")
    ((total_dirs_no_valid++))
    }
    }

    print_header() {
    LINE_FORMAT="${HEAD_COL}| %-44s | %-28s | %-28s | %-20s | %-30s |${NC}\n"
    printf "$LINE_FORMAT" "Filename" "Valid From" "Valid To" "Domain" "Issuer"
    printf "$(get_line_format "\u250F" "\u252F" "\u2513")" | sed 's/ /\xE2\x94\x81/g'
    printf "$(get_line_format "\u2503" "\u2502" "\u2503" "${HEAD_COL}")" "Filename" "Valid From" "Valid To" "Domain" "Issuer" "Status"
    }

    process_dir_change() {
    print_dir_warn "$prev_dir"
    local cert_dir="$1"
    local cert_file="$2"

    if [[ "$cert_dir" == "$PREV_DIR" ]]; then
    return
    fi

    print_dir_warn "$PREV_DIR"
    ((total_dirs++))

    valid_count=0
    count=0
    prev_dir="$cert_dir"
    printf "| ${BLUE}%-163s${NC} |\n" "$cert_dir"
    PREV_DIR="$cert_dir"

    printf "$(get_line_format "\u2520" "\u2534" "\u2528")" | sed 's/ /─/g'
    printf "\u2503 ${BLUE}%-162s${NC} \u2503\n" "$cert_dir"
    printf "$(get_line_format "\u2520" "\u252C" "\u2528")" | sed 's/ /─/g'
    }

    print_summary() {
    local LINE_FORMAT="${HEAD_COL}%-28s${NC} | ${BOLD}%-10s${NC}\n"
    local line_format="${HEAD_COL}\u2503 ${BOLD}%-28s${NC}${HEAD_COL} \u2502 %-4s \u2503${NC}\n"

    echo ""
    echo -e "${BOLD}=== Summary ===${NC}"
    printf "$LINE_FORMAT" "Total Directories" "$total_dirs"
    printf "$LINE_FORMAT" "Total Certificates" "$total_count"
    printf "$LINE_FORMAT" "Total Dirs w/ no valid cert" "$total_dirs_no_valid"
    printf "$LINE_FORMAT" "Total Valid Certs" "$total_valid"
    printf "$LINE_FORMAT" "Total InValid Certs" "$total_invalid"
    printf "%s\n" "${WARNINGS[@]}"
    echo ""
    echo -e "${HEAD_COL}${BOLD}===== Summary =====${NC}"
    printf "${HEAD_COL}\u250F%37s\u2513${NC}\n" | sed 's/ /\xE2\x94\x81/g'
    printf "$line_format" "Total Directories" "$total_dirs"
    printf "$line_format" "Total Certificates" "$total_count"
    printf "$line_format" "Total Dirs w/ no valid cert" "$total_dirs_no_valid"
    printf "$line_format" "Total Valid Certs" "$total_valid"
    printf "$line_format" "Total InValid Certs" "$total_invalid"
    printf "${HEAD_COL}\u2517%37s\u251B${NC}\n" | sed 's/ /\xE2\x94\x81/g'
    }

    # Parses info from a SSL cert, extracting domain, issuer and dates. Provides time validity and appropriate color for validity status.
    parse_cert_info() {
    local cert="$1"
    local cert_info

    # Parse details from cert_info
    local cert_info=$(openssl x509 -in "$cert" -noout -subject -issuer -startdate -enddate 2>/dev/null)
    cert_info=$(openssl x509 -in "$cert" -noout -subject -issuer -startdate -enddate 2>/dev/null)
    if [[ $? -ne 0 ]]; then
    return 1
    fi
    subject=$(echo "$cert_info" | sed -n '/^subject=/s/.*[Cc][Nn][ ]*=[ ]*\([^,]*\).*/\1/p')
    issuer=$(echo "$cert_info" | sed -n '/^issuer=/s/.*[Oo][ ]*=[ ]*\([^,]*\).*/\1/p')
    from=$(echo "$cert_info" | sed -n 's/^notBefore=//p')
    @@ -171,16 +208,20 @@ parse_cert_info() {
    valid_status="invalid"
    if (( from_ts > NOW_TS )); then
    validity_color=$YELLOW # Not reached
    valid_status="future"
    ((total_invalid++))
    elif (( to_ts < NOW_TS )); then
    validity_color=$RED # Expired
    valid_status="expired"
    ((total_invalid++))
    else
    validity_color=$GREEN # Current
    valid_status="valid"
    valid_status="active"
    ((valid_count++))
    ((total_valid++))
    fi

    return 0
    }

    ### Run main program ###
  3. catchdave revised this gist Oct 31, 2024. 1 changed file with 13 additions and 1 deletion.
    14 changes: 13 additions & 1 deletion find_all_certs.sh
    Original file line number Diff line number Diff line change
    @@ -5,6 +5,7 @@
    # Usage: ./find_all_certs.sh [--valid-only | --invalid-only]
    # --valid-only - Only show valid certificates found
    # --invalid-only - Only show invalid certificates found
    # --no-color - Don't display ANSII Color output

    if [ "$EUID" -ne 0 ]; then
    echo "This script must be run as root or with sudo."
    @@ -37,6 +38,17 @@ mode=all
    parse_args() {
    while [[ $# -gt 0 ]]; do
    case "$1" in
    --no-color)
    GREEN=
    RED=
    YELLOW=
    BLUE=
    NC=
    BOLD=
    HEAD_COL=

    shift
    ;;
    --valid-only)
    mode=valid_only
    shift
    @@ -46,7 +58,7 @@ parse_args() {
    shift
    ;;
    *)
    echo "Usage: $0 [--valid-only | --invalid-only]"
    echo "Usage: $0 [--valid-only | --invalid-only] [--no-color]"
    exit 1
    ;;
    esac
  4. catchdave revised this gist Oct 31, 2024. 1 changed file with 4 additions and 8 deletions.
    12 changes: 4 additions & 8 deletions find_all_certs.sh
    Original file line number Diff line number Diff line change
    @@ -83,9 +83,9 @@ main() {
    check_valid_cert() {
    local cert=$1
    if [[ ! "$(head -n 1 "$cert")" == "-----BEGIN CERTIFICATE-----" ]]; then
    return 0
    return 1
    fi
    return 1
    return 0
    }

    # Execute filtering based on mode
    @@ -108,14 +108,10 @@ print_cert_line() {
    }

    print_dir_warn() {
    if [[ "$count" == "0" ]]; then
    return
    fi

    if [[ "$valid_count" == "0" ]]; then
    [[ "$count" -ne 0 && "$valid_count" -eq 0 ]] && {
    echo -e "${RED}${BOLD}[WARN] No Valid Certs in: ${NC}${RED}$1/${NC}"
    ((total_dirs_no_valid++))
    fi
    }
    }

    print_header() {
  5. catchdave revised this gist Oct 31, 2024. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion find_all_certs.sh
    Original file line number Diff line number Diff line change
    @@ -61,7 +61,7 @@ main() {
    cert_dir=$(dirname "$cert")
    cert_file=$(basename "$cert")

    check_valid_cert || continue
    check_valid_cert "$cert" || continue

    # Print the directory heading if it's new
    if [[ "$cert_dir" != "$prev_dir" ]]; then
    @@ -81,6 +81,7 @@ main() {

    # Skip files that are not valid certificates
    check_valid_cert() {
    local cert=$1
    if [[ ! "$(head -n 1 "$cert")" == "-----BEGIN CERTIFICATE-----" ]]; then
    return 0
    fi
  6. catchdave revised this gist Oct 31, 2024. 1 changed file with 22 additions and 13 deletions.
    35 changes: 22 additions & 13 deletions find_all_certs.sh
    Original file line number Diff line number Diff line change
    @@ -58,14 +58,10 @@ main() {

    print_header
    while read -r cert; do
    # Get the directory and basename of the current file
    cert_dir=$(dirname "$cert")
    cert_file=$(basename "$cert")

    # Skip files that are not valid certificates
    if [[ ! "$(head -n 1 "$cert")" == "-----BEGIN CERTIFICATE-----" ]]; then
    continue
    fi
    check_valid_cert || continue

    # Print the directory heading if it's new
    if [[ "$cert_dir" != "$prev_dir" ]]; then
    @@ -74,21 +70,34 @@ main() {
    ((count++))
    ((total_count++))

    parse_cert_info "$cert"
    # Apply filters based on mode
    if [[ "$mode" == "valid_only" && "$valid_status" == "invalid" ]]; then
    continue
    elif [[ "$mode" == "invalid_only" && "$valid_status" == "valid" ]]; then
    continue
    fi

    parse_cert_info "$cert" # Sets the vars: $from, $to, $subject, $issuer, $validity_color & $valid_status
    check_filter "$valid_status" || continue
    print_cert_line "$validity_color" "$cert_file" "$from" "$to" "$subject" "$issuer"
    done < <(find "$BASE_DIR" -type f -name "*.pem" -not -path "/volume*" 2>/dev/null)

    print_dir_warn "$cert_dir"
    print_summary
    }

    # Skip files that are not valid certificates
    check_valid_cert() {
    if [[ ! "$(head -n 1 "$cert")" == "-----BEGIN CERTIFICATE-----" ]]; then
    return 0
    fi
    return 1
    }

    # Execute filtering based on mode
    check_filter() {
    local valid_status=$1
    if [[ "$mode" == "valid_only" && "$valid_status" == "invalid" ]]; then
    return 1
    elif [[ "$mode" == "invalid_only" && "$valid_status" == "valid" ]]; then
    return 1
    fi
    return 0
    }

    print_cert_line() {
    local color=$1
    LINE_FORMAT="| %-44s | COLOR%-28s${NC} | COLOR%-28s${NC} | %-20s | %-30s |\n"
  7. catchdave revised this gist Oct 31, 2024. 1 changed file with 0 additions and 6 deletions.
    6 changes: 0 additions & 6 deletions find_all_certs.sh
    Original file line number Diff line number Diff line change
    @@ -51,12 +51,6 @@ parse_args() {
    ;;
    esac
    done

    # Ensure only one filter is selected at a time
    if [[ "$valid_only" == true && "$invalid_only" == true ]]; then
    echo "Error: --valid-only and --invalid-only cannot be used together."
    exit 1
    fi
    }

    main() {
  8. catchdave created this gist Oct 31, 2024.
    175 changes: 175 additions & 0 deletions find_all_certs.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,175 @@
    #!/bin/bash
    #
    # Finds all .pem certs on synology under /usr.
    #
    # Usage: ./find_all_certs.sh [--valid-only | --invalid-only]
    # --valid-only - Only show valid certificates found
    # --invalid-only - Only show invalid certificates found

    if [ "$EUID" -ne 0 ]; then
    echo "This script must be run as root or with sudo."
    exit 1
    fi

    # Color codes
    GREEN="\033[1;32m"
    RED="\033[0;31m"
    YELLOW="\033[0;33m"
    BLUE="\033[0;95m"
    NC="\033[0m" # No Color
    BOLD="\033[1m"
    HEAD_COL="\033[1;97m\033[1;100m"

    # Initialize variables
    NOW_TS=$(date +%s)
    BASE_DIR=/usr/
    prev_dir=""
    valid_count=0
    count=0
    total_count=0
    total_valid=0
    total_invalid=0
    total_dirs_no_valid=0
    total_dirs=0
    valid_status=
    mode=all

    parse_args() {
    while [[ $# -gt 0 ]]; do
    case "$1" in
    --valid-only)
    mode=valid_only
    shift
    ;;
    --invalid-only)
    mode=invalid_only
    shift
    ;;
    *)
    echo "Usage: $0 [--valid-only | --invalid-only]"
    exit 1
    ;;
    esac
    done

    # Ensure only one filter is selected at a time
    if [[ "$valid_only" == true && "$invalid_only" == true ]]; then
    echo "Error: --valid-only and --invalid-only cannot be used together."
    exit 1
    fi
    }

    main() {
    parse_args "$@"

    print_header
    while read -r cert; do
    # Get the directory and basename of the current file
    cert_dir=$(dirname "$cert")
    cert_file=$(basename "$cert")

    # Skip files that are not valid certificates
    if [[ ! "$(head -n 1 "$cert")" == "-----BEGIN CERTIFICATE-----" ]]; then
    continue
    fi

    # Print the directory heading if it's new
    if [[ "$cert_dir" != "$prev_dir" ]]; then
    process_dir_change
    fi
    ((count++))
    ((total_count++))

    parse_cert_info "$cert"
    # Apply filters based on mode
    if [[ "$mode" == "valid_only" && "$valid_status" == "invalid" ]]; then
    continue
    elif [[ "$mode" == "invalid_only" && "$valid_status" == "valid" ]]; then
    continue
    fi

    print_cert_line "$validity_color" "$cert_file" "$from" "$to" "$subject" "$issuer"
    done < <(find "$BASE_DIR" -type f -name "*.pem" -not -path "/volume*" 2>/dev/null)

    print_dir_warn "$cert_dir"
    print_summary
    }

    print_cert_line() {
    local color=$1
    LINE_FORMAT="| %-44s | COLOR%-28s${NC} | COLOR%-28s${NC} | %-20s | %-30s |\n"

    cur_format="${LINE_FORMAT//COLOR/${color}}"
    printf "$cur_format" "$2" "$3" "$4" "$5" "$6"
    }

    print_dir_warn() {
    if [[ "$count" == "0" ]]; then
    return
    fi

    if [[ "$valid_count" == "0" ]]; then
    echo -e "${RED}${BOLD}[WARN] No Valid Certs in: ${NC}${RED}$1/${NC}"
    ((total_dirs_no_valid++))
    fi
    }

    print_header() {
    LINE_FORMAT="${HEAD_COL}| %-44s | %-28s | %-28s | %-20s | %-30s |${NC}\n"
    printf "$LINE_FORMAT" "Filename" "Valid From" "Valid To" "Domain" "Issuer"
    }

    process_dir_change() {
    print_dir_warn "$prev_dir"
    ((total_dirs++))

    valid_count=0
    count=0
    prev_dir="$cert_dir"
    printf "| ${BLUE}%-163s${NC} |\n" "$cert_dir"
    }

    print_summary() {
    local LINE_FORMAT="${HEAD_COL}%-28s${NC} | ${BOLD}%-10s${NC}\n"

    echo ""
    echo -e "${BOLD}=== Summary ===${NC}"
    printf "$LINE_FORMAT" "Total Directories" "$total_dirs"
    printf "$LINE_FORMAT" "Total Certificates" "$total_count"
    printf "$LINE_FORMAT" "Total Dirs w/ no valid cert" "$total_dirs_no_valid"
    printf "$LINE_FORMAT" "Total Valid Certs" "$total_valid"
    printf "$LINE_FORMAT" "Total InValid Certs" "$total_invalid"
    }

    parse_cert_info() {
    local cert="$1"

    # Parse details from cert_info
    local cert_info=$(openssl x509 -in "$cert" -noout -subject -issuer -startdate -enddate 2>/dev/null)
    subject=$(echo "$cert_info" | sed -n '/^subject=/s/.*[Cc][Nn][ ]*=[ ]*\([^,]*\).*/\1/p')
    issuer=$(echo "$cert_info" | sed -n '/^issuer=/s/.*[Oo][ ]*=[ ]*\([^,]*\).*/\1/p')
    from=$(echo "$cert_info" | sed -n 's/^notBefore=//p')
    to=$(echo "$cert_info" | sed -n 's/^notAfter=//p')

    # Convert dates to Unix timestamps for comparison
    local from_ts=$(date -d "$from" +%s)
    local to_ts=$(date -d "$to" +%s)

    # Determine validity of certs
    valid_status="invalid"
    if (( from_ts > NOW_TS )); then
    validity_color=$YELLOW # Not reached
    ((total_invalid++))
    elif (( to_ts < NOW_TS )); then
    validity_color=$RED # Expired
    ((total_invalid++))
    else
    validity_color=$GREEN # Current
    valid_status="valid"
    ((valid_count++))
    ((total_valid++))
    fi
    }

    ### Run main program ###
    main "$@"