Почему ввод пароля работает в конвейерной команде sudo?

25

Если я сделаю:

sudo cat /etc/resolv.conf | less

Он запросит у меня пароль, хотя меньше (предположительно) занимает стандартный ввод. По каким файлам отображается запрос пароля и как он возвращает ввод?

Karlo
источник

Ответы:

48

На самом деле, типичный вызов sudoвообще не читает пароль stdin. Вместо этого он sudoполучит прямой доступ к управляющему терминалу (a ttyили ptyчерез /dev/ttyспециальный файл) и выведет подсказку и прочитает символы напрямую. Это можно увидеть в tgetpass.cфайле в sudoисточнике.

Есть несколько других сценариев:

  • Если askpassуказана программа, например, в -Aпараметре, эта программа будет вызвана.
  • В противном случае, если вы специально запросите sudoчтение stdin, например, с -Sфлагом - и он также напишет приглашение stderr. Это тот случай, когда ответ MadHatter применяется.
  • В противном случае, если нет в ttyналичии
    • Если эхо пароля отключено (по умолчанию оно контролируется visiblepwфлагом в sudoers), sudoпоявится сообщение об ошибке:no tty present and no askpass program specified
    • В противном случае sudoвернется к использованию stdinи stderrдаже если это не было специально запрошено. Ответ MadHatter также будет применяться здесь.
боб
источник
10

Канал соединяет стандартный sudo catвывод lessсо стандартным, поэтому стандартный sudo catввод не затрагивается и может получить пароль.

Что касается подсказки, она выходит на sudo cats stderr; в bash, попробуйте перенаправить это вместе с stdout, используя

sudo cat /etc/resolv.conf |& less

и посмотрите, насколько отличается ответ.

MadHatter поддерживает Монику
источник
16
Хотя этот ответ верен в том sudoсмысле, что stdin все еще подключен к терминалу с помощью команды примера, это не имеет прямого отношения к тому, как он получает свой пароль: по умолчанию sudoон не запрашивает пароли через stdin и не отображает приглашение через stderr- вы могу попытаться 2>/dev/nullэто подтвердить. Вместо этого sudoнапрямую обращается к tty.
Боб