more progress. recovery seems to be working now.
[distorted-keys] / keeper-cards
1 #! /bin/sh
2 ###
3 ### Issue cards containing a bunch of keeper secrets
4 ###
5 ### (c) 2011 Mark Wooding
6 ###
7
8 ###----- Licensing notice ---------------------------------------------------
9 ###
10 ### This file is part of the distorted.org.uk key management suite.
11 ###
12 ### distorted-keys is free software; you can redistribute it and/or modify
13 ### it under the terms of the GNU General Public License as published by
14 ### the Free Software Foundation; either version 2 of the License, or
15 ### (at your option) any later version.
16 ###
17 ### distorted-keys is distributed in the hope that it will be useful,
18 ### but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 ### GNU General Public License for more details.
21 ###
22 ### You should have received a copy of the GNU General Public License
23 ### along with distorted-keys; if not, write to the Free Software Foundation,
24 ### Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25
26 set -e
27 case "${KEYSLIB+t}" in t) ;; *) echo >&2 "$0: KEYSLIB unset"; exit 1 ;; esac
28 . "$KEYSLIB"/keyfunc.sh
29
30 defhelp <<HELP
31 KEEPER [INDICES ...]
32 Typeset cards for a set of keeper secrets.
33
34 This program writes a file KEEPER.ps which will contain private keys from the
35 keeper set KEEPER, specifically the keys with the given INDICES. Elements of
36 the list are either simple integers or ranges [LOW]-[HIGH]; if LOW is
37 omitted, it means 0, and if HIGH is omitted, it means the highest possible
38 index. If no INDICES are given then all secret keys are written.
39
40 The public keys are found in $KEYS/keeper/KEEPER/I.pub;
41 private keys are read from KEEPER/I in the current directory.
42 HELP
43 dohelp
44
45 ## Parse the command line.
46 case $# in 0) echo >&2 "$usage"; exit 1 ;; esac
47 keeper=$1; shift
48 checkword "keeper set label" "$keeper"
49 read n hunoz <$KEYS/keeper/$keeper/meta
50
51 ## Build a colon-separated list of the indices we actually want.
52 want=:
53 case $# in 0) set 0- ;; esac
54 for range in "$@"; do
55 case "$range" in
56 *[!-0-9]* | *[!0-9]*-* | *-*[!0-9]*)
57 echo >&2 "$quis: bad index range \`$range'"
58 exit 1
59 ;;
60 *-*)
61 low=${range%-*} high=${range#*-}
62 ;;
63 *)
64 low=$range high=$range
65 ;;
66 esac
67 case "$low" in ?*) ;; *) low=0 ;; esac
68 case "$high" in ?*) ;; *) high=$((n - 1)) ;; esac
69 if [ 0 -gt $low -o $low -gt $high -o $high -ge $n ]; then
70 echo >&2 "$quis: invalid index range \`$range'"
71 exit 1
72 fi
73 i=$((low + 0))
74 while [ $i -le $high ]; do
75 case $want in *:"$i":*) ;; *) want=$want$i: ;; esac
76 i=$((i + 1))
77 done
78 done
79
80 ## Start working on the output file. This will contain deep secrets, so
81 ## don't leave stuff easily readable.
82 tmp=$(mktmp); cleanup rmtmp
83 umask 077
84 exec 3>$tmp/$keeper.tex
85 cat >&3 <<'EOF'
86 \documentclass[a4paper, landscape, 12pt]{article}
87 \usepackage[utf8]{inputenc}
88 \usepackage[T1]{fontenc}
89 \usepackage[palatino, helvetica, courier, maths = cmr]{mdwfonts}
90 \usepackage{graphicx}
91
92 %% Report errors with enough context that we can debug them.
93 \errorcontextlines=999
94
95 %% Basic layout for the cards. We use the paragraph filling machinery, but
96 %% don't actually need most of the trimmings.
97 \parindent=0pt
98 \parfillskip=0pt
99 \pagestyle{empty}
100
101 %% Page layout: try to use most of the page. The document class will already
102 %% have set up the paper size, but we do the rest here.
103 \hoffset=-1in \voffset=-1in
104 \oddsidemargin=20mm
105 \textwidth=\paperwidth \advance\textwidth by -2\oddsidemargin
106 \topmargin=20mm
107 \headheight=0pt \headsep=0pt
108 \textheight=\paperheight \advance\textheight by -2\topmargin
109 \AtBeginDocument{\special{papersize=\the\paperwidth,\the\paperheight}}
110
111 %% Parameters for the cards and guide rules.
112 \newdimen\cardwd \cardwd=82mm
113 \newdimen\cardht \cardht=49mm
114 \newdimen\guidelen \guidelen=10mm
115 \newdimen\rulewd \rulewd=0.6pt
116
117 %% Typesetting the secret as text. The macro \snarf TOKEN T0 T1 ... T7
118 %% gathers T0 T1 ... T7 into a single argument and passes them to TOKEN, as
119 %% long as T0 is not \relax. We use this to process the secret text in a
120 %% continuation-passing style.
121 \def\snarf#1#2{%
122 \ifx#2\relax\let\next\empty%
123 \else\def\next{\snarfdo#1#2}%
124 \fi%
125 \next%
126 }
127 \def\snarfdo#1#2#3#4#5#6#7#8#9{#1{#2#3#4#5#6#7#8#9}}
128
129 %% Print the left and right halves of the line, with a separator. Use boxes
130 %% for the lines so that TeX will work out the width of the enclosing vbox
131 %% for us. The basic usage is \line TEXT \relax ... \relax, with eight
132 %% \relax tokens: this is enough to complete both \snarf calls.
133 \def\line{\snarf\lineleft}
134 \def\lineleft#1{\hbox\bgroup#1 \snarf\lineright}
135 \def\lineright#1{#1\egroup\line}
136
137 %% Typeset a card containing a secret. Usage is \card{INDEX}{SECRET}.
138 \def\card#1#2{%
139 %%
140 %% Make sure we're setting a paragraph.
141 \leavevmode%
142 %%
143 %% Initial material: a stretchy space on the left.
144 \hbox{}\nobreak\hfil%
145 %%
146 %% An alignment for the guide markers surrounding the actual card.
147 \vbox{\halign{&##\cr%
148 %%
149 %% Top left guides.
150 \vrule width \guidelen height \rulewd depth 0pt%
151 \vrule width \rulewd depth 0pt height \guidelen%
152 &%
153 %%
154 %% Top centre gap.
155 \hfil%
156 &%
157 %%
158 %% Top right guides.
159 \vrule width \rulewd depth 0pt height \guidelen%
160 \vrule width \guidelen height \rulewd depth 0pt%
161 \cr%
162 %%
163 %% Left gap.
164 &%
165 %%
166 %% The actual card.
167 \vbox to \cardht{%
168 %%
169 %% We actually do more or less sensible typesetting. TeX will set the
170 %% box width from the hsize, and we should leave a small margin all
171 %% around.
172 \parfillskip=0pt plus 1fil%
173 \leftskip=1em \rightskip=1em%
174 \hsize=\cardwd%
175 %%
176 %% The heading.
177 \hrule height 0pt \prevdepth = 0pt%
178 \medskip%
179 {\large\bfseries\textsf{\keeper} secret #1/\total}%
180 %%
181 %% The QR-code and the text of the secret.
182 \vfil%
183 $%
184 \vcenter{\hbox{\includegraphics[scale = 2.4]{#1.eps}}}%
185 \hfil%
186 \vcenter{\ttfamily%
187 \line#2%
188 \relax\relax\relax\relax\relax\relax\relax\relax%
189 }%
190 $%
191 %%
192 %% And we're done.
193 \vfil%
194 }%
195 &%
196 %%
197 %% Right gap.
198 \cr%
199 %%
200 %% Bottom left guides.
201 \vrule width \guidelen depth \rulewd height 0pt%
202 \vrule width \rulewd depth \guidelen height 0pt%
203 &%
204 %% Bottom centre gap.
205 \hfil%
206 &%
207 %% Bottom right guides.
208 \vrule width \rulewd depth \guidelen height 0pt%
209 \vrule width \guidelen depth \rulewd height 0pt%
210 \cr%
211 %%
212 %% Leave a small vertical space at the bottom to separate lines of cards.
213 \strut \cr%
214 }}%
215 %%
216 %% End material: a stretchy space to match the one at the start, and then
217 %% allow a break.
218 \nobreak\hfil\hbox{}%
219 \penalty0%
220 }
221 EOF
222
223 ## Write the basic configuration stuff.
224 cat >&3 <<EOF
225
226 %% General configuration for the cards.
227 \def\keeper{$keeper}
228 \def\total{$n}
229 EOF
230
231 ## Start the document body.
232 cat >&3 <<'EOF'
233
234 %% The actual content.
235 \begin{document}
236 EOF
237
238 ## Work through the requested indices.
239 i=0
240 while [ $i -lt $n ]; do
241 case $want in
242 *:"$i":*)
243 read secret <$keeper/$i
244 tr -d '\n' <$keeper/$i | qrencode -m0 -s1 -o$tmp/$i.png
245 convert $tmp/$i.png $tmp/$i.eps
246 cat >&3 <<EOF
247 \card{$i}{$secret}
248 EOF
249 esac
250 i=$((i + 1))
251 done
252
253 ## Wrap up and build the document.
254 cat >&3 <<'EOF'
255 \end{document}
256 EOF
257 exec 3>&-
258 if ! (cd $tmp
259 exec </dev/null >tex.out 2>&1
260 latex $keeper.tex && dvips -o$keeper.ps $keeper.dvi); then
261 echo >&2 "$quis: document formatting failed"
262 sed >&2 's/^/| /' $tmp/tex.out
263 exit 1
264 fi
265 cp $tmp/$keeper.ps .
266
267 ###----- That's all, folks --------------------------------------------------