#!/bin/bash ##################################################################### # # Fortify SCA Scan 시간 추출 스크립트 # # 이 스크립트는 FPR파일을 분석하여 아래의 파일을 출력한다. # - CSV포맷의 스캔 시간 정리 # - 스케줄링을 추가하는 윈도우 배치파일 작성 # # 윈도우에서 실행 시: # bash -c "./get_fpr_scantime.sh ./fpr/*.fpr" # # by 이존석(hasu0707@esvali.com) # ##################################################################### DEBUG_ON=0 VERSION=0.1 WIN_MINGW_DIR="/cygdrive/c/PortableApps/cmd_cygwin_x86_64" CSV_FILENAME="fpr_scantime_list.csv" BAT_FILENAME="set_schedule.bat" SCA_SCRIPT_DIR="D:\fortify_work\scripts" SCHTASKS_FOLDER_NAME="Fortify_SCA" START_TIME=32400 # 3600*9 (09:00부터 시작시간까지 초) = 18:00 END_SEC=46800 # 3600*13 (09:00부터 끝시간까지 초) = 07:00 TMP_DIR1="./fpr_tmp" TMP_FILE1="tmp_file001.txt" TMP_FILE2="tmp_file002.txt" ##################################################################### # # 사용방법 출력 # ##################################################################### func_usage() { echo "$0 ver.${VERSION}" echo echo "usage: $0 <wildcard>" echo " example: $0 ./fpr/*.fpr" } ##################################################################### # # 초기화 # $1 : FPR 파일명 # ##################################################################### func_init() { if [ ${DEBUG_ON} -eq 1 ] then echo ">> func_init()" fi if [ -z "${WINDIR}" ]; then IS_WINDOWS=0 else IS_WINDOWS=1 fi if [ ${IS_WINDOWS} -eq 1 ]; then DEVNULL=null.dev WINCMD="/cygdrive/c/Windows/System32/cmd.exe /C" PATH=${WIN_MINGW_DIR}/bin:${PATH} else DEVNULL=/dev/null WINCMD="" PATH=${PATH} fi BUILD_ID=$(basename $1 .fpr) } ##################################################################### # # 필요한 유틸리티가 있는지 검사 # ##################################################################### func_check_utils() { if [ ${DEBUG_ON} -eq 1 ] then echo ">> func_check_utils()" fi local IS_EXIT=0; UTILNAMES=("grep" "unzip" "ls" "sort" "date") # 윈도우 유틸리티 체킹 if [ ${IS_WINDOWS} -eq 1 ]; then if [ ! -x ${WIN_MINGW_DIR}/bin/grep ] || [ ! -x ${WIN_MINGW_DIR}/bin/unzip ] || [ ! -x ${WIN_MINGW_DIR}/bin/ls ] || [ ! -x ${WIN_MINGW_DIR}/bin/sort ] || [ ! -x ${WIN_MINGW_DIR}/bin/date ]; then echo "ERROR: ${WIN_MINGW_DIR} not found !" IS_EXIT=1 fi if [ ${IS_EXIT} -ne 0 ]; then exit 1 fi return fi # 리눅스 유틸리티 체킹 for LOOP1 in "${UTILNAMES[@]}" do which ${LOOP1} > ${DEVNULL} if [ $? -ne 0 ]; then echo "ERROR: ${LOOP1} not found !" IS_EXIT=1 fi done # 없는 유틸리티가 있으면 스크립트 종료 if [ ${IS_EXIT} -ne 0 ]; then exit 1 fi unset UTILNAMES } ##################################################################### # # 초를 HH:MM:SS 형태로 계산하여 TIMESTAMP 변수에 대입한다. # $1 : 초 # ##################################################################### func_conv_sec2timestamp() { SEC_VAL=${1} ((h=${SEC_VAL}/3600)) ((m=(${SEC_VAL}%3600)/60)) ((s=${SEC_VAL}%60)) TIMESTAMP=$(printf "%02d:%02d:%02d\n" $h $m $s) } ##################################################################### # # FPR파일 unzip # $1 : fpr 파일명 # ##################################################################### func_unzip() { if [ ${DEBUG_ON} -eq 1 ] then echo ">> func_unzip()" fi if [ -d ${TMP_DIR1} ] then rm -rf ${TMP_DIR1} fi mkdir ${TMP_DIR1} unzip $1 -d ${TMP_DIR1} audit.fvdl &> ${DEVNULL} } ##################################################################### # # audit.fvdl에서 scantime을 뽑아낸다. # ##################################################################### func_get_scantime() { if [ ${DEBUG_ON} -eq 1 ] then echo ">> func_get_scantime()" fi if [ ! -f ${TMP_DIR1}/audit.fvdl ]; then echo "ERROR: ${TMP_DIR1}/audit.fvdl not found !" func_usage exit 2 fi SCANTIME=$(grep -Po '<ScanTime value=\"\K.*?(?=")' ${TMP_DIR1}/audit.fvdl) # 빌드 시간을 스캔시간의 1/6로 잡아서 더한다. ((ADD_BUILD_SEC=${SCANTIME}/6)) ((SCANTIME=${SCANTIME}+${ADD_BUILD_SEC})) func_conv_sec2timestamp ${SCANTIME} echo "${1},${SCANTIME},${TIMESTAMP}" >> ${TMP_FILE1} } ##################################################################### # # 초를 시:분으로 변환 # ##################################################################### func_sec_to_formatstring() { if [ ${DEBUG_ON} -eq 1 ] then echo ">> func_sec_to_formatstring()" fi local NUM=${1} local SECVAL=$((START_TIME+NUM)) if [ ${IS_WINDOWS} -eq 1 ]; then DATE_FMT_STR=$(${WIN_MINGW_DIR}/bin/date +'%H:%M' -d @${SECVAL}) else DATE_FMT_STR=$(date +'%H:%M' -d @${SECVAL}) fi } ##################################################################### # # 숫자를 주 이름으로 대입 # ##################################################################### func_get_weekname() { if [ ${DEBUG_ON} -eq 1 ] then echo ">> func_get_weekname()" fi local WEEKVAL=${1} WEEKNAME="SUN" if [ ${WEEKVAL} -eq 1 ]; then WEEKNAME="MON" elif [ ${WEEKVAL} -eq 2 ]; then WEEKNAME="TUE" elif [ ${WEEKVAL} -eq 3 ]; then WEEKNAME="WED" elif [ ${WEEKVAL} -eq 4 ]; then WEEKNAME="THU" elif [ ${WEEKVAL} -eq 5 ]; then WEEKNAME="FRI" elif [ ${WEEKVAL} -eq 6 ]; then WEEKNAME="SAT" elif [ ${WEEKVAL} -eq 7 ]; then WEEKNAME="SUN" fi } ##################################################################### # # SCHTASKS 배치 파일 쓰기 # ##################################################################### func_write_schtasks_bat() { if [ ${DEBUG_ON} -eq 1 ] then echo ">> func_write_schtasks_bat() $1 $2 $3 $4" fi echo -n "SCHTASKS /CREATE /F " >> ${TMP_FILE2} echo -n "/TN \"${SCHTASKS_FOLDER_NAME}\\${1}\" " >> ${TMP_FILE2} echo -n "/TR \"${2}\" " >> ${TMP_FILE2} echo -n "/SC WEEKLY " >> ${TMP_FILE2} func_get_weekname ${3} echo -n "/D ${WEEKNAME} " >> ${TMP_FILE2} func_sec_to_formatstring ${4} echo -n "/ST ${DATE_FMT_STR} " >> ${TMP_FILE2} echo "/MO 1" >> ${TMP_FILE2} } ##################################################################### # # CSV를 분석해서 SCHTASKS 배치 파일을 만든다 # ##################################################################### func_parse_csv() { if [ ${DEBUG_ON} -eq 1 ] then echo ">> func_parse_csv()" fi local LINE_CNT=0 local SEC_TOTAL=0 local WEEK_NO=1 rm -f ${TMP_FILE2} OLDIFS=${IFS} IFS=',' while read FPR SEC TIMESTAMP do SCH_NAME=$(basename -s .fpr ${FPR}) SH_FILENAME="${SCA_SCRIPT_DIR}\\$(basename -s .fpr ${FPR}).bat" func_write_schtasks_bat ${SCH_NAME} ${SH_FILENAME} ${WEEK_NO} ${SEC_TOTAL} SEC_TOTAL=$((SEC_TOTAL+SEC)) # 시간 체크 if [ ${SEC_TOTAL} -gt ${END_SEC} ]; then SEC_TOTAL=0 WEEK_NO=$((WEEK_NO+1)) fi # 일요일이 지나면 다시 월요일 if [ ${WEEK_NO} -gt 7 ]; then WEEK_NO=1 fi # 토요일, 일요일은 24시간 if [ ${WEEK_NO} -eq 6 -o ${WEEK_NO} -eq 7 ] then START_TIME=0 END_SEC=86400 fi done < ${CSV_FILENAME} IFS=${OLDIFS} } ##################################################################### # # 임시 및 불필요한 파일 삭제 # ##################################################################### func_clean() { if [ ${DEBUG_ON} -eq 1 ] then echo ">> func_clean()" fi if [ ${IS_WINDOWS} -eq 1 ]; then rm -f ${DEVNULL} fi rm -f ${TMP_FILE1} rm -f ${TMP_FILE2} rm -rf ${TMP_DIR1} rm -f ${BUILD_ID}.xml } ##################################################################### # # main # ##################################################################### # 명령행 인수가 없으면 사용방법 출력하고 끝냄 if [ $# -lt 1 ]; then func_usage exit 3 fi if [ -f ${CSV_FILENAME} ]; then rm -f ${CSV_FILENAME} fi func_init func_check_utils ##################################################################### # wildcard에 부합하는 파일들에 대한 처리 ##################################################################### for LOOP1 in $(ls -1 -SS $*) do if [ -f ${LOOP1} ] then echo ${LOOP1} func_unzip ${LOOP1} func_get_scantime ${LOOP1} else break fi done ##################################################################### # CSV 타이틀 출력 ##################################################################### #echo "Filename,Second,Timestamp(HH:MM:SS)" > ${CSV_FILENAME} ##################################################################### # 스캔 시간에 따라 역순 Sort ##################################################################### if [ ${IS_WINDOWS} -eq 1 ]; then ${WIN_MINGW_DIR}/bin/sort -t, -r -k3 ${TMP_FILE1} >> ${CSV_FILENAME} else sort -t, -r -k3 ${TMP_FILE1} >> ${CSV_FILENAME} fi func_parse_csv ##################################################################### # 윈도우 배치파일의 개행문자 및 코드셋 변경 ##################################################################### sed -i 's/$/\r/' ${TMP_FILE2} iconv -f utf8 -t euc-kr ${TMP_FILE2} > ${BAT_FILENAME} func_clean