PageRenderTime 57ms CodeModel.GetById 31ms RepoModel.GetById 0ms app.codeStats 1ms

/usr/src/boot/forth/check-password.4th

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