PageRenderTime 53ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/stand/forth/check-password.4th

https://bitbucket.org/freebsd/freebsd-base
Forth | 180 lines | 151 code | 29 blank | 0 comment | 35 complexity | d50d5002b31f4097a6cdc6d6952dc5e3 MD5 | raw file
  1. \ Copyright (c) 2006-2015 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$
  26. marker task-check-password.4th
  27. include /boot/screen.4th
  28. vocabulary password-processing
  29. only forth also password-processing definitions
  30. 13 constant enter_key \ The decimal ASCII value for Enter key
  31. 8 constant bs_key \ The decimal ASCII value for Backspace key
  32. 21 constant ctrl_u \ The decimal ASCII value for Ctrl-U sequence
  33. 255 constant readmax \ Maximum number of characters for the password
  34. variable read-tick \ Twiddle position (used by read)
  35. variable read-start \ Starting X offset (column)(used by read)
  36. create readval readmax allot \ input obtained (up to readmax characters)
  37. variable readlen \ input length
  38. \ This function blocks program flow (loops forever) until a key is pressed.
  39. \ The key that was pressed is added to the top of the stack in the form of its
  40. \ decimal ASCII representation. Note: the stack cannot be empty when this
  41. \ function starts or an underflow exception will occur. Simplest way to prevent
  42. \ this is to pass 0 as a stack parameter (ie. `0 sgetkey'). This function is
  43. \ called by the read function. You need not call it directly. NOTE: arrow keys
  44. \ show as 0 on the stack
  45. \
  46. : sgetkey ( -- )
  47. begin \ Loop forever
  48. key? if \ Was a key pressed? (see loader(8))
  49. drop \ Remove stack-cruft
  50. key \ Get the key that was pressed
  51. \ Check key pressed (see loader(8)) and input limit
  52. dup 0<> if ( and ) readlen @ readmax < if
  53. \ Spin the twiddle and then exit this function
  54. read-tick @ dup 1+ 4 mod read-tick !
  55. 2 spaces
  56. dup 0 = if ( 1 ) ." /" else
  57. dup 1 = if ( 2 ) ." -" else
  58. dup 2 = if ( 3 ) ." \" else
  59. dup 3 = if ( 4 ) ." |" else
  60. 1 spaces
  61. then then then then drop
  62. read-start @ 25 at-xy
  63. exit
  64. then then
  65. \ Always allow Backspace, Enter, and Ctrl-U
  66. dup bs_key = if exit then
  67. dup enter_key = if exit then
  68. dup ctrl_u = if exit then
  69. then
  70. 50 ms \ Sleep for 50 milliseconds (see loader(8))
  71. again
  72. ;
  73. : cfill ( c c-addr/u -- )
  74. begin dup 0> while
  75. -rot 2dup c! 1+ rot 1-
  76. repeat 2drop drop
  77. ;
  78. : read-reset ( -- )
  79. 0 readlen !
  80. 0 readval readmax cfill
  81. ;
  82. : read ( c-addr/u -- ) \ Expects string prompt as stack input
  83. 0 25 at-xy \ Move the cursor to the bottom-left
  84. dup 1+ read-start ! \ Store X offset after the prompt
  85. 0 readlen ! \ Initialize the read length
  86. type \ Print the prompt
  87. begin \ Loop forever
  88. 0 sgetkey \ Block here, waiting for a key to be pressed
  89. \ We are not going to echo the password to the screen (for
  90. \ security reasons). If Enter is pressed, we process the
  91. \ password, otherwise augment the key to a string.
  92. dup enter_key = if
  93. drop \ Clean up stack cruft
  94. 3 spaces \ Erase the twiddle
  95. 10 emit \ Echo new line
  96. exit
  97. else dup ctrl_u = if
  98. 3 spaces read-start @ 25 at-xy \ Erase the twiddle
  99. 0 readlen ! \ Reset input to NULL
  100. else dup bs_key = if
  101. readlen @ 1 - dup readlen ! \ Decrement input length
  102. dup 0< if drop 0 dup readlen ! then \ Don't go negative
  103. 0= if 3 spaces read-start @ 25 at-xy then \ Twiddle
  104. else dup \ Store the character
  105. \ NB: sgetkey prevents overflow by way of blocking
  106. \ at readmax except for Backspace or Enter
  107. readlen @ 1+ dup readlen ! 1- readval + c!
  108. then then then
  109. drop \ last key pressed
  110. again \ Enter was not pressed; repeat
  111. ;
  112. only forth definitions also password-processing also support-functions
  113. : check-password ( -- )
  114. \ Do not allow the user to proceed beyond this point if a boot-lock
  115. \ password has been set (preventing even boot from proceeding)
  116. s" bootlock_password" getenv dup -1 <> if
  117. dup readmax > if drop readmax then
  118. begin
  119. s" Boot Password: " read ( prompt -- )
  120. 2dup readval readlen @ compare 0<>
  121. while
  122. 3000 ms ." loader: incorrect password" 10 emit
  123. repeat
  124. 2drop read-reset
  125. else drop then
  126. \ Prompt for GEOM ELI (geli(8)) passphrase if enabled
  127. s" geom_eli_passphrase_prompt" getenv dup -1 <> if
  128. s" YES" compare-insensitive 0= if
  129. s" GELI Passphrase: " read ( prompt -- )
  130. readval readlen @ s" kern.geom.eli.passphrase" setenv
  131. read-reset
  132. then
  133. else drop then
  134. \ Exit if a password was not set
  135. s" password" getenv -1 = if exit else drop then
  136. \ We should prevent the user from visiting the menu or dropping to the
  137. \ interactive loader(8) prompt, but still allow the machine to boot...
  138. any_conf_read? if load_kernel load_modules then
  139. 0 autoboot
  140. \ Only reached if autoboot fails for any reason (including if/when
  141. \ the user aborts/escapes the countdown sequence leading to boot).
  142. s" password" getenv dup readmax > if drop readmax then
  143. begin
  144. s" Password: " read ( prompt -- )
  145. 2dup readval readlen @ compare 0= if \ Correct password?
  146. 2drop read-reset exit
  147. then
  148. 3000 ms ." loader: incorrect password" 10 emit
  149. again
  150. ;
  151. only forth definitions