clevis-luks-bind 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. #!/bin/bash -e
  2. # vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80:
  3. #
  4. # Copyright (c) 2016 Red Hat, Inc.
  5. # Author: Harald Hoyer <harald@redhat.com>
  6. # Author: Nathaniel McCallum <npmccallum@redhat.com>
  7. #
  8. # This program is free software: you can redistribute it and/or modify
  9. # it under the terms of the GNU General Public License as published by
  10. # the Free Software Foundation, either version 3 of the License, or
  11. # (at your option) any later version.
  12. #
  13. # This program is distributed in the hope that it will be useful,
  14. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. # GNU General Public License for more details.
  17. #
  18. # You should have received a copy of the GNU General Public License
  19. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. #
  21. . clevis-luks-common-functions
  22. SUMMARY="Binds a LUKS device using the specified policy"
  23. usage() {
  24. exec >&2
  25. echo
  26. echo "Usage: clevis luks bind [-y] [-f] [-s SLT] [-k KEY] [-t TOKEN_ID] -d DEV PIN CFG"
  27. echo
  28. echo "$SUMMARY":
  29. echo
  30. echo " -f Do not prompt for LUKSMeta initialization"
  31. echo
  32. echo " -d DEV The LUKS device on which to perform binding"
  33. echo
  34. echo " -y Automatically answer yes for all questions"
  35. echo
  36. echo " -s SLT The LUKS slot to use"
  37. echo
  38. echo " -t TKN_ID The LUKS token ID to use; only available for LUKS2"
  39. echo
  40. echo " -k KEY Non-interactively read LUKS password from KEY file"
  41. echo " -k - Non-interactively read LUKS password from standard input"
  42. echo
  43. exit 2
  44. }
  45. if [ $# -eq 1 ] && [ "$1" = "--summary" ]; then
  46. echo "$SUMMARY"
  47. exit 0
  48. fi
  49. FRC=
  50. YES=
  51. while getopts ":hfyd:s:k:t:" o; do
  52. case "$o" in
  53. f) FRC='-f';;
  54. d) DEV="$OPTARG";;
  55. s) SLT="$OPTARG";;
  56. k) KEY="$OPTARG";;
  57. t) TOKEN_ID="$OPTARG";;
  58. y) FRC='-f'
  59. YES='-y';;
  60. *) usage;;
  61. esac
  62. done
  63. if [ -z "$DEV" ]; then
  64. echo "Did not specify a device!" >&2
  65. usage
  66. fi
  67. if ! luks_type="$(clevis_luks_type "${DEV}")"; then
  68. echo "${DEV} is not a supported LUKS device" >&2
  69. exit 1
  70. fi
  71. if ! PIN="${@:$((OPTIND++)):1}" || [ -z "$PIN" ]; then
  72. echo "Did not specify a pin!" >&2
  73. usage
  74. elif ! EXE=$(command -v clevis-encrypt-"${PIN}") || [ -z "${EXE}" ]; then
  75. echo "'${PIN}' is not a valid pin!" >&2
  76. usage
  77. fi
  78. if ! CFG="${@:$((OPTIND++)):1}" || [ -z "$CFG" ]; then
  79. echo "Did not specify a pin config!" >&2
  80. usage
  81. fi
  82. # Check whether the config is valid JSON.
  83. if ! jose fmt --json="${CFG}" --object 2>/dev/null; then
  84. echo "Configuration is malformed; it should be valid JSON" >&2
  85. exit 1
  86. fi
  87. if [ "${luks_type}" = "luks1" ] && [ -n "${TOKEN_ID}" ]; then
  88. echo "${DEV} is a LUKS1 device; -t is only supported in LUKS2" >&2
  89. exit 1
  90. fi
  91. # Get the existing passphrase/keyfile.
  92. existing_key=
  93. keyfile=
  94. case "${KEY}" in
  95. "") IFS= read -r -s -p "Enter existing LUKS password: " existing_key; echo >&2;;
  96. -) IFS= read -r -s -p "" existing_key ||:
  97. if [ "${luks_type}" = "luks1" ] && ! luksmeta test -d "${DEV}" \
  98. && [ -z "${FRC}" ]; then
  99. echo "Cannot use '-k-' without '-f' or '-y' unless already initialized!" >&2
  100. usage
  101. fi
  102. ;;
  103. *) keyfile="${KEY}"
  104. if [ ! -r "${keyfile}" ]; then
  105. echo "Cannot read key file '${keyfile}'" >&2
  106. exit 1
  107. fi
  108. ;;
  109. esac
  110. # If necessary, initialize the LUKS volume.
  111. if [ "${luks_type}" = "luks1" ] && ! luksmeta test -d "${DEV}"; then
  112. luksmeta init -d "${DEV}" ${FRC}
  113. fi
  114. if ! clevis_luks_do_bind "${DEV}" "${SLT}" "${TOKEN_ID}" \
  115. "${PIN}" "${CFG}" \
  116. "${YES}" "" \
  117. "${existing_key}" "${keyfile}"; then
  118. echo "Error adding new binding to ${DEV}" >&2
  119. exit 1
  120. fi