1

Я пытаюсь создать очень простую консоль входа в систему для сценария, который у меня есть, просто для удовольствия посмотреть, работает ли он.

По сути, я думал, что это возможно.

Я прочитаю в файле $password_file и в файле $username_file если есть определенный шаблон. Допустим, я поместил в обоих файлах "Брайан" в первую строку (или любую другую строку). Теперь я хочу поместить этот кусок кода, прежде чем скрипт продолжит выполнять свои основные функции.

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

Я думаю, что я делаю что-то не так, потому что я получаю сообщение об ошибке, что есть неожиданный токен рядом с else .

Поэтому я просто хочу, чтобы оператор if сначала читал $username_file , затем, если шаблон bryan находится в этом файле, я хочу, чтобы он читал $password_file , после чего я хочу, чтобы скрипт продолжал переходить к определенной строке в скрипт, на котором начинается нормальный скрипт, который я написал.

Надеюсь, я все правильно объяснил, чтобы вы меня поняли.

(Я также могу расширить этот маленький скрипт, добавив что-то вроде: если имя пользователя или пароль не находятся в этом файле, echo "not found, скрипт перезагрузит попытку снова".)

3 ответа3

2

Проблема в том, что bash интерпретирует это как then; else ; поставить : в этой строке.

Если каждая строка состоит только из того, что вы ищете, вы также можете использовать 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
2

Здесь есть ряд проблем:

  • Там нет никаких команд в then части вашего внутренних , if заявления, которое вызывает ошибку , которую вы видите. Эту проблему можно решить либо с помощью псевдокоманды-заполнителя : в части then , либо отменив тест и пропустив раздел else .

  • Команда sed также недопустима, и в любом случае это неправильный инструмент для работы. Для поиска файла по определенной строке grep обычно является предпочтительной командой. В этом случае, вероятно, лучше использовать grep -Fx для сопоставления всего текста (-F) с открытым текстом (-x).

  • Логика if ... if ... else также отключена. Я предполагаю, что вы хотите выйти, если имя пользователя или пароль не найдены, но (как написано) предложение else выполняется только в том случае, если имя пользователя было найдено, а пароль не был. Чтобы это исправить, используйте что-то вроде этого:

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

    Или, может быть:

    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
    
  • На самом деле, эта логика все еще неверна; все, что он проверяет, это то, что имя пользователя и пароль существуют в их соответствующих файлах, а не в том, что они идут вместе. Я мог бы ввести свой пароль и имя другого пользователя, и он позволил бы мне войти. Вы должны убедиться, что имя пользователя и пароль совпадают, возможно, поместив их в один файл и выполнив поиск сразу:

    if ! grep -Fxq "$username:$password" "$user_file" ; then
        echo "Invalid login"
        exit 1
    fi
    
  • Наконец, хранение паролей (даже в файле, который может прочитать только root) - очень плохая идея - хешировать пароль и хранить вместо него хеш. На самом деле, для лучшей безопасности вы должны использовать соленый хеш, который усложняет поиск - вы должны найти запись пользователя, вычислить соль, которая использовалась с его паролем, хэшировать то, что пользователь набрал с той же солью, и сравнить это с что в файле. Это, в свою очередь, означает, что grep -Fx больше не будет работать, нам нужно использовать grep в режиме, который выполняет сопоставление с шаблоном и быть осторожным, чтобы избежать метасимволов шаблона в имени пользователя ...

Вот быстрый пример, если у вас есть openssl:

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#\$1\$}"
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

Чтобы создать записи в пользовательском файле, используйте что-то вроде этого:

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

Я не обещаю, что вышесказанное не содержит ошибок; Я только что провел несколько базовых тестов.

0

Это звучит как проблема XY.

почему ты хочешь сделать это? Как показывает отличный ответ @Gordon Davisson, это сложнее, чем вы думаете. Не только проблемы с безопасностью, но и не все пароли Unix хранятся в /etc /passwd. Так что либо вам придется переделать многое из того, что PAM уже делает.

Быстрая идея, может быть, вы хотите сделать что-то вроде

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

Если su не работает, значит, у них нет пароля. Тогда пройдено будет пустым. Используя su, вы пройдете все обычные процедуры паролей, используя pam при необходимости, и вам не нужно будет ничего поддерживать.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .