|
#!/bin/bash |
|
|
|
# .htpasswd Manager Script |
|
# |
|
# Changelog: |
|
# [2025-09-02] |
|
# - Adicionado tratamento para interrupção com CTRL+C (trap). |
|
# - Aceita arquivo diretamente sem precisar de -f/--file. |
|
# - Evita duplicação de usuários ao adicionar. |
|
# - Ajustado formato de comentários (# Added / # Modified) para linha separada (melhor compatibilidade). |
|
# - Ajustado chmod 600 no arquivo de senhas por segurança. |
|
# - Melhorias na listagem de usuários (exibe só username). |
|
|
|
# Trap para CTRL+C |
|
trap 'echo -e "\n\n⚠️ Interrompido pelo usuário. Saindo..."; exit 130' INT |
|
|
|
# Verifica parâmetro |
|
if [[ "$1" == "-f" || "$1" == "--file" ]]; then |
|
HTPASSWD_FILE="$2" |
|
else |
|
HTPASSWD_FILE="$1" |
|
fi |
|
|
|
if [[ -z "$HTPASSWD_FILE" ]]; then |
|
echo "Uso: $0 [-f|--file] <arquivo.htpasswd>" |
|
exit 1 |
|
fi |
|
|
|
# Verifica se arquivo existe, senão cria |
|
if [[ ! -f "$HTPASSWD_FILE" ]]; then |
|
echo "⚠️ Arquivo $HTPASSWD_FILE não existe. Criando..." |
|
touch "$HTPASSWD_FILE" |
|
fi |
|
|
|
# Garante permissões seguras |
|
chmod 600 "$HTPASSWD_FILE" |
|
|
|
# Função: adicionar usuário |
|
add_user() { |
|
read -p "Digite o nome do usuário: " username |
|
|
|
if grep -q "^$username:" "$HTPASSWD_FILE"; then |
|
echo "❌ Erro: usuário '$username' já existe." |
|
return |
|
fi |
|
|
|
read -s -p "Digite a senha: " password |
|
echo |
|
timestamp=$(date +"%Y-%m-%d %H:%M:%S") |
|
encrypted=$(echo "$password" | openssl passwd -apr1 -stdin) |
|
{ |
|
echo "# Added $timestamp" |
|
echo "$username:$encrypted" |
|
} >> "$HTPASSWD_FILE" |
|
echo "✅ Usuário '$username' adicionado com sucesso." |
|
} |
|
|
|
# Função: listar usuários |
|
list_users() { |
|
echo "📜 Usuários em $HTPASSWD_FILE:" |
|
grep -v "^#" "$HTPASSWD_FILE" | awk -F: '{print NR ") " $1}' |
|
} |
|
|
|
# Função: deletar usuário |
|
delete_user() { |
|
list_users |
|
read -p "Digite o número do usuário para excluir: " user_number |
|
if [[ ! "$user_number" =~ ^[0-9]+$ ]]; then |
|
echo "❌ Erro: digite um número válido." |
|
return |
|
fi |
|
total_users=$(grep -vc "^#" "$HTPASSWD_FILE") |
|
if [[ "$user_number" -lt 1 || "$user_number" -gt "$total_users" ]]; then |
|
echo "❌ Erro: número inválido." |
|
return |
|
fi |
|
temp_file=$(mktemp) |
|
awk -F: -v n="$user_number" 'BEGIN{c=0} !/^#/ {c++} c!=n {print}' "$HTPASSWD_FILE" > "$temp_file" |
|
mv "$temp_file" "$HTPASSWD_FILE" |
|
echo "🗑️ Usuário removido com sucesso." |
|
} |
|
|
|
# Função: editar usuário |
|
edit_user() { |
|
list_users |
|
read -p "Digite o número do usuário para editar: " user_number |
|
if [[ ! "$user_number" =~ ^[0-9]+$ ]]; then |
|
echo "❌ Erro: digite um número válido." |
|
return |
|
fi |
|
total_users=$(grep -vc "^#" "$HTPASSWD_FILE") |
|
if [[ "$user_number" -lt 1 || "$user_number" -gt "$total_users" ]]; then |
|
echo "❌ Erro: número inválido." |
|
return |
|
fi |
|
username=$(grep -v "^#" "$HTPASSWD_FILE" | awk -F: -v n="$user_number" 'NR == n {print $1}') |
|
read -s -p "Digite a nova senha para $username: " password |
|
echo |
|
timestamp=$(date +"%Y-%m-%d %H:%M:%S") |
|
encrypted=$(echo "$password" | openssl passwd -apr1 -stdin) |
|
temp_file=$(mktemp) |
|
# Remove linha antiga e adiciona nova |
|
awk -F: -v n="$user_number" 'BEGIN{c=0} !/^#/ {c++} c!=n {print}' "$HTPASSWD_FILE" > "$temp_file" |
|
{ |
|
echo "# Modified $timestamp" |
|
echo "$username:$encrypted" |
|
} >> "$temp_file" |
|
mv "$temp_file" "$HTPASSWD_FILE" |
|
echo "✏️ Usuário '$username' atualizado com sucesso." |
|
} |
|
|
|
# Menu principal |
|
while true; do |
|
echo -e "\n===== .htpasswd Manager =====" |
|
echo "1) Adicionar usuário" |
|
echo "2) Excluir usuário" |
|
echo "3) Editar usuário" |
|
echo "Q) Sair" |
|
read -p "Escolha uma opção: " choice |
|
|
|
case $choice in |
|
1) add_user ;; |
|
2) delete_user ;; |
|
3) edit_user ;; |
|
[Qq]) echo "👋 Saindo..."; exit 0 ;; |
|
*) echo "❌ Opção inválida." ;; |
|
esac |
|
done |
|
|
|
// fonte: https://grok.com/share/bGVnYWN5_ffc94a5e-6a99-4afb-8529-2449da2ccb8e |
|
// rev2: https://chatgpt.com/c/68b71b53-2d74-8325-82f5-36c5fdb7d748 |