Declaração if simples que verifica se a linha está em um arquivo

1

Eu estou tentando criar um console de login muito simples para um script que eu tenho, isso é apenas por diversão para ver se funciona.

Basicamente, o que eu pensei que seria possível é isso.

Eu vou ler no arquivo $password_file e no arquivo $username_file se houver um certo padrão. Vamos dizer que eu coloquei os dois arquivos "bryan" na primeira linha (ou qualquer outra linha). Agora quero colocar este trecho de código antes que o script continue com suas funções básicas.

echo "Welcome"
echo "Ur username is:"
read username
echo "Ur password is:"
read password
if sed -n "/$username/" $username_file; then
    if sed -n "/$password" $password_file; then

else
    exit;
    fi
fi

Acho que estou fazendo algo errado aqui, porque estou recebendo um erro informando que há um token inesperado perto do else .

Então, basicamente, eu só quero que a instrução if primeiro leia $username_file , então se o padrão bryan estiver nesse arquivo, eu quero ler o $password_file , depois disso eu quero que o script continue a vá para uma certa linha no script no qual o script normal que eu escrevi começa.

Espero ter explicado corretamente, para que você possa me entender.

(Eu também posso expandir este pequeno script adicionando algo como, se nome de usuário ou senha não estiver nesse arquivo echo "não encontrado, o script será recarregado tente novamente".)

    
por bryan 05.06.2011 / 23:31

3 respostas

2

O problema é que o bash está interpretando como then; else ; coloque um : nessa linha.

Se cada linha é composta apenas pelo que você está procurando, você também pode usar fgrep -x :

echo "Welcome"
echo "Username:"
read username
echo "Password:"
read password
if ! (fgrep -qx "$username" $username_file && fgrep -qx "$password" $password_file); then
    exit
fi
    
por 06.06.2011 / 00:50
2

Existem vários problemas aqui:

  • Não há comandos na parte then de sua instrução if interna, que está causando o erro que você vê. Você poderia resolver isso usando o marcador de posição pseudocommand : na parte then ou negando o teste e deixando de fora a seção else .

  • O comando sed também é inválido e, de qualquer forma, é a ferramenta errada para o trabalho. Para pesquisar um arquivo em uma linha específica, grep geralmente é o comando escolhido. Nesse caso, grep -Fx para fazer uma correspondência de linha inteira ( -F ) ( -x ) é provavelmente melhor.

  • A lógica if ... if ... else está desativada também. Eu suponho que você quer sair se o nome de usuário ou senha não for encontrado, mas (como escrito) a cláusula else só é executada se o nome de usuário foi encontrado, e a senha não foi. Para corrigir isso, use algo assim:

    if ! grep -Fxq "$username" "$username_file" || ! grep -Fxq "$password" "$password_file"; then
        echo "Invalid login"
        exit 1
    fi
    

    Ou talvez:

    if ! grep -Fxq "$username" "$username_file"; then
        echo "User $username not found"
        exit 1
    elif ! grep -Fxq "$password" "$password_file"; then
        echo "Incorrect password"
        exit 1
    fi
    
  • Na verdade, essa lógica ainda está errada; tudo o que verifica é que o nome de usuário e a senha existem em seus respectivos arquivos, não que eles estejam juntos. Eu poderia digitar minha senha e o nome de usuário de outra pessoa, e ela me permitiria entrar. Você precisa verificar se o nome de usuário e a senha estão juntos, provavelmente colocando-os no mesmo arquivo e pesquisando os dois de uma só vez:

    if ! grep -Fxq "$username:$password" "$user_file" ; then
        echo "Invalid login"
        exit 1
    fi
    
  • Finalmente, armazenar senhas (mesmo em um arquivo que somente o root pode ler) é uma péssima idéia - use a senha e armazene o hash. Na verdade, para melhor segurança, você deve usar um hash salgado, o que complica a busca - você precisa encontrar a entrada do usuário, descobrir o sal que foi usado com sua senha, dividir o usuário com o mesmo sal e compará-lo com O que há no arquivo? Isso, por sua vez, significa que grep -Fx não funcionará mais, precisamos usar grep em um modo que faça correspondência de padrões e tenha cuidado para evitar metacaracteres de padrão no nome de usuário ...

Aqui está uma rápida tentativa, supondo que você tenha o openssl disponível:

echo "Welcome"
read -p "Ur username is: " username
if [[ "$username" =~ "[][(){}*.?+|^\$]" ]]; then
    echo "Illegal character in username"
    exit 1
fi

# Find the user's record in the file
user_record="$(grep "^$username:" "$user_file")"
if [[ -z "$user_record" ]]; then
    echo "User $username not found"
    exit 1
fi
# Parse out the user's hashed password and salt
recordedhash="${user_record#*:}"
if [[ "$recordedhash" != '$1$'* ]]; then
    echo "Invalid user record for $username"
    exit 1
fi
salt="${recordedhash#\\$}"
salt="${salt%\$*}"

read -p "Ur password is: " -s password
echo
if [[ "$(printf "%s" "$password" | openssl passwd -1 -stdin -salt "$salt")" != "$recordedhash" ]]; then
    echo "Incorrect password"
    exit 1
fi

Para criar entradas no arquivo do usuário, use algo assim:

read -p "Ur username is: " username
if [[ "$username" =~ "[][(){}*.?+|^\$]" ]]; then
    echo "Illegal character in username"
    exit 1
fi
read -p "Ur password is: " -s password
echo
hashedpw="$(printf "%s" "$password" | openssl passwd -1 -stdin)"
user_record="$username:$hashedpw"
# Then do something to add $user_record to the file, or replace the existing record if there is one

Eu não faço promessas de que o acima é livre de bugs; Acabei de fazer alguns testes básicos sobre isso.

    
por 06.06.2011 / 02:15
0

Isso soa como um problema XY .

Por que você quer fazer isso? Como a excelente resposta do @Gordon Davisson mostra, isso é mais difícil do que você pensa. Não só há questões de segurança para pensar, senhas unix não são todas armazenadas em / etc / passwd. Então ou você terá que refazer muito do que o PAM já faz.

Uma ideia rápida, talvez você queira fazer algo como

PASSED = $ (su $ USER -c "echo LOGIN")

Se o su falhar, eles não terão a senha. Então PASSED ficará em branco. Usando su, você passará por todas as rotinas normais de senha, usando o pam, se necessário, e não precisará manter nada.

    
por 06.06.2011 / 02:24

Tags