/sys/boot/forth/check-password.4th

https://bitbucket.org/iorivur/freebsd-bhyve-with-suspend-resume · Forth · 170 lines · 135 code · 35 blank · 0 comment · 17 complexity · 75fb9af7c50739da2c8b1427e2098d63 MD5 · raw file

  1. \ Copyright (c) 2006-2012 Devin Teske <dteske@FreeBSD.org>
  2. \ All rights reserved.
  3. \
  4. \ Redistribution and use in source and binary forms, with or without
  5. \ modification, are permitted provided that the following conditions
  6. \ are met:
  7. \ 1. Redistributions of source code must retain the above copyright
  8. \ notice, this list of conditions and the following disclaimer.
  9. \ 2. Redistributions in binary form must reproduce the above copyright
  10. \ notice, this list of conditions and the following disclaimer in the
  11. \ documentation and/or other materials provided with the distribution.
  12. \
  13. \ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  14. \ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  15. \ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  16. \ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  17. \ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  18. \ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  19. \ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  20. \ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  21. \ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  22. \ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  23. \ SUCH DAMAGE.
  24. \
  25. \ $FreeBSD: head/sys/boot/forth/check-password.4th 244158 2012-12-12 17:49:01Z dteske $
  26. marker task-check-password.4th
  27. include /boot/screen.4th
  28. 13 constant enter_key \ The decimal ASCII value for Enter key
  29. 8 constant bs_key \ The decimal ASCII value for Backspace key
  30. 16 constant readmax \ Maximum number of characters for the password
  31. variable readX \ Current X offset (column)(used by read)
  32. variable read-start \ Starting X offset (column)(used by read)
  33. create readval 16 allot \ input obtained (maximum 16 characters)
  34. variable readlen \ input length
  35. \ This function blocks program flow (loops forever) until a key is pressed.
  36. \ The key that was pressed is added to the top of the stack in the form of its
  37. \ decimal ASCII representation. Note: the stack cannot be empty when this
  38. \ function starts or an underflow exception will occur. Simplest way to prevent
  39. \ this is to pass 0 as a stack parameter (ie. `0 sgetkey'). This function is
  40. \ called by the read function. You need not call it directly. NOTE: arrow keys
  41. \ show as 0 on the stack
  42. \
  43. : sgetkey ( -- )
  44. begin \ Loop forever
  45. key? if \ Was a key pressed? (see loader(8))
  46. drop \ Remove stack-cruft
  47. key \ Get the key that was pressed
  48. \ Check key pressed (see loader(8)) and input limit
  49. dup 0<> if ( and ) readlen @ readmax < if
  50. \ Echo an asterisk (unless Backspace/Enter)
  51. dup bs_key <> if ( and ) dup enter_key <> if
  52. ." *" \ Echo an asterisk
  53. then then
  54. exit \ Exit from the function
  55. then then
  56. \ Always allow Backspace and Enter
  57. dup bs_key = if exit then
  58. dup enter_key = if exit then
  59. then
  60. 50 ms \ Sleep for 50 milliseconds (see loader(8))
  61. again
  62. ;
  63. : read ( String prompt -- )
  64. 0 25 at-xy \ Move the cursor to the bottom-left
  65. dup 1+ read-start ! \ Store X offset after the prompt
  66. read-start @ readX ! \ copy value to the current X offset
  67. 0 readlen ! \ Initialize the read length
  68. type \ Print the prompt
  69. begin \ Loop forever
  70. 0 sgetkey \ Block here, waiting for a key to be pressed
  71. \ We are not going to echo the password to the screen (for
  72. \ security reasons). If Enter is pressed, we process the
  73. \ password, otherwise augment the key to a string.
  74. \ If the key that was entered was not Enter, advance
  75. dup enter_key <> if
  76. readX @ 1+ readX ! \ Advance the column
  77. readlen @ 1+ readlen ! \ Increment input length
  78. then
  79. \ Handle backspacing
  80. dup bs_key = if
  81. readX @ 2 - readX ! \ Set new cursor position
  82. readlen @ 2 - readlen ! \ Decrement input length
  83. \ Don't move behind starting position
  84. readX @ read-start @ < if
  85. read-start @ readX !
  86. then
  87. readlen @ 0< if
  88. 0 readlen !
  89. then
  90. \ Reposition cursor and erase character
  91. readX @ 25 at-xy 1 spaces readX @ 25 at-xy
  92. then
  93. dup enter_key = if
  94. drop \ Clean up stack cruft
  95. 10 emit \ Echo new line
  96. exit
  97. then
  98. \ If not Backspace or Enter, store the character
  99. dup bs_key <> if ( and ) dup enter_key <> if
  100. \ store the character in our buffer
  101. dup readval readlen @ 1- + c!
  102. then then
  103. drop \ drop the last key that was entered
  104. again \ Enter was not pressed; repeat
  105. ;
  106. : check-password ( -- )
  107. \ Do not allow the user to proceed beyond this point if a boot-lock
  108. \ password has been set (preventing even boot from proceeding)
  109. s" bootlock_password" getenv dup -1 <> if
  110. begin
  111. s" Boot Password: " read ( prompt -- )
  112. 2dup readval readlen @ compare 0<>
  113. while
  114. 3000 ms ." loader: incorrect password" 10 emit
  115. repeat
  116. 2drop ( c-addr/u )
  117. else
  118. drop ( -1 ) \ getenv cruft
  119. then
  120. \ Exit if a password was not set
  121. s" password" getenv -1 = if exit else drop then
  122. \ We should prevent the user from visiting the menu or dropping to the
  123. \ interactive loader(8) prompt, but still allow the machine to boot...
  124. 0 autoboot
  125. \ Only reached if autoboot fails for any reason (including if/when
  126. \ the user aborts/escapes the countdown sequence leading to boot).
  127. s" password" getenv
  128. begin
  129. s" Password: " read ( prompt -- )
  130. 2dup readval readlen @ compare 0= if
  131. 2drop exit \ Correct password
  132. then
  133. 3000 ms ." loader: incorrect password" 10 emit
  134. again
  135. ;