vlock.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * vlock implementation for busybox
  4. *
  5. * Copyright (C) 2000 by spoon <spoon@ix.netcom.com>
  6. * Written by spoon <spon@ix.netcom.com>
  7. *
  8. * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
  9. */
  10. /* Shoutz to Michael K. Johnson <johnsonm@redhat.com>, author of the
  11. * original vlock. I snagged a bunch of his code to write this
  12. * minimalistic vlock.
  13. */
  14. /* Fixed by Erik Andersen to do passwords the tinylogin way...
  15. * It now works with md5, sha1, etc passwords. */
  16. #include <sys/vt.h>
  17. #include "libbb.h"
  18. static void release_vt(int signo UNUSED_PARAM)
  19. {
  20. /* If -a, param is 0, which means:
  21. * "no, kernel, we don't allow console switch away from us!" */
  22. ioctl(STDIN_FILENO, VT_RELDISP, (unsigned long) !option_mask32);
  23. }
  24. static void acquire_vt(int signo UNUSED_PARAM)
  25. {
  26. /* ACK to kernel that switch to console is successful */
  27. ioctl(STDIN_FILENO, VT_RELDISP, VT_ACKACQ);
  28. }
  29. int vlock_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  30. int vlock_main(int argc UNUSED_PARAM, char **argv)
  31. {
  32. struct vt_mode vtm;
  33. struct termios term;
  34. struct termios oterm;
  35. struct vt_mode ovtm;
  36. struct passwd *pw;
  37. pw = xgetpwuid(getuid());
  38. opt_complementary = "=0"; /* no params! */
  39. getopt32(argv, "a");
  40. /* Ignore some signals so that we don't get killed by them */
  41. bb_signals(0
  42. + (1 << SIGTSTP)
  43. + (1 << SIGTTIN)
  44. + (1 << SIGTTOU)
  45. + (1 << SIGHUP )
  46. + (1 << SIGCHLD) /* paranoia :) */
  47. + (1 << SIGQUIT)
  48. + (1 << SIGINT )
  49. , SIG_IGN);
  50. /* We will use SIGUSRx for console switch control: */
  51. /* 1: set handlers */
  52. signal_SA_RESTART_empty_mask(SIGUSR1, release_vt);
  53. signal_SA_RESTART_empty_mask(SIGUSR2, acquire_vt);
  54. /* 2: unmask them */
  55. sig_unblock(SIGUSR1);
  56. sig_unblock(SIGUSR2);
  57. /* Revert stdin/out to our controlling tty
  58. * (or die if we have none) */
  59. xmove_fd(xopen(CURRENT_TTY, O_RDWR), STDIN_FILENO);
  60. xdup2(STDIN_FILENO, STDOUT_FILENO);
  61. xioctl(STDIN_FILENO, VT_GETMODE, &vtm);
  62. ovtm = vtm;
  63. /* "console switches are controlled by us, not kernel!" */
  64. vtm.mode = VT_PROCESS;
  65. vtm.relsig = SIGUSR1;
  66. vtm.acqsig = SIGUSR2;
  67. ioctl(STDIN_FILENO, VT_SETMODE, &vtm);
  68. tcgetattr(STDIN_FILENO, &oterm);
  69. term = oterm;
  70. term.c_iflag &= ~BRKINT;
  71. term.c_iflag |= IGNBRK;
  72. term.c_lflag &= ~ISIG;
  73. term.c_lflag &= ~(ECHO | ECHOCTL);
  74. tcsetattr_stdin_TCSANOW(&term);
  75. do {
  76. printf("Virtual console%s locked by %s.\n",
  77. option_mask32 /*o_lock_all*/ ? "s" : "",
  78. pw->pw_name);
  79. if (correct_password(pw)) {
  80. break;
  81. }
  82. bb_do_delay(FAIL_DELAY);
  83. puts("Password incorrect");
  84. } while (1);
  85. ioctl(STDIN_FILENO, VT_SETMODE, &ovtm);
  86. tcsetattr_stdin_TCSANOW(&oterm);
  87. fflush_stdout_and_exit(EXIT_SUCCESS);
  88. }