chiark / gitweb /
Initial revision
[become] / manual / become.tex
1 %%% -*-LaTeX-*-
2 %%%
3 %%% $Id: become.tex,v 1.1 1997/07/21 13:47:54 mdw Exp $
4 %%%
5 %%% Documentation for `become'
6 %%%
7 %%% (c) 1997 EBI
8 %%%
9
10 %%%----- Licencing notice ---------------------------------------------------
11 %%% 
12 %%% This file is part of `become'
13 %%% 
14 %%% `Become' is free software; you can redistribute it and/or modify
15 %%% it under the terms of the GNU General Public License as published by
16 %%% the Free Software Foundation; either version 2 of the License, or
17 %%% (at your option) any later version.
18 %%% 
19 %%% `Become' is distributed in the hope that it will be useful,
20 %%% but WITHOUT ANY WARRANTY; without even the implied warranty of
21 %%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22 %%% GNU General Public License for more details.
23 %%% 
24 %%% You should have received a copy of the GNU General Public License
25 %%% along with `become'; if not, write to the Free Software
26 %%% Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27
28 %%%----- Revision history ---------------------------------------------------
29 %%%
30 %%% $Log: become.tex,v $
31 %%% Revision 1.1  1997/07/21 13:47:54  mdw
32 %%% Initial revision
33 %%%
34
35 %%%----- Document preamble --------------------------------------------------
36
37
38 %% --- Document class and packages ---
39
40 \documentclass[a4paper, 10pt]{article}
41 \usepackage{array, tabularx}
42 \usepackage[rounded]{syntax}
43
44 \newif\ifxypic
45 % \IfFileExists{xy.sty}{\usepackage[all]{xy}\xypictrue}{\xypicfalse}
46
47 \IfFileExists{mdwfonts.sty}{\usepackage{mdwfonts}}{}
48
49
50 %% --- Macros and things ---
51
52 \newcommand{\become}{\textsf{become}}
53 \newcommand{\path}[1]{\texttt{#1}}
54 \def\<#1>{\synt{#1}}
55 \newcommand{\xor}{\oplus}
56 \newcommand{\ror}{\mathbin{>\mskip-6mu>\mskip-6mu>}}
57
58
59 %% --- eqalign, from Plain TeX, LaTeXified ---
60
61 \makeatletter
62 \def\eqalign{%
63   \null\,\vcenter\bgroup\openup\jot\m@th%
64   \ialign\bgroup%
65     \strut\hfil$\displaystyle{##}$&$\displaystyle{{}##}$\hfil\crcr%
66 }
67 \def\endeqalign{
68     \crcr%
69   \egroup\egroup%
70   \,%
71 }
72 \makeatother
73
74
75 %% --- Other layout preferences ---
76
77 \setlength{\grammarindent}{1in}
78 \renewcommand{\arraystretch}{1.2}
79 \addtolength{\textwidth}{0.6in}
80 \addtolength{\oddsidemargin}{-0.3in}
81 \sloppy
82
83 \begin{document}
84
85
86 %%%----- Introductory matter ------------------------------------------------
87
88
89 %% --- Title and some `brief' acknowledgements ---
90
91 \title{The \become\ program}
92 \author{Mark Wooding\thanks{
93     The program contains nontrivial pieces of code owned by the European
94     Bioinformatics Institute, Mark Wooding and Straylight (even though I
95     actually wrote it all).  Thanks also to the Free Software Foundation for
96     Autoconf; to Ron Rivest for the MD5 message digest algorithm; to Xuekia
97     Lai and James Massey for the IDEA cipher; and to Bruce Schneier, for
98     writing \emph{Applied Cryptography}, which explained why I'd written the
99     first version of all this code wrong.} \\
100   \texttt{mdw@ebi.ac.uk}}
101
102 \maketitle
103
104
105 %% --- Abstract ---
106
107 \begin{abstract}
108   This document describes a system for allowing users to `become' other users
109   in a secure and controlled way under Unix.  The idea is to allow users to
110   maintain programs and other resources which require their own accounts
111   while removing the need for such accounts to have passwords (which can be
112   disclosed, forgotten or otherwise abused in ways that passwords for user
113   accounts don't tend to be).
114
115   The \become\ program will look up the user's identity, the identity of the
116   user he or she wishes to `become', the name of the program which is to be
117   executed, and the identity of the current host, consult a configuration
118   file, and decide whether the request is permitted before granting it.  The
119   novel idea is that the table doesn't need to be on the local machine --
120   \become\ will send a request to a server, asking it for permission,
121   allowing the information to be held centrally, and making maintenance more
122   convenient.  Cryptographic protocols are used to ensure the authenticity of
123   the server's responses.
124 \end{abstract}
125
126
127 %% --- Contents ---
128
129 \tableofcontents
130
131
132 %%%--------------------------------------------------------------------------
133 \section{User guide}
134
135
136 \subsection{Introduction}
137
138 Running \become\ lets you `become' another user.  What this really means is
139 that it lets you execute a process with the permissions of another user.
140 Which users you're allowed to `become', and exactly what processes you're
141 allowed to execute as those users is determined by the people that installed
142 \become.
143
144
145 \subsection{Invoking \become}
146
147 Invoking the \become\ program is impressively simple.  There are essentially
148 two forms of invocation:
149 \begin{syntdiag}
150   `become' <user-name> \[ <program> \[ \< <argument> \> \] \]
151 \end{syntdiag}
152 and
153 \begin{syntdiag}
154   `become' `-c' <shell-command> <user-name>
155 \end{syntdiag}
156 The first variant allows you to execute any \<program> as user \<user-name>,
157 as limited by your site's configuration.  The second variant simply passes
158 the \<shell-command> to \path{/bin/sh}, so you must have permission to
159 execute the shell as \<user-name>.  The latter form doesn't actually allow
160 you to do anything the former doesn't: it is in fact entirely equivalent to
161 saying `\syntax{"become" <user-name> "/bin/sh -c" <shell-command>}', but
162 slightly more compact.
163
164
165 %%%--------------------------------------------------------------------------
166 \section{Installation and configuration}
167
168
169 \subsection{Unpacking and compiling}
170
171 Before you begin, there are some prerequisites you should check:
172 \begin{itemize}
173 \item You need the Free Software Foundation's gzip program to unpack the
174   distribution archive.
175 \item You need an ANSI-conformant C~compiler and library to correctly compile
176   the source code.  No effort at all has been made to support nonstandard
177   C~implementations.\footnote{
178     The ANSI~C standard was ratified in 1989.  It is now 1997.  If your
179     system vendor hasn't bothered to comply with an eight year old standard,
180     you ought to firstly complain to your vendor, and secondly install the
181     GNU~C compiler.}
182 \item You need a copy of GNU make to build the software.  This can be
183   obtained from any GNU software archive.
184 \item You'll probably need GNU flex and bison to rebuild the scanner and
185   parser.  However, prebuilt C~source for these components is provided, and
186   will probably work.
187 \item A recent version of \LaTeX\ is required for formatting the manual.  For
188   those without \LaTeX, a formatted version of the manual is supplied, in
189   PostScript form.
190 \end{itemize}
191
192 The \become\ software is distributed as a gzipped tape archive: saying
193 \begin{verbatim}
194     $ gunzip -c become-1.1.tar.gz | tar xvf -
195 \end{verbatim}
196 will decompress and unpack the source code into a directory
197 \path{become-1.1}.
198
199 The software must be configured prior to compilation.  The author has used
200 the Free Software Foundation's Autoconf system which will (with luck)
201 configure \become\ correctly for the host platform.  The simplest way to do
202 this is to change into the unpacked source directory and say
203 \begin{verbatim}
204     $ ./configure
205 \end{verbatim}
206 If you're compiling for several architectures, you can keep the object files
207 for each in a separate directory.  To do this, create a directory for each
208 one, e.g., by saying something like
209 \begin{verbatim}
210     $ mkdir linux solaris
211 \end{verbatim}
212 Then make the appropriate directory current, and run the configure script
213 from the parent directory:
214 \begin{verbatim}
215     $ cd linux
216     $ ../configure
217 \end{verbatim}
218
219 Without any arguments, the configure script will attempt to deduce all it
220 needs to know about your platform, and it will choose default places to
221 install files.  You can change the configure script's ideas about where to
222 put the files by passing it command line arguments.  By default, all of
223 \become's files are placed relative to a \emph{prefix} directory (so binaries
224 go in \emph{prefix}\path{/bin} and so on).  The prefix directory is usually
225 \path{/usr/local}, although you can change this by using the
226 \texttt{--prefix} option, e.g.,
227 \begin{verbatim}
228     $ ./configure --prefix=/usr/local/become-1.1
229 \end{verbatim}
230 (This will keep all of \become's files in a subdirectory of
231 \path{/usr/local}, which you may find makes maintenance easier.)
232
233 You can also choose different locations for various types of file.  Most
234 importantly, \become's configuration files are put into a `system
235 configuration' directory, which by default is \emph{prefix}\path{/etc}.  You
236 can change it using the \texttt{--sysconfdir} option, e.g.,
237 \begin{verbatim}
238     $ ./configure --sysconfdir=/etc/become
239 \end{verbatim}
240 If you're planning to use \become\ in a centralised installation (see
241 section~\ref{sec:become.inst-type} on page~\pageref{sec:become.inst-type})
242 then the system configuration directory \emph{must not} be on a remote
243 filesystem because cryptographic keys are stored in this directory and
244 putting them on a remote filesystem will make them visible on the network.
245
246 A complete list of options accepted by the configure script may be displayed
247 by passing the \texttt{--help} option:
248 \begin{verbatim}
249     $ ./configure --help
250 \end{verbatim}
251
252 You can now build the programs by invoking GNU make.  Whether simply typing
253 \texttt{make} is sufficient to run GNU make depends on your site: ask around
254 if you don't know how to invoke GNU make.
255
256 Finally, you can install the various files to their correct directories by
257 saying
258 \begin{verbatim}
259     $ make install
260 \end{verbatim}
261 (again, using GNU make, so maybe it's not called `\texttt{make}' at your
262 site).
263
264 Congratulations: \become\ is now compiled.  The easy part is now done.
265
266
267 \subsection{Different installation types}
268 \label{sec:become.inst-type}
269
270 There are two types of installation for \become, and which one you choose
271 depends on how you want to maintain the configuration file, which contains
272 the rules describing who is allowed to become whom:
273 \begin{itemize}
274 \item a \emph{standalone} installation, where the configuration is stored
275   locally, and
276 \item a \emph{centralised} installation, where the configuration is stored on
277   a central (and trusted) server.
278 \end{itemize}
279 The difference is basically how you want to maintain the configuration.  In
280 the standalone case, you have to ensure that the configuration file is copied
281 to each participating host each time it gets changed.  In the centralised
282 case, you only have one copy of the configuration file, and have a different
283 problem concerning key distribution.
284
285
286 \subsection{The configuration file}
287
288 The configuration file for \become is called \path{become.conf}, and it's
289 stored in the system configuration directory you set up when compiling the
290 program.  It defines a set of records, each containing four fields:
291 \begin{itemize}
292 \item a \emph{from} field, identifying a class of users;
293 \item a \emph{to} field, identifying a (possibly different) class of users;
294 \item a \emph{commands} field, describing a class of commands; and
295 \item a \emph{hosts} field, describing a class of hosts.
296 \end{itemize}
297 Such a record permits any user in the \emph{from} class to run a command
298 contained in the \emph{commands} class as any user in the \emph{to} class, on
299 any host in the \emph{hosts} class.  If any class fails to match, permission
300 is denied.
301
302 The configuration file can contain comments, which start with a \lit{\#}
303 character and extend to the end of the line; this is the only time when
304 newlines are significant in the configuration file.
305
306 \subsubsection{Allow records}
307
308 A record like the one described above is represented in the configuration
309 file by an \emph{allow record}.  It has the following syntax:
310 \begin{grammar}
311
312 <allow>         ::= \[[
313   `allow'
314     \[ `[' <host-class> `]' \]
315     <user-class> `->' \[ <user-class> \]
316     \[ `:' <command-class> \]
317   `;'
318 \]]
319
320 \end{grammar}
321 The items \<host-class>, \<user-class> and \<command-class> are all
322 \emph{class expressions}.  If you omit one of the classes, then it will match
323 all requests.  So saying
324 \begin{verbatim}
325     allow EVILHACKER -> ;
326 \end{verbatim}
327 allows anyone in the `EVILHACKER' class to become anyone they like,
328 everywhere, and do anything.
329
330 \subsubsection{Class expressions}
331
332 Class expressions allow you to define classes of users, hosts and commands
333 conveniently.
334
335 All class expressions have the same high-level syntax, and it's fairly easy
336 to understand.  It looks a little bit like set notation: you can obtain the
337 union of two classes using the \lit{|} character (or), take intersections
338 using \lit{\&} (and), and subtract classes using \lit{-}.  Finally, you can
339 list several classes by separating them with commas \lit{,}.  The order of
340 precedence, from lowest to highest, is \lit{,}, \lit{-}, \lit{|} and
341 \lit{\&}.\footnote{
342   Actually, the \lit{,} and \lit{|} operators do exactly the same thing.  The
343   only difference is their relative precedence.  It probably helps if you
344   think of them as being conceptually different, though.}
345 You can override the precedence rules by using parentheses.
346
347 The whole syntax looks like this:
348 \begin{grammar}
349
350 <class-expr>    ::= \[[
351   \[ \< <class-minus-expr> \\ `,' \> \] <class-minus-expr>
352  \]]
353
354 <class-minus-expr> ::= \[[
355   \[ \< <class-or-expr> \\ `-' \> \] <class-or-expr>
356 \]]
357
358 <class-or-expr> ::= \[[
359   \[ \< <class-and-expr> \\ `|' \> \] <class-and-expr>
360 \]]
361
362 <class-and-expr> ::= \[[
363   \[ \< <class-primary> \\ `&' \> \] <class-primary>
364 \]]
365
366 <class-primary> ::= \[[
367   \( `(' <class-expr> `)' \\ <class-name> \\ <explicit-item> \)
368 \]]
369
370 \end{grammar}
371
372 \subsubsection{Naming classes}
373
374 To save repetition, you can give names to classes, using one of the three
375 assignment statements:
376 \begin{grammar}
377
378 <user-assign>   ::= \[[ `user' <name> `=' <user-class> `;' \]]
379
380 <host-assign>   ::= \[[ `host' <name> `=' <host-class> `;' \]]
381
382 <command-assign> ::= \[[ `command' <name> `=' <command-class> `;' \]]
383
384 \end{grammar}
385
386 Classes can be defined in terms of themselves: saying
387 \begin{verbatim}
388     user HACKERS = HACKERS | "mdw";
389 \end{verbatim}
390 says to add `mdw' to the class of hackers, for example.  The configuration
391 file is read strictly top-to-bottom, and an allow record already given
392 doesn't change its meaning just because you later redefine of the classes it
393 refers to.
394
395 \subsubsection{Naming users, hosts and commands}
396
397 Right: you now know how to define classes in terms of other classes, but
398 you've got to start somewhere.  Each type of class has its own way of
399 identifying members.
400 \begin{itemize}
401 \item A user may be identified either by writing the user's name in double
402   quotes (e.g, \texttt{"mdw"}) or by giving the integer user id (e.g.,
403   \texttt{272}).
404 \item A host may be specified by giving, in quotes, either the host's
405   \emph{fully qualified} name (e.g., \texttt{"excessus.hacker.org"}), or its
406   IP~address, (e.g., \texttt{"158.152.170.219"}).  Note that the IP~address
407   must be quoted too: this is slightly unusual.  Either form may contain
408   wildcards: \lit{?} matches any character, and \lit{*} matches zero or more
409   characters.  For example, I can name all hosts at hacker.org by saying
410   \texttt{"*.hacker.org"}.  \emergencystretch=10pt
411 \item A command may be specified by giving its \emph{full pathname} in quotes
412   (e.g., \texttt{"/sbin/shutdown"}).  Again, wildcards can be used to specify
413   lots of commands at the same time.
414 \end{itemize}
415
416 Also, note that lots of user classes come \emph{predefined}.  A class is
417 defined for every user, named with the user's name, and containing that user.
418 Also, for every group, there is a class, named with the group's name, which
419 contains all users who are members of that group.  You can redefine these
420 classes if you like: they're meant to be a convenience, but if you don't like
421 them, you don't have to use them.
422
423 A warning is in order: some systems have group names which are also user
424 names: in this case, a class is defined containing the named user \emph{and}
425 all the members of the group.  That's probably not desirable.
426
427
428 \subsection{Configuring standalone installations}
429
430 That's it, really.  Make sure that \become\ can find the configuration file
431 on each host.  If \become\ can't find a server to talk to (which it can't
432 because you haven't configured one) it will parse the local configuration
433 file and decide for itself whether to grant the user's request.
434
435 If you're only interested in setting up a standalone installation, then
436 you're finished, and can get on with doing something interesting.
437 Alternatively, read on, and see all the work you don't have to do.
438
439
440 \subsection{Keys and random numbers}
441
442 Because \become\ uses cryptographic methods for communicating with its
443 server, you must set up some encryption keys for it to use.  You need to set
444 up two files, both in \become's system configuration directory:
445 \begin{itemize}
446 \item The file \path{become.key} contains \become's `master' key.  Someone
447   who knows the master key can fake responses from the server, and grant
448   themselves any privileges they like.
449 \item The file \path{become.random} contains a `random number seed' which is
450   used (together with the master key) to generate random numbers (e.g.,
451   session keys).  Someone who knows the random numbers can fake responses
452   from the server, and grant themselves any privileges they like.  It's
453   difficult to actually predict random numbers given the random number seed
454   file, although it's not a good idea to leave the seed lying around.
455 \end{itemize}
456 Both of these files should be stored on a local filesystem, and they should
457 be readable only by the super-user.
458
459 Each of the two files, the key and the random number file, contain a 128-bit
460 number, written in hexadecimal.  To make the thing more readable, you may
461 insert dashes in the number between each chunk of eight digits.\footnote{
462   Actually, you can insert dashes wherever you like in the number, but
463   this is only because the parser is rather primitive.  The author recommends
464   that you stick with every eight digits.}
465 Here's an example of a possible key file:
466 \begin{verbatim}
467     4fda99b0-fcbd8bcb-d1bcf951-e1ed04c9
468 \end{verbatim}
469
470 You should generate 128 genuinely random bits for each file.  It is
471 \emph{not} good enough to use a computer random number generator.  A program
472 will be supplied later which will examine key timings as a source for random
473 numbers.  Also, don't use the number printed above.  That would be really
474 silly.
475
476 To help you do this, a program `keygen' is provided.  It uses timings of
477 keypresses to generate random numbers.  To use the program to generate (for
478 example) the random number seed file, type
479 \begin{verbatim}
480     $ keygen -o become.random
481 \end{verbatim}
482 Keygen will report the number of bits which still need to be generated.  Keep
483 typing until it says `done'.  The program automatically ensures that its
484 output file, if it doesn't already exist, is readable only by its owner.  The
485 command line arguments to keygen are simple:
486 \begin{syntdiag}
487 `keygen' \< \[ `--bits' <number> \\ `--output' <file-name> \] \>
488 \end{syntdiag}
489 If you don't specify a \<number> of bits, a default of 128 random bits are
490 generated, which is correct for IDEA keys.  If you omit the \<file-name>, the
491 random key is written to standard output.
492
493
494 \subsection{Setting up the server and clients}
495
496 You don't need a separate program to run as a \become\ server: the normal
497 \become\ is quite capable of behaving as a server all by itself.  However,
498 before you start the server up, you need to decide on a port to which it will
499 listen.  The author uses port 9876 for testing purposes, and there's not much
500 reason why you couldn't do the same.
501
502 There are three ways you can inform \become\ of your choice of port:
503 \begin{itemize}
504 \item You can pass the port number on the command line, using the
505   \texttt{--port} option.
506 \item You can add a line saying `\syntax{"port" <number> ";"}' to the
507   configuration file.
508 \item You can add an entry to your \path{/etc/services} file (or NIS map),
509   binding your chosen port number to the name `become'.\footnote{
510     Actually, \become\ searches for the port using the filename with which
511     it was invoked, so if you call the \become\ binary \path{splat}, then
512     \become will look for a service labelled `splat'.}
513 \end{itemize}
514 If \become\ still has no idea which port to use, it refuses to start up as a
515 server and reports an error message to you.
516
517 You can also choose a different key file to use, by writing a line of the
518 form `\syntax{"key" <filename> ";"}' in \path{become.conf}.  The client won't
519 listen to this -- only the server does that.
520
521 To make \become\ run as a server, say
522 \begin{verbatim}
523     $ become --daemon
524 \end{verbatim}
525 (or to use an explicit port number, say something like
526 \begin{verbatim}
527     $ become --daemon --port=9876
528 \end{verbatim}
529 replacing \texttt{9876} in the example with your chosen port).  You can also
530 run the daemon with a different configuration file, by using the
531 \texttt{--config-file} option, e.g.,
532 \begin{verbatim}
533     $ become --daemon --config-file=/etc/become/server.conf
534 \end{verbatim}
535
536 Now to configure the clients.  All they need is a file saying where to find
537 the server.  All this contains is a single line of the form
538 \begin{syntdiag}
539   <host-name> \[ `:' <port-number> \]
540 \end{syntdiag}
541 If you omit the port number (or it's otherwise incomprehensible) then
542 \become\ looks at the services table (again using the name under which it was
543 invoked) to find a port.  If it still can't find a port to use, then \become\
544 complains.
545
546 The server wakes up every five minutes to rescan its configuration and
547 encryption key.  Thus, it should react fairly quickly to changes to the user
548 database or to its configuration.  However, you can always force the server
549 to refetch its configuration files by sending it a SIGHUP signal.  To help
550 you do this, the server stores its process id in a file \path{become.pid}
551 within its system configuration directory.
552
553
554 \subsection{Maintaining \become}
555
556 There's not much to it really, apart from updating the configuration file
557 when your requirements change.
558
559 The only other thing you really ought to do is to periodically change the
560 master key.  This should be done about once a week, I'd suspect.  The
561 difficult part is distributing the keys over the network: you don't really
562 want to trust the old keys.  I'd recommend that you investigate `ssh' for key
563 distribution.
564
565
566 \subsection{Summary of \become\ configuration}
567
568 \subsubsection{Table of the configuration files}
569
570 \begin{tabularx}{\textwidth}{@{} >{\ttfamily}l X @{}}
571   \multicolumn{1}{@{}l}{\textbf{File name}} &
572   \multicolumn{1}{l@{}}{\textbf{Contents}} \\
573   become.conf   & Main configuration file.  See the syntax below for the
574                   complete reference \\
575   become.key    & Master encryption key.  Should contain a 128-bit random
576                   number. \\
577   become.pid    & Server's process id (so that you can kill it).  The server
578                   creates this file all by itself. \\
579   become.random & Random number seed for generating session keys.  Should
580                   also contain a 128-bit random number.  Don't be surprised
581                   if the number keeps changing -- it's meant to. \\
582   become.server & Tells the \become\ client where to find the server. \\
583 \end{tabularx}
584
585 \subsubsection{Definitive syntax for \path{become.conf}}
586
587 The syntax for \path{become.conf} files is shown below.  This mainly reprises
588 the syntax shown earlier, but in a different order, and without all the
589 explanatory text getting in the way.
590
591 Firstly, the lexical grammar is as follows:
592
593 \begin{grammar}
594
595 <comment>       ::= \[[
596   `#' \< \tok{any character other than <new-line>} \> <new-line>
597 \]]
598
599 <name>          ::= \[[
600   \tok{letter or `_'} \< \( \tok{letter or `_'} \\ \tok{digit} \) \>
601 \]]
602
603 <integer>       ::= \[[ \< \tok{digit} \> \]]
604
605 <string>        ::= \[[
606   `"' \< \( \tok{any character other than `"', <new-line> or `\\'} \\
607             `\\' \tok{any character other than <new-line>} \) \> `"'
608 \]]
609
610 \end{grammar}
611
612 All \<comment>s and whitespace are ignored entirely.  What's left is parsed
613 as follows:
614
615 \begin{grammar}
616
617 <become-conf>   ::= \[[ \< <statement> \> \]]
618
619 <statement>     ::= \[[
620   \( \( `user' \\ `command' \\ `host' \) <name> `=' <class-expr> `;' \\
621      `allow' <allow-spec> `;' \\
622      `port' <integer> `;' \\
623      `key' <string> `;' \)
624 \]]
625
626 <allow-spec>    ::= \[[
627    \[ `[' <host-class> `]' \]
628   <user-class> `->' \[ <user-class> \]
629   \[ `:' <command-class> \]
630 \]]
631
632 <class-expr>    ::= \[[
633   \[ \< <class-minus-expr> \\ `,' \> \] <class-minus-expr>
634  \]]
635
636 <class-minus-expr> ::= \[[
637   \[ \< <class-or-expr> \\ `-' \> \] <class-or-expr>
638 \]]
639
640 <class-or-expr> ::= \[[
641   \[ \< <class-and-expr> \\ `|' \> \] <class-and-expr>
642 \]]
643
644 <class-and-expr> ::= \[[
645   \[ \< <class-primary> \\ `&' \> \] <class-primary>
646 \]]
647
648 <class-primary> ::= \[[
649   \( `(' <class-expr> `)' \\ <name> \\ <integer> \\ <string> \)
650 \]]
651
652 \end{grammar}
653
654
655 %%%--------------------------------------------------------------------------
656 \section{Cryptographic trivia}
657
658
659 \subsection{Design requirements}
660
661 The way the system works is that the \become\ client program builds a
662 \emph{request block} containing all the information needed to decide whether
663 the user's request is valid.  It then sends this to a server, asking it
664 whether this request should be granted.  If the server replies `yes', then
665 \become\ changes its uid, and runs the user's program.
666
667 The really important point is that the client must be able to trust the
668 responses it gets from the server: the final decision over whether to grant
669 the request lies only with the client.  The server doesn't really need to
670 worry too much about whether it trusts a request -- it's not going to do
671 anything with them anyway except send a reply back.
672
673
674 \subsection{Notation}
675
676 Some slightly weird mathematical notation is used in the following sections.
677 \begin{description}
678 \item [$a \xor b$] denotes the exclusive-or (XOR) operation (bitwise addition
679   mod 2).
680 \item [$(a, b, c)$] denotes concatenation of the quantities $a$, $b$ and $c$.
681 \item [$a[x : y]$] denotes bits $x$ up to $y$ of $a$, including bit~$x$ but
682   \emph{not} bit~$y$.  For example, $a[32:64]$ is a 32-bit quantity.  The
683   bits are labelled starting from the left at zero, and increasing to the
684   right.
685 \item [$E_{k, IV}(a)$] denotes encryption of $a$, using the key $k$ and
686   initialisation vector $IV$.
687 \item [$D_{k, IV}(a)$] denotes decryption of $a$, using the key $k$ and
688   initialisation vector $IV$.
689 \end{description}
690 Encryption is performed using the IDEA algorithm, in 64-bit ciphertext
691 feedback mode.
692
693
694 \subsection{The actual protocol}
695
696 The protocol \become\ uses to communicate with the server is as follows:
697 \begin{enumerate}
698
699 \item The client and server share a secret key~$k$.
700
701 \item The client calculates the following:
702   \begin{description}
703   \item [$F$] is the `from' user id;
704   \item [$T$] is the `to' user id;
705   \item [$C$] is the command the user wishes to execute;
706   \item [$t$] is the current time, as returned from \texttt{time}(2); and
707   \item [$p$] is the client's process id.
708   \end{description}
709   The fields $t$ and~$p$ are to ensure that the client doesn't get confused
710   by replies to the wrong requests.
711
712 \item The client generates a session key~$s$ and initialisation vector~$IV$.
713   It then calculates a checksum
714   \[ X = MD5(F, T, C, t, p)[0:32] \]
715   and sends the server a message
716   \[ \bigl(IV, E_{k, IV}(s), E_{s, IV'}(F, T, C, t, p, X)\bigr) \]
717   where $IV'$ is $E_{k, IV}(s)[64:128]$ (i.e., the last block of ciphertext
718   after encrypting the session key, so the whole message is encrypted as one
719   ciphertext feedback job, with a key change part-way).
720
721 \item The server decrypts the message, and checks it to make sure it's valid:
722   \begin{itemize}
723   \item It checks that $X$ is the correct checksum.
724   \item It ensures that the difference between $t$ and the true time is
725     acceptable.  (The current implementation allows $t$ to be 15 seconds
726     out.)
727   \end{itemize}
728   If either of these checks fails, the request is rejected without
729   acknowledgement.
730
731 \item The server decides whether to grant the request.  If it gives its
732   permission, it sets $a = 1$; otherwise it sets $a = 0$.  It calculates a
733   checksum
734   \[ Y = MD5(t, p, a)[0:32] \]
735   and sends the client a message
736   \[ \bigl(IV'', E_{s, IV''}(t, p, a, Y)\bigr) \]
737   where $IV''$ is the last 64~bits of ciphertext received from the client,
738   continuing the ciphertext feedback again.  (Later versions of \become\
739   might use a different method for deciding on the initialisation vector.)
740
741 \item The client decrypts the reply, and verifies it:
742   \begin{itemize}
743   \item It checks that $Y$ is a valid checksum.
744   \item It checks that the $t$ and $p$ values received match the ones in the
745     original request.
746   \end{itemize}
747   If either fail to match, the reply is discarded, and the client continues
748   to wait for a valid reply (possibly timing out).
749
750 \item The client accepts the reply.  If $a = 1$ it changes uid and executes
751   the named process~$C$.
752
753 \end{enumerate}
754
755 The encryption makes it hard for an attacker to alter the data being
756 transmitted in any meaningful way; the 32-bit checksum means that an altered
757 message has a $2^{-32}$ probability of not being noticed.
758
759 The use of ciphertext feedback mode attempts to prevent chosen-plaintext
760 attacks, even though the user can make the client send arbitrary messages.
761
762
763 \subsection{The random number generator}
764
765 The random number generator is used to generate initialisation vectors and
766 session keys for the cryptographic protocol above.  The random number
767 generator might well change in later versions of \become.
768
769 The current implementation maintains an $n$-bit random number seed~$R_i$.  It
770 generates a 128-bit session key~$s$, an initialisation vector~$IV$ and a new
771 seed~$R_{i+1}$.
772 \[
773    \begin{eqalign}
774    s         &= MD5(R_i, t, p, k) \cr
775    IV        &= MD5(R_i, t, p, s)[0:64] \cr
776    R_{i + 1} &= (R_i[n - 128 : n] \xor s, R_i[0 : n - 128]) \cr
777    \end{eqalign}
778 \]
779 \ifxypic
780   See figure~\ref{fig:become.randgen} for a diagrammatic representation of
781   the generator.  It's
782 \else
783   This is
784 \fi
785 really just a weird sort of feedback shift register, generating 128~bits of
786 data at a time.
787
788 \ifxypic
789 \begin{figure}
790
791   \xymatrix{
792     
793   }
794
795   \caption{The \become\ random number generator}
796   \label{fig:become.randgen}
797 \end{figure}
798 \fi
799
800
801 The use of the secret key~$k$ helps to ensure that even if the random number
802 seed is compromised, an attacker still needs to know $k$ before he can
803 predict session keys.  Of course, if the attacker knows $k$, he has no need
804 to predict session keys: he can just decrypt them from the messages.  The use
805 of the values $t$ and $p$ attempts to add a small quantity of randomness to
806 the seed in each iteration.
807
808
809 \subsection{The `keygen' program}
810
811 The `keygen' program attempts to take advantage of the variations in time
812 between your keystrokes to generate random numbers.  It's not perfect.  It
813 may help a little if you know exactly how it works.
814
815 Keygen keeps track of the interval between keypresses.  It exclusive-ors
816 adjacent interval times together, and strips off leading and trailing
817 sequences of one- or zero-bits.  What's left is shifted into the accumulator.
818 The aim of all this complexity is to measure the variation in key timings,
819 and then discard any uninteresting bits from the result.
820
821 This method works best on machines with very high-resolution clocks
822 (preferably with microsecond granularity), although even on the author's
823 Linux machine, which uses a clock with centisecond granularity, the number of
824 keystrokes required is acceptable.
825
826
827 \subsection{How to break \become's security}
828
829 The author can't see any obvious weaknesses in the protocol used.  Here are
830 some possibilities which might occur to an attacker, though:
831 \begin{itemize}
832
833 \item Forge a server reply packet and send it to the client.  Intercept the
834   request packet and discard it before it reaches the real server.  The
835   required contents of the reply packet can be guessed.  However, encrypting
836   it requires knowledge of the session key sent by the client.  Obtaining
837   this means you need to break the IDEA cipher, which (to the author's
838   knowledge) isn't practical.
839
840 \item Send another packet to the server at the same time, altering the sender
841   address so that the server replies to the wrong host or port.  This won't
842   work, because the client will attempt to decrypt the fake reply with the
843   wrong session key and will reject the packet when it finds that the
844   checksum is incorrect.
845
846 \item Find some other back door into the client host, to become root.  Read
847   the secret key file, and use that to decrypt requests and send back
848   replies.  If you can already become the super-user, why bother cracking
849   \become?
850
851 \item Feed the client program bad input to overflow a fixed-size buffer.  The
852   bad input contains executable code which gives the attacker a privileged
853   shell.  The author isn't aware of any buffers which might overflow as a
854   result of user-supplied data.
855
856 \end{itemize}
857
858 The above assumes that \become\ has been set up correctly.  The following
859 attacks rely on misconfiguration:
860 \begin{itemize}
861
862 \item Watch new secret keys being transmitted over the network when the
863   administrator replaces them.  Now you can decrypt request packets and send
864   back replies.  Make sure that the original server's responses are
865   corrupted so that the client rejects them.
866
867 \item Watch the client or server reading the secret key from a remote
868   filesystem.
869
870 \item Clobber the configuration file when the server re-reads it from a
871   remote filesystem, so that it gives your user account permission to become
872   anyone.
873
874 \end{itemize}
875
876
877 %%%----- Licencing conditions -----------------------------------------------
878
879 \input{gpl}
880
881 %%%----- That's all, folks --------------------------------------------------
882
883 \end{document}
884
885 %%% Local Variables: 
886 %%% mode: latex
887 %%% TeX-master: t
888 %%% End: