1
0
mirror of https://github.com/hashcat/hashcat.git synced 2024-12-27 00:48:13 +00:00
hashcat/extra/tab_completion/hashcat.sh
philsmd de0ff9a42b
tab completion: allow using "install version" of hashcat
With this little update we also allow the installed version of "hashcat" (e.g. in /usr/local/bin/hashcat) to work with the tab completion script (most importantly used for the "hashcat -I" device lists).
2019-05-17 09:46:53 +02:00

828 lines
24 KiB
Bash

##
## Author......: See docs/credits.txt
## License.....: MIT
##
HASHCAT_ROOT="."
# helper functions
_hashcat_backend_devices ()
{
local cur_selection="${1}"
hashcat_device_list=""
local executable="${HASHCAT_ROOT}"/hashcat
if [ ! -x "${executable}" ]; then
executable="${HASHCAT_ROOT}"/hashcat.bin
fi
if [ ! -x "${executable}" ]; then
local which_hashcat=$(which hashcat 2>/dev/null)
if [ -n "${which_hashcat}" ]; then
executable="${which_hashcat}"
fi
fi
if [ ! -x "${executable}" ]; then
return
fi
# remove separator at the end (if present)
cur_selection=$(echo "${cur_selection}" | sed 's/,$//')
# sanity check, all device ids must be numerical
if [ -n "${cur_selection}" ]; then
if echo "${cur_selection}" | sed 's/,/\n/g' | grep -q -v '^[0-9]\+$'
then
return
fi
fi
local hashcat_I=$("${executable}" -I 2>/dev/null | grep "Backend Device ID #[0-9]\+" | sed 's/^ *Backend Device ID #//')
if [ -z "${hashcat_I}" ]; then
return
fi
local aliases=$(echo "${hashcat_I}" | grep "(Alias: #[0-9]\+)" | sed 's/ *(Alias: #\([0-9]\+\))/ \1/')
local aliases_num=$(echo "${aliases}" | wc -l)
local aliases_deduplicate=""
local alias_pos=""
for alias_pos in $(seq 1 ${aliases_num}); do
local alias_sorted=$(echo "${aliases}" | sed -n "${alias_pos}p" | tr ' ' '\n' | sort -n | tr '\n' ' ' | sed 's/ *$//')
if [ -n "${aliases_deduplicate}" ]; then
aliases_deduplicate=$(echo -e "${aliases_deduplicate}\n${alias_sorted}")
else
aliases_deduplicate="${alias_sorted}"
fi
done
aliases_deduplicate=$(echo "${aliases_deduplicate}" | sort -u)
aliases_num=$(echo "${aliases_deduplicate}" | wc -l)
local device_list=$(echo "${hashcat_I}" | grep -o "^[0-9]*" | sort -n -u)
local cur_device_list=$(echo "${cur_selection}" | sed 's/,/\n/g' | grep "^[0-9]\+\$" | sort -nu)
# make sure that every device in the current selected device list (parameter) is within our backend device list
local device=""
for device in ${cur_device_list}; do
if ! echo "${device_list}" | grep -q "^${device}\$" 2>/dev/null; then
return # error
fi
done
local appended_device_list=${device_list}
for device in ${cur_device_list}; do
appended_device_list=$(echo "${appended_device_list}" | grep -v "^${device}\$")
done
local hashcat_backend_list=""
if [ -n "${cur_selection}" ]; then
hashcat_backend_list="${cur_selection}"
fi
for device in ${appended_device_list}; do
if [ -z "${hashcat_backend_list}" ]; then
if [ -z "${cur_selection}" ]; then
hashcat_backend_list="${device}"
else
hashcat_backend_list="${cur_selection},${device}"
fi
else
if [ -z "${cur_selection}" ]; then
hashcat_backend_list=$(echo -e "${hashcat_backend_list}\n${device}")
else
hashcat_backend_list=$(echo -e "${hashcat_backend_list}\n${cur_selection},${device}")
fi
fi
done
# finally, blacklist all devices that are just aliases
local device_str=""
for device_str in ${hashcat_backend_list}; do
local devices=$(echo "${device_str}" | tr ',' '\n')
local conflict=0
for alias_pos in $(seq 1 ${aliases_num}); do
local alias=$(echo "${aliases_deduplicate}" | sed -n "${alias_pos}p" | tr ' ' '\n')
# currently, an alias always consists of 2 devices:
local alias1=$(echo "${alias}" | sed -n "1p") # head -n 1
local alias2=$(echo "${alias}" | sed -n "2p") # tail -n 1
if echo "${devices}" | grep -q "^${alias1}\$"; then
if echo "${devices}" | grep -q "^${alias2}\$"; then
conflict=1
break
fi
fi
done
if [ "${conflict}" -eq 1 ]; then
continue
fi
# we add it because we didn't find any conflicts:
if [ -z "${hashcat_device_list}" ]; then
hashcat_device_list="${device_str}"
else
hashcat_device_list=$(echo -e "${hashcat_device_list}\n${device_str}")
fi
done
}
_hashcat_cpu_devices ()
{
local cur_selection="${1}"
hashcat_device_list=""
if [ ! -f "/proc/cpuinfo" ]; then
return
fi
local num_devices=$(cat /proc/cpuinfo 2> /dev/null | grep -c processor 2> /dev/null)
local device_list=$(seq 1 ${num_devices})
# remove separator at the end (if present)
cur_selection=$(echo "${cur_selection}" | sed 's/,$//')
# sanity check, all device ids must be numerical
if [ -n "${cur_selection}" ]; then
if echo "${cur_selection}" | sed 's/,/\n/g' | grep -q -v '^[0-9]\+$'
then
return
fi
fi
local cur_device_list=$(echo "${cur_selection}" | sed 's/,/\n/g' | grep "^[0-9]\+\$" | sort -nu)
# make sure that every device in the current selected device list (parameter) is within our cpu device list
local device=""
for device in ${cur_device_list}; do
if ! echo "${device_list}" | grep -q "^${device}\$" 2>/dev/null; then
return # error
fi
done
local appended_device_list=${device_list}
for device in ${cur_device_list}; do
appended_device_list=$(echo "${appended_device_list}" | grep -v "^${device}\$")
done
if [ -n "${cur_selection}" ]; then
hashcat_device_list="${cur_selection}"
fi
for device in ${appended_device_list}; do
if [ -z "${hashcat_device_list}" ]; then
if [ -z "${cur_selection}" ]; then
hashcat_device_list="${device}"
else
hashcat_device_list="${cur_selection},${device}"
fi
else
if [ -z "${cur_selection}" ]; then
hashcat_device_list=$(echo -e "${hashcat_device_list}\n${device}")
else
hashcat_device_list=$(echo -e "${hashcat_device_list}\n${cur_selection},${device}")
fi
fi
done
}
_hashcat_contains ()
{
local haystack=${1}
local needle="${2}"
if echo "${haystack}" | grep -q " ${needle} " 2> /dev/null; then
return 0
elif echo "${haystack}" | grep -q "^${needle} " 2> /dev/null; then
return 0
elif echo "${haystack}" | grep -q " ${needle}\$" 2> /dev/null; then
return 0
fi
return 1
}
_hashcat ()
{
local VERSION=5.1.0
local ATTACK_MODES="0 1 3 6 7"
local HCCAPX_MESSAGE_PAIRS="0 1 2 3 4 5"
local OUTFILE_FORMATS="1 2 3 4 5 6 7 8 9 10 11 12 13 14 15"
local OPENCL_DEVICE_TYPES="1 2 3"
local BACKEND_VECTOR_WIDTH="1 2 4 8 16"
local DEBUG_MODE="1 2 3 4"
local WORKLOAD_PROFILE="1 2 3 4"
local BRAIN_CLIENT_FEATURES="1 2 3"
local HIDDEN_FILES="exe|bin|potfile|hcstat2|dictstat2|sh|cmd|bat|restore"
local HIDDEN_FILES_AGGRESIVE="${HIDDEN_FILES}|hcmask|hcchr"
local BUILD_IN_CHARSETS='?l ?u ?d ?a ?b ?s ?h ?H'
local SHORT_OPTS="-m -a -V -h -b -t -T -o -p -c -d -D -w -n -u -j -k -r -g -1 -2 -3 -4 -i -I -s -l -O -S -z"
local LONG_OPTS="--hash-type --attack-mode --version --help --quiet --benchmark --benchmark-all --hex-salt --hex-wordlist --hex-charset --force --status --status-json --status-timer --stdin-timeout-abort --machine-readable --loopback --markov-hcstat2 --markov-disable --markov-classic --markov-threshold --runtime --session --speed-only --progress-only --restore --restore-file-path --restore-disable --outfile --outfile-format --outfile-autohex-disable --outfile-check-timer --outfile-check-dir --wordlist-autohex-disable --separator --show --left --username --remove --remove-timer --potfile-disable --potfile-path --debug-mode --debug-file --induction-dir --segment-size --bitmap-min --bitmap-max --cpu-affinity --example-hashes --backend-info --backend-devices --opencl-device-types --backend-vector-width --workload-profile --kernel-accel --kernel-loops --kernel-threads --spin-damp --hwmon-disable --hwmon-temp-abort --skip --limit --keyspace --rule-left --rule-right --rules-file --generate-rules --generate-rules-func-min --generate-rules-func-max --generate-rules-seed --custom-charset1 --custom-charset2 --custom-charset3 --custom-charset4 --increment --increment-min --increment-max --logfile-disable --scrypt-tmto --keyboard-layout-mapping --truecrypt-keyfiles --veracrypt-keyfiles --veracrypt-pim-start --veracrypt-pim-stop --stdout --keep-guessing --hccapx-message-pair --nonce-error-corrections --encoding-from --encoding-to --optimized-kernel-enable --self-test-disable --slow-candidates --brain-server --brain-client --brain-client-features --brain-host --brain-port --brain-session --brain-session-whitelist --brain-password"
local OPTIONS="-m -a -t -o -p -c -d -w -n -u -j -k -r -g -1 -2 -3 -4 -s -l --hash-type --attack-mode --status-timer --stdin-timeout-abort --markov-hcstat2 --markov-threshold --runtime --session --timer --outfile --outfile-format --outfile-check-timer --outfile-check-dir --separator --remove-timer --potfile-path --restore-file-path --debug-mode --debug-file --induction-dir --segment-size --bitmap-min --bitmap-max --cpu-affinity --backend-devices --opencl-device-types --backend-vector-width --workload-profile --kernel-accel --kernel-loops --kernel-threads --spin-damp --hwmon-temp-abort --skip --limit --rule-left --rule-right --rules-file --generate-rules --generate-rules-func-min --generate-rules-func-max --generate-rules-seed --custom-charset1 --custom-charset2 --custom-charset3 --custom-charset4 --increment-min --increment-max --scrypt-tmto --keyboard-layout-mapping --truecrypt-keyfiles --veracrypt-keyfiles --veracrypt-pim-start --veracrypt-pim-stop --hccapx-message-pair --nonce-error-corrections --encoding-from --encoding-to --brain-client-features --brain-host --brain-password --brain-port --brain-session --brain-session-whitelist"
COMPREPLY=()
local cur="${COMP_WORDS[COMP_CWORD]}"
local prev="${COMP_WORDS[COMP_CWORD-1]}"
# if cur is just '=', ignore the '=' and treat it as only the prev was provided
if [[ "${cur}" == '=' ]]; then
cur=""
elif [[ "${prev}" == '=' ]]; then
if [ "${COMP_CWORD}" -gt 2 ]; then
prev="${COMP_WORDS[COMP_CWORD-2]}"
fi
fi
case "${prev}" in
-a|--attack-mode)
COMPREPLY=($(compgen -W "${ATTACK_MODES}" -- ${cur}))
return 0
;;
--hccapx-message-pair)
COMPREPLY=($(compgen -W "${HCCAPX_MESSAGE_PAIRS}" -- ${cur}))
return 0
;;
--outfile-format)
COMPREPLY=($(compgen -W "${OUTFILE_FORMATS}" -- ${cur}))
return 0
;;
-w|--workload-profile)
COMPREPLY=($(compgen -W "${WORKLOAD_PROFILE}" -- ${cur}))
return 0
;;
--brain-client-features)
COMPREPLY=($(compgen -W "${BRAIN_CLIENT_FEATURES}" -- ${cur}))
return 0
;;
-o|--outfile|-r|--rules-file|--debug-file|--potfile-path| --restore-file-path)
local files=$(ls -d ${cur}* 2> /dev/null | grep -Eiv '*\.('${HIDDEN_FILES_AGGRESIVE}')' 2> /dev/null)
COMPREPLY=($(compgen -W "${files}" -- ${cur})) # or $(compgen -f -X '*.+('${HIDDEN_FILES_AGGRESIVE}')' -- ${cur})
return 0
;;
--markov-hcstat2)
local files=$(ls -d ${cur}* 2> /dev/null | grep '.*\.hcstat2$' 2> /dev/null)
COMPREPLY=($(compgen -W "${files}" -- ${cur})) # or $(compgen -f -X '*.+('${HIDDEN_FILES_AGGRESIVE}')' -- ${cur})
return 0
;;
-d|--backend-devices)
_hashcat_backend_devices ${cur}
COMPREPLY=($(compgen -W "${hashcat_device_list}" -- ${cur}))
return 0
;;
--opencl-device-types)
COMPREPLY=($(compgen -W "${OPENCL_DEVICE_TYPES}" -- ${cur}))
return 0
;;
--backend-vector-width)
COMPREPLY=($(compgen -W "${BACKEND_VECTOR_WIDTH}" -- ${cur}))
return 0
;;
--cpu-affinity)
_hashcat_cpu_devices ${cur}
COMPREPLY=($(compgen -W "${hashcat_device_list}" -- ${cur}))
return 0
;;
--keyboard-layout-mapping)
local files=$(ls -d ${cur}* 2> /dev/null | grep '.*\.hckmap$' 2> /dev/null)
COMPREPLY=($(compgen -W "${files}" -- ${cur})) # or $(compgen -f -X '*.+('${HIDDEN_FILES_AGGRESIVE}')' -- ${cur})
return 0
;;
-1|-2|-3|-4|--custom-charset1|--custom-charset2|--custom-charset3|--custom-charset4)
local mask=${BUILD_IN_CHARSETS}
if [ -e "${cur}" ]; then # should be hcchr file (but not enforced)
COMPREPLY=($(compgen -W "${cur}" -- ${cur}))
return 0
fi
if [ -n "${cur}" ]; then
local cur_var=$(echo "${cur}" | sed 's/\?$//')
mask="${mask} ${cur_var}"
local h
for h in ${mask}; do
if ! echo ${cur} | grep -q ${h} 2> /dev/null; then
if echo ${cur} | grep -q '?a' 2> /dev/null; then
if [[ "${h}" == "?l" ]] ; then
continue
elif [[ "${h}" == "?u" ]] ; then
continue
elif [[ "${h}" == "?d" ]] ; then
continue
elif [[ "${h}" == "?s" ]] ; then
continue
elif [[ "${h}" == "?b" ]] ; then
continue
fi
fi
mask="${mask} ${cur_var}${h}"
fi
done
fi
local files=$(ls -d ${cur}* 2> /dev/null | grep -Eiv '*\.('${HIDDEN_FILES}')' 2> /dev/null)
mask="${mask} ${files}"
COMPREPLY=($(compgen -W "${mask}" -- ${cur}))
return 0
;;
--brain-session)
local cur_session=$(echo "${cur}" | grep -Eo '^0x[0-9a-fA-F]*' | sed 's/^0x//')
local session_var="0x${cur_session}"
if [ "${#cur_session}" -lt 8 ]
then
session_var="${session_var}0 ${session_var}1 ${session_var}2 ${session_var}3 ${session_var}4
${session_var}5 ${session_var}6 ${session_var}7 ${session_var}8 ${session_var}9
${session_var}a ${session_var}b ${session_var}c ${session_var}d ${session_var}e
${session_var}f"
fi
COMPREPLY=($(compgen -W "${session_var}" -- ${cur}))
return 0
;;
--brain-session-whitelist)
local session_list=$(echo "${cur}" | grep -Eo '^0x[0-9a-fA-F,x]*' | sed 's/^0x//')
local cur_session=$(echo "${session_list}" | sed 's/^.*0x//')
local session_var="0x${session_list}"
if [ "${#cur_session}" -eq 8 ]
then
cur_session=""
session_var="${session_var},0x"
fi
if [ "${#cur_session}" -lt 8 ]
then
session_var="${session_var}0 ${session_var}1 ${session_var}2 ${session_var}3 ${session_var}4
${session_var}5 ${session_var}6 ${session_var}7 ${session_var}8 ${session_var}9
${session_var}a ${session_var}b ${session_var}c ${session_var}d ${session_var}e
${session_var}f"
fi
COMPREPLY=($(compgen -W "${session_var}" -- ${cur}))
return 0
;;
--debug-mode)
COMPREPLY=($(compgen -W "${DEBUG_MODE}" -- ${cur}))
return 0
;;
--truecrypt-keyfiles|--veracrypt-keyfiles)
# first: remove the quotes such that file matching is possible
local cur_part0=$(echo "${cur}" | grep -Eo '^("|'"'"')')
local cur_mod=$(echo "${cur}" | sed 's/^["'"'"']//')
local cur_part1=$(echo "${cur_mod}" | grep ',' 2> /dev/null | sed 's/^\(.*, *\)[^,]*$/\1/')
local cur_part2=$(echo "${cur_mod}" | sed 's/^.*, *\([^,]*\)$/\1/')
# generate lines with the file name and a duplicate of it with a comma at the end
local files=$(ls -d ${cur_part2}* 2> /dev/null | grep -Eiv '*\.('${HIDDEN_FILES_AGGRESIVE}')' 2> /dev/null | sed 's/^\(.*\)$/\1\n\1,\n/' | sed "s/^/${cur_part0}${cur_part1}/" | sed "s/$/${cur_part0}/")
COMPREPLY=($(compgen -W "${files}" -- ${cur}))
return 0
esac
# allow also the VARIANTS w/o spaces
# we could use compgen -P prefix, but for some reason it doesn't seem to work always
case "$cur" in
-a*)
local attack_modes_var="$(echo -n "-a ${ATTACK_MODES}" | sed 's/ / -a/g')"
COMPREPLY=($(compgen -W "${attack_modes_var}" -- ${cur}))
return 0
;;
-w*)
local workload_profile_var="$(echo -n "-w ${WORKLOAD_PROFILE}" | sed 's/ / -w/g')"
COMPREPLY=($(compgen -W "${workload_profile_var}" -- ${cur}))
return 0
;;
-o*)
local outfile_var=$(ls -d ${cur:2}* 2> /dev/null | grep -Eiv '*\.('${HIDDEN_FILES_AGGRESIVE}')' 2> /dev/null)
outfile_var="$(echo -e "\n${outfile_var}" | sed 's/^/-o/')"
COMPREPLY=($(compgen -W "${outfile_var}" -- ${cur}))
return 0
;;
-r*)
local outfile_var=$(ls -d ${cur:2}* 2> /dev/null | grep -Eiv '*\.('${HIDDEN_FILES_AGGRESIVE}')' 2> /dev/null)
outfile_var="$(echo -e "\n${outfile_var}" | sed 's/^/-r/')"
COMPREPLY=($(compgen -W "${outfile_var}" -- ${cur}))
return 0
;;
-d*)
_hashcat_backend_devices $(echo ${cur} | sed 's/^-d//')
local hashcat_devices_permutation="$(echo -e "\n${hashcat_device_list}" | sed 's/^/-d/')"
COMPREPLY=($(compgen -W "${hashcat_devices_permutation}" -- ${cur}))
return 0
;;
esac
# Complete options/switches (not the arguments)
if [[ "${cur}" == -* ]]; then
COMPREPLY=($(compgen -W "${SHORT_OPTS} ${LONG_OPTS}" -- ${cur}))
return 0
fi
# additional parameter, no switch nor option but maybe hash file, dictionary, mask, directory
# check if first option out of (hash.txt and dictionary|mask|directory)
# is first option iff: here
# is second option iff: COMP_CWORD > 2 and no switch before (-*) if no option afterwards (for mask -a 3, -a 6, -a 7 - but possible for dicts!)
local h=1
local no_opts=0
local attack_mode=0 # also default of hashcat
local has_charset_1=0
local has_charset_2=0
local has_charset_3=0
local has_charset_4=0
while [ ${h} -le ${COMP_CWORD} ]; do
if [[ "${COMP_WORDS[h]}" == "-a" ]]; then
attack_mode=${COMP_WORDS[$((h + 1))]}
elif [[ "${COMP_WORDS[h]}" == -a* ]]; then
attack_mode=${COMP_WORDS[h]:2}
elif [[ "${COMP_WORDS[h]}" == "--attack-mode" ]]; then
attack_mode=${COMP_WORDS[$((h + 1))]}
elif [[ "${COMP_WORDS[h]}" == "-1" ]]; then
has_charset_1=1
elif [[ "${COMP_WORDS[h]}" == "--custom-charset1" ]]; then
has_charset_1=1
elif [[ "${COMP_WORDS[h]}" == "-2" ]]; then
has_charset_2=1
elif [[ "${COMP_WORDS[h]}" == "--custom-charset2" ]]; then
has_charset_2=1
elif [[ "${COMP_WORDS[h]}" == "-3" ]]; then
has_charset_3=1
elif [[ "${COMP_WORDS[h]}" == "--custom-charset3" ]]; then
has_charset_3=1
elif [[ "${COMP_WORDS[h]}" == "-4" ]]; then
has_charset_4=1
elif [[ "${COMP_WORDS[h]}" == "--custom-charset4" ]]; then
has_charset_4=1
fi
if _hashcat_contains "${OPTIONS}" "${COMP_WORDS[h]}"; then
h=$((h + 2))
else
if ! _hashcat_contains "${LONG_OPTS}${SHORT_OPTS}" "${COMP_WORDS[h]}"; then
local variants="-m -a -w -n -u -o -r -d"
local skip=0
local v
for v in ${variants}; do
if [[ "${COMP_WORDS[h]:0:2}" == "${v}" ]]; then
skip=1
fi
done
if [ "${skip}" -eq 0 ]; then
no_opts=$((no_opts + 1))
fi
fi
h=$((h + 1))
fi
done
case "${no_opts}" in
0)
return 0
;;
1)
local files=$(ls -d ${cur}* 2> /dev/null | grep -Eiv '*\.('${HIDDEN_FILES_AGGRESIVE}')' 2> /dev/null)
COMPREPLY=($(compgen -W "${files}" -- ${cur}))
return 0
;;
*)
case "${attack_mode}" in
0)
# dict/directory are files here
local files=$(ls -d ${cur}* 2> /dev/null | grep -Eiv '*\.('${HIDDEN_FILES_AGGRESIVE}')' 2> /dev/null)
COMPREPLY=($(compgen -W "${files}" -- ${cur}))
return 0
;;
1)
if [ "${no_opts}" -gt 4 ]; then
return 0
fi
local files=$(ls -d ${cur}* 2> /dev/null | grep -Eiv '*\.('${HIDDEN_FILES_AGGRESIVE}')' 2> /dev/null)
COMPREPLY=($(compgen -W "${files}" -- ${cur}))
return 0
;;
3)
if [ "${no_opts}" -eq 2 ]; then
local mask=${BUILD_IN_CHARSETS}
if [ "${has_charset_1}" -eq 1 ]; then
mask="${mask} ?1"
fi
if [ "${has_charset_2}" -eq 1 ]; then
mask="${mask} ?2"
fi
if [ "${has_charset_3}" -eq 1 ]; then
mask="${mask} ?3"
fi
if [ "${has_charset_4}" -eq 1 ]; then
mask="${mask} ?4"
fi
if [ -e "${cur}" ]; then # should be hcmask file (but not enforced)
COMPREPLY=($(compgen -W "${cur}" -- ${cur}))
return 0
fi
if [ -n "${cur}" ]; then
local cur_var=$(echo "${cur}" | sed 's/\?$//')
mask="${mask} ${cur_var}"
local h
for h in ${mask}; do
mask="${mask} ${cur_var}${h}"
done
fi
local files=$(ls -d ${cur}* 2> /dev/null | grep -Eiv '*\.('${HIDDEN_FILES}')' 2> /dev/null)
mask="${mask} ${files}"
COMPREPLY=($(compgen -W "${mask}" -- ${cur}))
return 0
fi
;;
6)
if [ "${no_opts}" -eq 2 ]; then
local files=$(ls -d ${cur}* 2> /dev/null | grep -Eiv '*\.('${HIDDEN_FILES_AGGRESIVE}')' 2> /dev/null)
COMPREPLY=($(compgen -W "${files}" -- ${cur}))
elif [ "${no_opts}" -eq 3 ]; then
local mask=${BUILD_IN_CHARSETS}
if [ "${has_charset_1}" -eq 1 ]; then
mask="${mask} ?1"
fi
if [ "${has_charset_2}" -eq 1 ]; then
mask="${mask} ?2"
fi
if [ "${has_charset_3}" -eq 1 ]; then
mask="${mask} ?3"
fi
if [ "${has_charset_4}" -eq 1 ]; then
mask="${mask} ?4"
fi
if [ -e "${cur}" ]; then # should be hcmask file (but not enforced)
COMPREPLY=($(compgen -W "${cur}" -- ${cur}))
return 0
fi
if [ -n "${cur}" ]; then
local cur_var=$(echo "${cur}" | sed 's/\?$//')
mask="${mask} ${cur_var}"
local h
for h in ${mask}; do
mask="${mask} ${cur_var}${h}"
done
fi
local files=$(ls -d ${cur}* 2> /dev/null | grep -Eiv '*\.('${HIDDEN_FILES}')' 2> /dev/null)
mask="${mask} ${files}"
COMPREPLY=($(compgen -W "${mask}" -- ${cur}))
return 0
fi
;;
7)
if [ "${no_opts}" -eq 2 ]; then
local mask=${BUILD_IN_CHARSETS}
if [ "${has_charset_1}" -eq 1 ]; then
mask="${mask} ?1"
fi
if [ "${has_charset_2}" -eq 1 ]; then
mask="${mask} ?2"
fi
if [ "${has_charset_3}" -eq 1 ]; then
mask="${mask} ?3"
fi
if [ "${has_charset_4}" -eq 1 ]; then
mask="${mask} ?4"
fi
if [ -e "${cur}" ]; then # should be hcmask file (but not enforced)
COMPREPLY=($(compgen -W "${cur}" -- ${cur}))
return 0
fi
if [ -n "${cur}" ]; then
local cur_var=$(echo "${cur}" | sed 's/\?$//')
mask="${mask} ${cur_var}"
local h
for h in ${mask}; do
mask="${mask} ${cur_var}${h}"
done
fi
local files=$(ls -d ${cur}* 2> /dev/null | grep -Eiv '*\.('${HIDDEN_FILES}')' 2> /dev/null)
mask="${mask} ${files}"
COMPREPLY=($(compgen -W "${mask}" -- ${cur}))
return 0
elif [ "${no_opts}" -eq 3 ]; then
local files=$(ls -d ${cur}* 2> /dev/null | grep -Eiv '*\.('${HIDDEN_FILES_AGGRESIVE}')' 2> /dev/null)
COMPREPLY=($(compgen -W "${files}" -- ${cur}))
return
fi
;;
esac
esac
}
complete -F _hashcat -o filenames "${HASHCAT_ROOT}"/hashcat.bin "${HASHCAT_ROOT}"/hashcat hashcat