Advertisement
devinteske

secure_thumb Makefile

Nov 6th, 2018
572
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Make 21.53 KB | None | 0 0
  1. ############################################################ IDENT(1)
  2. #
  3. # $Title: Makefile to produce GELI encrypted image for use on USB thumb drive $
  4. #
  5. ############################################################ OBJECTS
  6.  
  7. # Image file
  8. IMGFILE=    secure_thumb.md
  9.  
  10. # Sizes (in MB)
  11. IMGSIZE=    256
  12.  
  13. # Sizes (in KB)
  14. KEYSIZE=    512
  15.  
  16. ############################################################ FUNCTIONS
  17.  
  18. EVAL2=      exec 3<&1; eval2(){ echo "$$*" >&3;eval "$$*"; }
  19.  
  20. DISKPROMPT= \
  21.     diskprompt()                                                         \
  22.     {                                                                    \
  23.         DISK=;                                                       \
  24.         local disks ndisks ignored _new d n num;                     \
  25.         disks=$$( sysctl -n kern.disks );                            \
  26.         set -- $$disks;                                              \
  27.         ndisks=$$\#;                                                 \
  28.         while :; do                                                  \
  29.             printf "< Insert physical media and press ENTER > "; \
  30.             read ignored;                                        \
  31.             set -- $$( sysctl -n kern.disks );                   \
  32.             if [ $$\# -lt $$ndisks ]; then                       \
  33.                 disks="$$*";                                 \
  34.                 ndisks=$$\#;                                 \
  35.                 continue;                                    \
  36.             elif [ "$$*" = "$$disks" ]; then                     \
  37.                 continue;                                    \
  38.             fi;                                                  \
  39.             break;                                               \
  40.         done;                                                        \
  41.         _new=;                                                       \
  42.         for d in $$*; do                                             \
  43.             case "$$disks" in                                    \
  44.             "$$d"|"$$d "*|*" $$d") continue ;;                   \
  45.             esac;                                                \
  46.             _new="$$_new $$d";                                   \
  47.         done;                                                        \
  48.         set -- $$_new;                                               \
  49.         if [ $$\# -gt 1 ]; then                                      \
  50.             n=1;                                                 \
  51.             while :; do                                          \
  52.                 echo "Detected disks:";                      \
  53.                 for d in $$*; do                             \
  54.                     printf "\t%u) %s\n" $$n $$d;         \
  55.                     n=$$(( $$n + 1 ));                   \
  56.                 done;                                        \
  57.                 printf "Choose disk: ";                      \
  58.                 read num;                                    \
  59.                 eval set -- \$$$${num};                      \
  60.                 [ ! "$$1" ] && break;                        \
  61.             done;                                                \
  62.         fi;                                                          \
  63.         DISK="$$1";                                                  \
  64.     }
  65.  
  66. YESNO=  \
  67.     yesno()                                       \
  68.     {                                             \
  69.         local OPTIND=1 OPTARG flag;           \
  70.         local default_no=;                    \
  71.         while getopts n flag; do              \
  72.             case "$$flag" in              \
  73.             n) default_no=1 ;;            \
  74.             esac;                         \
  75.         done;                                 \
  76.         shift $$(( $$OPTIND - 1 ));           \
  77.         local yesno= prompt="$$*";            \
  78.         while [ ! "$$yesno" ]; do             \
  79.             printf "$$prompt";            \
  80.             read yesno;                   \
  81.             [ ! "$$yesno" ] &&            \
  82.                 [ "$$default_no" ] && \
  83.                 break;                \
  84.         done;                                 \
  85.         case "$$yesno" in                     \
  86.         [Yy]|[Yy][Ee][Ss]) return 0 ;;        \
  87.         esac;                                 \
  88.         echo "User cancelled (exiting)" >&2;  \
  89.         exit 0;                               \
  90.     }
  91.  
  92. DD_WITH_PROGRESS=   \
  93.     dd_with_progress()                                                                 \
  94.     {                                                                                  \
  95.         local arg infile=;                                                         \
  96.         for arg in "$$@"; do                                                       \
  97.             case "$$arg" in                                                    \
  98.             if=*) infile="$${arg\#if=}"; break ;;                              \
  99.             esac;                                                              \
  100.         done;                                                                      \
  101.         if [ ! "$$infile" ]; then                                                  \
  102.             echo "dd_with_progress: No input file given (exiting)" >&2;        \
  103.             exit 1;                                                            \
  104.         fi;                                                                        \
  105.         sudo -v || exit 1;                                                         \
  106.         trap exit SIGINT;                                                          \
  107.         ( eval "eval2 sudo dd $$* 2>&1 &";                                         \
  108.             local sudo_pid=$$! dd_pid=;                                        \
  109.             while [ ! "$$dd_pid" ]; do                                         \
  110.                 dd_pid=$$( sudo ps axo pid,ppid |                          \
  111.                     awk -v ppid="$$sudo_pid" '$$2==ppid{print $$1}' ); \
  112.                 sleep 1;                                                   \
  113.             done;                                                              \
  114.             while sudo kill -INFO $$dd_pid > /dev/null 2>&1; do                \
  115.                 sleep 1;                                                   \
  116.             done;                                                              \
  117.         ) | time awk -v total="$$( stat -f%z "$$infile" )" '                       \
  118.             BEGIN {                                                            \
  119.                 w = 40;                                                    \
  120.                 bar = sprintf("[%*s] (%3s%%)", w, "", "");                 \
  121.             }                                                                  \
  122.             /bytes transferred/ {                                              \
  123.                 pct = $$1 * 100 / total;                                   \
  124.                 left = int(w * pct / 100);                                 \
  125.                 right = w - left;                                          \
  126.                 bar = sprintf("%*s", left, "");                            \
  127.                     gsub(/ /, "=", bar);                                       \
  128.                 sub(/.$$/, ">", bar);                                      \
  129.                 rate = $$(NF-1);                                           \
  130.                 sub(/^\(/, "", rate);                                      \
  131.                 printf "\r%10.1f MB [%s%*s] (%3u%%) %10.1f MB/s",          \
  132.                     $$1 / 1024 / 1024, bar, right, "",                 \
  133.                     pct, rate / 1024 / 1024;                           \
  134.                 fflush();                                                  \
  135.             }                                                                  \
  136.             END { print "" }                                                   \
  137.         ';                                                                         \
  138.     }
  139.  
  140. ############################################################ TARGETS
  141.  
  142. .PHONY: all
  143.  
  144. all: $(IMGFILE)
  145.  
  146. .PHONY: usage help
  147.  
  148. usage:
  149.     @exec >&2;                                                        \
  150.      echo "Targets:";                                                 \
  151.      echo " all/default:    Create $(IMGFILE)";                       \
  152.      echo " open:           Attach and mount $(IMGFILE)";             \
  153.      echo " close:          Unmount and detach $(IMGFILE)";           \
  154.      echo " attach:         Attach an md(4) device to $(IMGFILE)";    \
  155.      echo " detach:         Detach md(4) device from $(IMGFILE)";     \
  156.      echo " resize:         Resize $(IMGFILE) to IMGSIZE MB";         \
  157.      echo " deployusb:      Write $(IMGFILE) to physical media";      \
  158.      echo " resizeusb:      Resize physical media to use free space"; \
  159.      echo
  160.  
  161. help: usage
  162.  
  163. $(IMGFILE):
  164.     dd if=/dev/zero of=$(IMGFILE) bs=1m seek=$(IMGSIZE) count=0
  165.     @$(EVAL2);                                                           \
  166.      set -e;                                                             \
  167.      trap='eval2 sudo mdconfig -d -u "$${md#md}"';                       \
  168.      trap "$$trap" EXIT;                                                 \
  169.      md=$$( eval2 sudo mdconfig -f $(IMGFILE) );                         \
  170.      echo "$$md";                                                        \
  171.      md="$${md%%[$$IFS]*}";                                              \
  172.      eval2 sudo gpart create -s MBR "$$md";                              \
  173.      eval2 sudo gpart add -t freebsd -i 1 "$$md";                        \
  174.      eval2 sudo gpart create -s BSD "$${md}s1";                          \
  175.      eval2 sudo gpart add -t freebsd-ufs -i 1 -s 128m "$${md}s1";        \
  176.      eval2 sudo gpart add -t freebsd-ufs -i 4 -s 16m "$${md}s1";         \
  177.      eval2 sudo gpart add -t freebsd-ufs -i 5 "$${md}s1";                \
  178.      eval2 sudo newfs -U -O 1 -f 512 -b 4096 -i 8192 "$${md}s1a";        \
  179.      eval2 mkdir -p mnt;                                                 \
  180.      eval2 sudo mount "/dev/$${md}s1a" mnt;                              \
  181.      trap="eval2 sudo umount mnt && $$trap";                             \
  182.      trap "$$trap" EXIT;                                                 \
  183.      eval2 sudo mkdir -p mnt/geli;                                       \
  184.      trap "stty echo || :; $$trap" EXIT;                                 \
  185.      stty -echo;                                                         \
  186.      printf "Enter new passphrase: ";                                    \
  187.      read pass1;                                                         \
  188.      echo;                                                               \
  189.      printf "Reenter new passphrase: ";                                  \
  190.      read pass2;                                                         \
  191.      echo;                                                               \
  192.      stty echo;                                                          \
  193.      trap "$$trap" EXIT;                                                 \
  194.      if [ "$$pass1" != "$$pass2" ]; then                                 \
  195.         echo "Password mismatch (exiting)" >&2;                      \
  196.         trap "$$trap && eval2 rm -f $(IMGFILE)" EXIT;                \
  197.         exit 1;                                                      \
  198.      fi;                                                                 \
  199.      geli1=mnt/geli/ffthumb-s1d;                                         \
  200.      geli2=mnt/geli/ffthumb-s1e;                                         \
  201.      eval2 sudo dd if=/dev/random of=$$geli1.key bs=1k count=$(KEYSIZE); \
  202.      eval2 sudo dd if=/dev/random of=$$geli2.key bs=1k count=$(KEYSIZE); \
  203.      echo "$$pass1" | eval2 sudo geli init -J-                           \
  204.         -B $$geli1.backup -K $$geli1.key "$${md}s1d";                \
  205.      echo "$$pass1" | eval2 sudo geli init -J-                           \
  206.         -B $$geli2.backup -K $$geli2.key "$${md}s1e";                \
  207.      echo "$$pass1" | eval2 sudo geli attach -j-                         \
  208.         -k $$geli1.key "$${md}s1d";                                  \
  209.      trap="eval2 sudo geli detach $${md}s1d && $$trap";                  \
  210.      trap "$$trap" EXIT;                                                 \
  211.      echo "$$pass2" | eval2 sudo geli attach -j-                         \
  212.         -k $$geli2.key "$${md}s1e";                                  \
  213.      trap="eval2 sudo geli detach $${md}s1e && $$trap";                  \
  214.      trap "$$trap" EXIT;                                                 \
  215.      eval2 sudo newfs -U -O 1 -f 512 -b 4096 -i 8192 "$${md}s1d.eli";    \
  216.      eval2 sudo newfs -U -O 1 -f 512 -b 4096 -i 8192 "$${md}s1e.eli";    \
  217.      eval2 sudo mkdir -p mnt/keys;                                       \
  218.      eval2 sudo mount "/dev/$${md}s1d.eli" mnt/keys;                     \
  219.      trap="eval2 sudo umount mnt/keys && $$trap";                        \
  220.      trap "$$trap" EXIT;                                                 \
  221.      eval2 sudo cp Makefile.keys mnt/keys/Makefile;                      \
  222.      eval2 sudo mkdir -p mnt/encstore;                                   \
  223.      eval2 sudo cp mount.sh umount.sh mnt/
  224.  
  225. attach: $(IMGFILE)
  226.     @$(EVAL2);                                                 \
  227.      set -e;                                                   \
  228.      if md=$$( eval2 sudo mdconfig -lf $(IMGFILE) ); then      \
  229.         echo "$$md";                                       \
  230.         echo "$(IMGFILE) already attached (skipping)" >&2; \
  231.         exit 0;                                            \
  232.      fi;                                                       \
  233.      md=$$( eval2 sudo mdconfig -f $(IMGFILE) );               \
  234.      echo "$$md";                                              \
  235.      md="$${md%%[$$IFS]*}";                                    \
  236.      echo "$(IMGFILE) successfully attached to $$md" >&2
  237.  
  238. open: attach
  239.     @$(EVAL2);                                                       \
  240.      set -e;                                                         \
  241.      md=$$( eval2 sudo mdconfig -lf $(IMGFILE) );                    \
  242.      echo "$$md";                                                    \
  243.      md="$${md%%[$$IFS]*}";                                          \
  244.      eval2 mkdir -p mnt;                                             \
  245.      df=$$( eval2 df -nh mnt );                                      \
  246.      echo "$$df";                                                    \
  247.      dev="/dev/$${md}s1a";                                           \
  248.      if echo "$$df" |                                                \
  249.         eval2 awk "'\$$1==\"$$dev\"{exit s=1}END{exit !s}'";     \
  250.      then                                                            \
  251.         echo "$(IMGFILE) already mounted on mnt (skipping)" >&2; \
  252.      else                                                            \
  253.         eval2 sudo mount "$$dev" mnt;                            \
  254.         echo "$(IMGFILE) successfully mounted on mnt" >&2;       \
  255.      fi;                                                             \
  256.      [ ! -x mnt/mount.sh ] || eval2 sudo mnt/mount.sh -d
  257.  
  258. detach:
  259.     @$(EVAL2);                                              \
  260.      set -e;                                                \
  261.      [ -e $(IMGFILE) ] || exit 0;                           \
  262.      if ! md=$$( eval2 sudo mdconfig -lf $(IMGFILE) ); then \
  263.         echo "$(IMGFILE) not attached (skipping)" >&2;  \
  264.         exit 0;                                         \
  265.      fi;                                                    \
  266.      echo "$$md";                                           \
  267.      md="$${md%%[$$IFS]*}";                                 \
  268.      eval2 sudo mdconfig -d -u "$${md#md}" &&               \
  269.         echo "$$md successfully detached from $(IMGFILE)" >&2
  270.  
  271. close:
  272.     @$(EVAL2);                                                   \
  273.      set -e;                                                     \
  274.      [ -e $(IMGFILE) ] || exit 0;                                \
  275.      if ! md=$$( eval2 sudo mdconfig -lf $(IMGFILE) ); then      \
  276.         echo "$(IMGFILE) not attached (skipping)" >&2;       \
  277.         [ ! -e mnt ] || eval2 rmdir mnt;                     \
  278.         exit 0;                                              \
  279.      fi;                                                         \
  280.      echo "$$md";                                                \
  281.      md="$${md%%[$$IFS]*}";                                      \
  282.      if [ ! -e mnt ]; then                                       \
  283.         eval2 sudo mdconfig -d -u "$${md#md}";               \
  284.         exit 0;                                              \
  285.      fi;                                                         \
  286.      df=$$( eval2 df -nh mnt );                                  \
  287.      echo "$$df";                                                \
  288.      dev="/dev/$${md}s1a";                                       \
  289.      if echo "$$df" |                                            \
  290.         eval2 awk "'\$$1==\"$$dev\"{exit s=1}END{exit !s}'"; \
  291.      then                                                        \
  292.         [ ! -x mnt/umount.sh ] || sudo mnt/umount.sh;        \
  293.         eval2 sudo umount mnt;                               \
  294.      fi;                                                         \
  295.      eval2 rmdir mnt;                                            \
  296.      eval2 sudo mdconfig -d -u "$${md#md}";                      \
  297.      echo "$(IMGFILE) successfully unmounted and detached" >&2
  298.  
  299. clean: close
  300.     @$(EVAL2);                            \
  301.      $(YESNO);                            \
  302.      set -e;                              \
  303.      [ -e $(IMGFILE) ] || exit 0;         \
  304.      yesno -n "Delete $(IMGFILE)? [N]: "; \
  305.      eval2 rm -f $(IMGFILE)
  306.  
  307. resize:
  308.     @$(EVAL2);                                                          \
  309.      set -e;                                                            \
  310.      if [ ! -e $(IMGFILE) ]; then                                       \
  311.         echo "$(IMGFILE) does not exist (skipping)" >&2;            \
  312.         exit 0;                                                     \
  313.      fi;                                                                \
  314.      if eval2 sudo mdconfig -lf $(IMGFILE); then                        \
  315.         echo "$(IMGFILE) attached (detaching)" >&2;                 \
  316.         eval2 $(MAKE) IMGFILE=$(IMGFILE) close;                     \
  317.      fi;                                                                \
  318.      size=$$( eval2 stat -f%z $(IMGFILE) );                             \
  319.      echo "$$size";                                                     \
  320.      size=$$(( $$size / 1024 / 1024 ));                                 \
  321.      if [ $$size -eq $(IMGSIZE) ]; then                                 \
  322.         echo "$(IMGFILE) is already $$size MB (exiting)" >&2;       \
  323.         exit 0;                                                     \
  324.      elif [ $$size -gt $(IMGSIZE) ]; then                               \
  325.         echo "Cannot shrink $(IMGFILE)"                             \
  326.              "from $$size to $(IMGSIZE) MB (exiting)" >&2;          \
  327.         exit 1;                                                     \
  328.      fi;                                                                \
  329.      eval2 dd if=/dev/zero of=$(IMGFILE) bs=1m seek=$(IMGSIZE) count=0; \
  330.      eval2 $(MAKE) IMGFILE=$(IMGFILE) attach;                           \
  331.      trap 'eval2 $(MAKE) IMGFILE=$(IMGFILE) detach' EXIT;               \
  332.      if ! md=$$( eval2 sudo mdconfig -lf $(IMGFILE) ); then             \
  333.         echo "$(IMGFILE) not attached (exiting)" >&2;               \
  334.         exit 1;                                                     \
  335.      fi;                                                                \
  336.      echo "$$md";                                                       \
  337.      md="$${md%%[$$IFS]*}";                                             \
  338.      eval2 sudo gpart resize -i 1 "$$md";                               \
  339.      gpart=$$( eval2 gpart show "$${md}s1" );                           \
  340.      echo "$$gpart";                                                    \
  341.      oldsize=$$( echo "$$gpart" |                                       \
  342.         eval2 awk "'\$$3==5{print \$$2*512}'" );                    \
  343.      echo "$$oldsize";                                                  \
  344.      eval2 sudo gpart resize -i 5 "$${md}s1";                           \
  345.      eval2 sudo geli resize -s $$oldsize "$${md}s1e";                   \
  346.      trap 'eval2 $(MAKE) IMGFILE=$(IMGFILE) close' EXIT;                \
  347.      eval2 $(MAKE) IMGFILE=$(IMGFILE) open;                             \
  348.      eval2 sudo growfs -y "$${md}s1e.eli"
  349.  
  350. deployusb: $(IMGFILE)
  351.     @$(EVAL2);                                                   \
  352.      $(DISKPROMPT);                                              \
  353.      $(YESNO);                                                   \
  354.      $(DD_WITH_PROGRESS);                                        \
  355.      set -e;                                                     \
  356.      diskprompt;                                                 \
  357.      echo "LAST CHANCE!!! Will write $(IMGFILE) to /dev/$$DISK"; \
  358.      yesno "OK to overwrite any/all data on $$DISK? [y/n]: ";    \
  359.      dd_with_progress if=$(IMGFILE) of=/dev/$$DISK bs=1m
  360.  
  361. resizeusb:
  362.     @$(EVAL2);                                                  \
  363.      $(DISKPROMPT);                                             \
  364.      $(YESNO);                                                  \
  365.      set -e;                                                    \
  366.      diskprompt;                                                \
  367.      echo "LAST CHANCE!!! Will resize /dev/$${DISK}s1e";        \
  368.      yesno "OK to expand partition to use free space? [y/n]: "; \
  369.      eval2 sudo gpart resize -i 1 $$DISK;                       \
  370.      gpart=$$( eval2 gpart show $${DISK}s1 );                   \
  371.      echo "$$gpart";                                            \
  372.      oldsize=$$( echo "$$gpart" |                               \
  373.         eval2 awk "'\$$3==5{print \$$2*512}'" );            \
  374.      echo "$$oldsize";                                          \
  375.      eval2 sudo gpart resize -i 5 $${DISK}s1;                   \
  376.      eval2 sudo geli resize -s $$oldsize $${DISK}s1e;           \
  377.      eval2 mkdir -p mnt.$$$$;                                   \
  378.      trap="eval2 rmdir mnt.$$$$";                               \
  379.      trap "$$trap" EXIT;                                        \
  380.      eval2 sudo mount /dev/$${DISK}s1a mnt.$$$$;                \
  381.      trap="eval2 sudo umount mnt.$$$$ && $$trap";               \
  382.      trap "$$trap" EXIT;                                        \
  383.      eval2 sudo mnt.$$$$/mount.sh -d;                           \
  384.      trap "eval2 sudo mnt.$$$$/umount.sh && $$trap" EXIT;       \
  385.      eval2 sudo growfs -y $${DISK}s1e.eli
  386.  
  387. ################################################################################
  388. # END
  389. ################################################################################
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement