Advertisement
argideli

initramfs-luks-handler-ash.sh

Jun 10th, 2015
705
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 7.15 KB | None | 0 0
  1. #ctrl+c trap
  2. #
  3. ctrl_c() {
  4.         echo "** CTRL-C Pressed --"
  5.         result="1"
  6.         return 1
  7. }
  8.  
  9. #Find the filesystem that the partition uses. Handy in mounting and determining if the
  10. #partition is a swap device.
  11. find_fstype(){
  12.   local fs_type=$(blkid $1)
  13.   fs_type=${fs_type##*TYPE=\"}
  14.   fs_type=${fs_type%%\"*}
  15.   echo -n $fs_type
  16. }
  17.  
  18. #getCryptKey() searches for the specified block device and finds the LUKS key.
  19. #If the device does not exist it waits for 10s before returning an error code
  20. #Also it cleans up if there was any mounting when searching for the key (file key)
  21.  
  22. getCryptKey() {
  23. local key_dev=$(find_real_device $2)
  24. local key_dev_con="false"
  25. if [ $3 == "clean" ];then
  26.   umount $key_dev
  27.   rmdir "/mnt/$1_key"
  28. else
  29.   local counter="0"
  30.   echo  "Searching for key in $key_dev" >&2
  31.   while [ ! -b $key_dev ] && [ "$counter" != "10" ]; do
  32.     counter=$((counter+1))
  33.     echo  "Waiting 10s for $key_dev : Try $counter" >&2
  34.     key_dev=$(find_real_device $2)
  35.     if [ -b $key_dev ] ; then
  36.       echo  "$key_dev connected" >&2
  37.     fi
  38.     sleep 1
  39.   done
  40.  
  41.   if [ "$4" == "FILE" ]; then
  42.     if [ -b $key_dev ];then
  43.       if [ ! -d "/mnt/$1_key" ];then
  44.     mkdir "/mnt/$1_key"
  45.       fi
  46.       mount -r -t $(find_fstype $key_dev) $key_dev "/mnt/$1_key"
  47.      
  48.       if  [ -f "/mnt/$1_key/$3" ];then
  49.     echo  "Found key in $key_dev" >&2
  50.     echo "0"
  51.       else
  52.     echo  "$3 does not exist in $key_dev" >&2
  53.     echo "1"
  54.       fi
  55.     else
  56.       echo  "Key device: $key_dev is not present">&2
  57.       echo "1"
  58.     fi
  59.   else
  60.     if [ -b $key_dev ];then
  61.       echo  "Found key device $key_dev" >&2
  62.       echo "0"
  63.     else
  64.       echo  "Key device: $key_dev is not present">&2
  65.       echo "1"
  66.     fi
  67.   fi
  68. fi
  69. }
  70.  
  71. #openLUKS() Unlocks a volume based on the boot args. If the volume is a swap device
  72. #it gets mounted.
  73. openLUKS() {
  74. #luks_dev : $1
  75. #luks_map : $2
  76. #luks_opts: $3
  77. #key_dev  : $4
  78. #key_type : $5
  79. #key      : $6
  80. result=""
  81. local luks_opts=$(echo $luks_opts |  awk -F',' '{for (i=1; i<=NF; i++) print $i}')
  82. local luks_dev=$(find_real_device $1)
  83. if [ $luks_opts == "null" ];then
  84.   luks_opts=""
  85. fi
  86. case $5 in
  87.     PASS|"null")
  88.     echo  "Trying to unlock $luks_dev" >&2
  89.     cryptsetup luksOpen $luks_opts $luks_dev $2
  90.     if [ $? == "0" ] && [ -b "/dev/mapper/$2" ]; then
  91.       echo  "LUKS Volume $luks_dev is now unlocked" >&2
  92.       if [ "$(find_fstype "/dev/mapper/$2")" == "swap" ];then
  93.           swapon "/dev/mapper/$2"
  94.       fi
  95.       echo "0"
  96.     else
  97.       echo "1"
  98.     fi
  99.         ;;
  100.     BLK)
  101.     key_start=$(echo $key_loc | awk -F'-' '{print $1}')
  102.         key_size=$(echo $key_loc | awk -F'-' '{print $2}')
  103.         result=$(getCryptKey $2 $4 $6 $5)
  104.         if [ $result == "0" ];then
  105.       echo  "Trying to unlock $luks_dev" >&2
  106.       local key_dev=$(find_real_device $4)
  107.       key_dev=${key_dev%%[0-9]*}
  108.       echo  "Trying to unlock $luks_dev" >&2
  109.       dd if=$key_dev bs=1 skip=$key_start count=$key_size | cryptsetup  luksOpen $luks_opts $luks_dev $2 --key-file=-
  110.           result="$?"
  111.           if [ "$result" == "0" ] && [ -b "/dev/mapper/$2" ]; then
  112.         echo  "LUKS Volume $luks_dev is now unlocked" >&2  
  113.         if [ "$(find_fstype "/dev/mapper/$2")" == "swap" ];then
  114.           swapon "/dev/mapper/$2"
  115.         fi
  116.         echo "0"
  117.       else
  118.         echo "1"
  119.       fi
  120.     else
  121.       echo "1"
  122.     fi
  123.         ;;
  124.     FILE)
  125.         result=$(getCryptKey $2 $4 $6 $5)
  126.         if [ $result == "0" ];then
  127.       echo  "Trying to unlock $luks_dev" >&2
  128.       cryptsetup -d /mnt/$2_key/$6 open --type luks $luks_opts $luks_dev $2
  129.       if [ $? == "0" ] && [ -b "/dev/mapper/$2" ]; then
  130.         echo  "LUKS Volume $luks_dev is now unlocked" >&2
  131.         if [ "$(find_fstype "/dev/mapper/$2")" == "swap" ];then
  132.           swapon "/dev/mapper/$2"
  133.         fi
  134.         echo "0"
  135.       else
  136.         echo "1"
  137.       fi
  138.     else
  139.       echo "1"
  140.     fi
  141.     getCryptKey $2 $4 "clean"
  142.         ;;
  143.     *)
  144.         echo  "Unknown Key Type" >&2
  145. esac
  146. }
  147.  
  148. #startLUKS() reads the boot line, stores the arguments in arrays, parses them
  149. #and uses openLUKS() to unlock the LUKS volumes. If a volume fails it is included
  150. #in the error array.
  151. startLUKS() {
  152. boot_args="$(cat /proc/cmdline)"
  153. root_arg=""
  154. dev_error=""
  155. crypt_devs=""
  156. crypt_keys=""
  157. unlocked="false"
  158.  
  159. trap ctrl_c INT
  160.  
  161. for boot_arg in $boot_args
  162. do
  163.   if [ ${boot_arg%%=*} == "real_root" ]; then
  164.     REAL_ROOT=${boot_arg#*=}
  165.   fi
  166.  
  167.   if [ ${boot_arg%%=*} == "crypt_dev" ]; then
  168.     boot_arg_map=$(echo $boot_arg | awk -F':' '{print $2}')
  169.     boot_arg_path=$(find_real_device $(echo "${boot_arg#*=}" |awk -F':' '{print $1}'))
  170.     boot_arg_opts=$(echo $boot_arg | awk -F':' '{print $3}')
  171.     if [ -z $boot_arg_map ]; then
  172.       boot_arg_map="null"
  173.     fi
  174.     if [ -z $boot_arg_opts ]; then
  175.       boot_arg_opts="null"
  176.     fi
  177.     crypt_devs="$crypt_devs $boot_arg_path|$boot_arg_map|$boot_arg_opts "
  178.   fi
  179.  
  180.   if [ ${boot_arg%%=*} == "crypt_key" ]; then
  181.       key_map=$(echo ${boot_arg#*=} | awk -F':' '{print $1}')
  182.       key_dev=$(echo ${boot_arg#*=} | awk -F':' '{print $2}')
  183.       key_type=$(echo ${boot_arg#*=} | awk -F':' '{print $3}')
  184.       key_loc=$(echo ${boot_arg#*=} | awk -F':' '{print $4}')
  185.       crypt_keys="$crypt_keys $key_map|$key_dev|$key_type|$key_loc "
  186.      
  187.   fi
  188. done
  189.  
  190. for dev in $crypt_devs
  191. do
  192.   key_map="null"
  193.   key_dev="null"
  194.   key_type="null"
  195.   key_loc="null"
  196.   luks_dev=$(echo $dev | awk -F'|' '{print $1}')
  197.   luks_map=$(echo $dev | awk -F'|' '{print $2}')
  198.   luks_opts=$(echo $dev | awk -F'|' '{print $3}')
  199.  
  200.   for key in $crypt_keys
  201.   do
  202.     key_map=$(echo $key | awk -F'|' '{print $1}')
  203.     if [ $luks_map == $key_map ];then
  204.       key_dev=$(echo $key | awk -F'|' '{print $2}')
  205.       key_type=$(echo $key | awk -F'|' '{print $3}')
  206.       key_loc=$(echo $key | awk -F'|' '{print $4}')
  207.       break
  208.     else
  209.       key_map="null"
  210.       key_dev="null"
  211.       key_type="null"
  212.       key_loc="null"
  213.     fi
  214.   done
  215.  
  216.   if [ ! -b $(find_real_device $luks_dev) ];then
  217.     echo "LUKS device $luks_dev does not exist"
  218.     dev_error="$dev_error $luks_dev"
  219.   elif [ $luks_map == "null" ];then
  220.     echo "LUKS Map cannot be empty!"
  221.     dev_error="$dev_error $luks_dev"
  222.   else
  223.     result=$(openLUKS $luks_dev $luks_map $luks_opts $key_dev $key_type $key_loc)
  224.     if [ $result == "0" ];then
  225.        unlocked="true"
  226.     else
  227.        dev_error="$dev_error $luks_dev"
  228.     fi
  229.   fi
  230. done
  231.  
  232. if [ -n "$dev_error" ]; then
  233.   for i in $dev_error
  234.   do
  235.     luks_dev="$(echo $i | awk -F':' '{print $1}')"
  236.     luks_map="$(echo $i | awk -F':' '{print $2}')"
  237.     echo "Failed to unlock: $luks_dev"
  238.     echo -n "Retry with Password? [y/n]: "
  239.     read try_pass
  240.     if [ $try_pass == "Y" ] || [ $try_pass == "y" ];then
  241.       cryptsetup luksOpen $luks_dev $luks_map
  242.       if [ $? == "0" ] && [ -b "/dev/mapper/$luks_map" ]; then
  243.         echo  "LUKS Volume $luks_dev is now unlocked"
  244.         if [ "$(find_fstype "/dev/mapper/$luks_map")" == "swap" ];then
  245.           swapon "/dev/mapper/$luks_map"
  246.         fi
  247.       fi
  248.     else
  249.       echo "Unlocking $luks_dev aborted"
  250.     fi
  251.   done
  252. else
  253.   if [ -z "$dev_error" ];then
  254.     echo "All LUKS devices were succesfully unlocked"
  255.   fi
  256. fi
  257.  
  258. if [ -n "${REAL_ROOT}" ]; then
  259.   startVolumes
  260. else
  261.   if [ -z "$REAL_ROOT" ]; then
  262.     REAL_ROOT="/dev/mapper/root"
  263.   fi
  264. fi
  265. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement