From: mdw Date: Sun, 12 Oct 2003 00:14:55 +0000 (+0000) Subject: Major overhaul. Now uses DSA signatures rather than the bogus symmetric X-Git-Url: https://git.distorted.org.uk/~mdw/become/commitdiff_plain/f60a34341fee6aafd5b878dce23b80af7c60064d Major overhaul. Now uses DSA signatures rather than the bogus symmetric encrypt-and-hope thing. Integrated with mLib and Catacomb. --- diff --git a/.links b/.links index 3cf3638..b16ee17 100644 --- a/.links +++ b/.links @@ -5,5 +5,3 @@ manual/texinfo.tex manual/texinice.tex missing mkinstalldirs -src/mdwopt.c -src/mdwopt.h diff --git a/acconfig.h b/acconfig.h index ee00cfd..b6fe638 100644 --- a/acconfig.h +++ b/acconfig.h @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: acconfig.h,v 1.9 1999/05/04 16:25:42 mdw Exp $ + * $Id: acconfig.h,v 1.10 2003/10/12 00:14:44 mdw Exp $ * * Default settings for `become' config.h * @@ -29,6 +29,10 @@ /*----- Revision history --------------------------------------------------* * * $Log: acconfig.h,v $ + * Revision 1.10 2003/10/12 00:14:44 mdw + * Major overhaul. Now uses DSA signatures rather than the bogus symmetric + * encrypt-and-hope thing. Integrated with mLib and Catacomb. + * * Revision 1.9 1999/05/04 16:25:42 mdw * Fixes for new version of automake. * @@ -74,9 +78,6 @@ /* The `etcdir' contains configuration and state information. */ #define ETCDIR "/etc/become" -/* Define to be the size of an int. */ -#define SIZEOF_INT 4 - /* Default login style can be `l_preserve', `l_setuser' or `l_login'. */ #define DEFAULT_LOGIN_STYLE l_preserve @@ -87,7 +88,7 @@ #undef NONETWORK /* Debugging options. */ -#undef TRACING +#undef NTRACE #ifndef TEST_RIG #undef NDEBUG @@ -101,24 +102,16 @@ @BOTTOM@ -/*----- Some light processing on the configuration varaibles --------------*/ +/*----- Some light processing on the configuration variables --------------*/ /* --- Important filenames based on the @ETCDIR@ --- */ #define file_KEY ETCDIR "/become.key" +#define file_PUBKEY ETCDIR "/become.pubkey" #define file_PID ETCDIR "/become.pid" -#define file_RANDSEED ETCDIR "/become.random" #define file_RULES ETCDIR "/become.conf" #define file_SERVER ETCDIR "/become.server" -/* --- Find a suitable 32-bit type --- */ - -#if SIZEOF_INT < 4 - typedef unsigned long uint_32; -#else - typedef unsigned int uint_32; -#endif - /* --- Debugging macros --- */ #ifdef NDEBUG diff --git a/configure.in b/configure.in index e5146fd..ff93341 100644 --- a/configure.in +++ b/configure.in @@ -1,6 +1,6 @@ dnl -*-fundamental-*- dnl -dnl $Id: configure.in,v 1.18 1999/07/28 09:30:12 mdw Exp $ +dnl $Id: configure.in,v 1.19 2003/10/12 00:14:44 mdw Exp $ dnl dnl Source for auto configuration for `become' dnl @@ -28,6 +28,10 @@ dnl Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. dnl----- Revision history --------------------------------------------------- dnl dnl $Log: configure.in,v $ +dnl Revision 1.19 2003/10/12 00:14:44 mdw +dnl Major overhaul. Now uses DSA signatures rather than the bogus symmetric +dnl encrypt-and-hope thing. Integrated with mLib and Catacomb. +dnl dnl Revision 1.18 1999/07/28 09:30:12 mdw dnl Use new-fangled mdw_TYPE_SSIZE_T macro. dnl @@ -89,8 +93,8 @@ dnl Revision 1.1 1997/07/21 13:47:51 mdw dnl Initial revision dnl -AC_INIT(src/icrypt.c) -AM_INIT_AUTOMAKE(become, 1.3.3) +AC_INIT(src/become.c) +AM_INIT_AUTOMAKE(become, 1.4.0) AM_CONFIG_HEADER(config.h) dnl --- Check for compilers and things --- @@ -141,28 +145,15 @@ AC_SUBST(htmldir) dnl --- Debugging stuff --- -AC_ARG_WITH(electric-fence, -[ --with-electric-fence link programs with Electric Fence], - [if test "$withval" = "yes"; then - AC_CHECK_LIB(efence, malloc) - fi]) - -AC_ARG_ENABLE(debugging, -[ --enable-debugging spews vast swathes of useless information], - [if test "$enableval" = "no"; then - AC_DEFINE(NDEBUG, 1) - fi], - AC_DEFINE(NDEBUG, 1)) - -AC_ARG_ENABLE(tracing, -[ --enable-tracing enable output of tracing information], - [if test "$enableval" = "yes"; then - AC_DEFINE(TRACING) - fi], - AC_DEFINE(TRACING)) +mdw_OPT_EFENCE +mdw_OPT_NDEBUG +mdw_OPT_TRACE dnl --- Libraries --- +mdw_MLIB(2.0.1) +mdw_CATACOMB(2.0.1) + mdw_CHECK_MANYLIBS(socket, socket,, [AC_MSG_ERROR([Socket library not found])]) @@ -181,10 +172,6 @@ AC_TYPE_PID_T AC_TYPE_UID_T mdw_TYPE_SSIZE_T -dnl --- Check on type sizes --- - -AC_CHECK_SIZEOF(int, 2) - dnl --- Set the path separator --- AC_DEFINE(PATHSEP, '/') diff --git a/manual/.cvsignore b/manual/.cvsignore index 78384aa..a2942ae 100644 --- a/manual/.cvsignore +++ b/manual/.cvsignore @@ -13,3 +13,4 @@ become.vr become_*.html html stamp-html.in +become.html diff --git a/manual/become.texi b/manual/become.texi index cdf6ef1..58fbf36 100644 --- a/manual/become.texi +++ b/manual/become.texi @@ -1,6 +1,6 @@ \input texinfo @c -*-texinfo-*- @c -@c $Id: become.texi,v 1.4 1998/04/23 13:16:14 mdw Exp $ +@c $Id: become.texi,v 1.5 2003/10/12 00:14:49 mdw Exp $ @c @c Documentation for `become' @c @@ -10,6 +10,10 @@ @c ----- Revision history --------------------------------------------------- @c @c $Log: become.texi,v $ +@c Revision 1.5 2003/10/12 00:14:49 mdw +@c Major overhaul. Now uses DSA signatures rather than the bogus symmetric +@c encrypt-and-hope thing. Integrated with mLib and Catacomb. +@c @c Revision 1.4 1998/04/23 13:16:14 mdw @c Include `texinice' to produce decent printed output. Add documentation @c for new `bcquery' program. Various fixes, including spelling mistakes, @@ -133,6 +137,7 @@ This file documents Become version @value{version}. * Administering Become:: How to maintain Become * Invoking Become:: Reference to Become's command line options +@detailmenu --- The Detailed Node Listing --- Becoming someone else @@ -197,18 +202,15 @@ Networked configuration * Choosing servers:: Which servers Become tries to talk to * Setting up keys:: How to generate keys for Become -* Random number files:: Become keeps random number state around * Issuing a new key:: How to issue new keys without disruption -Setting up keys - -* Invoking keygen:: How to use the @code{keygen} program - Invoking Become * Becoming another user:: Options for becoming another user * Starting Become daemons:: Options for starting Become daemons * Debugging options:: Options to use when Become goes wrong + +@end detailmenu @end menu @c -------------------------------------------------------------------------- @@ -925,16 +927,16 @@ when they get there. Only needed on servers or standalone machines. A list of servers to contact. Only needed on client machines. @item become.key -The encryption key to use when sending requests to servers. Needed on -clients and servers, but not on standalone machines. +The signing key to use when sending requests to servers. Needed on servers, +but not on standalone machines. + +@item become.pubkey +The verification keys to use when checking server responses. Needed on +clients, but not on standalone machines. @item become.pid The process id of the server. Created automatically by Become's server when in starts up. - -@item become.random -Contains state information for Become's random number generator. Created -automatically if it doesn't exist. @end table @@ -1477,7 +1479,6 @@ section. @menu * Choosing servers:: Which servers Become tries to talk to * Setting up keys:: How to generate keys for Become -* Random number files:: Become keeps random number state around * Issuing a new key:: How to issue new keys without disruption @end menu @@ -1508,107 +1509,47 @@ Become isn't particularly processor-intensive, and doesn't seem to require very much memory. -@node Setting up keys, Random number files, Choosing servers, Networked configuration +@node Setting up keys, Issuing a new key, Choosing servers, Networked configuration @subsection Setting up keys Communication between Become clients and the server is encrypted to ensure that it's not feasible to gain unauthorised privilege by subverting the -network. Become uses simple symmetric cryptography -- it's not necessary to -use complicated public key techniques in this case. +network. Become uses the DSA algorithm to ensure authenticity of replies. Each client machine, and the server, must have a copy of the same key. The key is usually stored in @file{/etc/become/become.key}. Become's keys are 128 bits long. -The key file can be generated using the @code{keygen} program, supplied. The -command +The key file can be generated using Catacomb's @code{key} program. The +commands @example -keygen --bits=128 --output=/etc/become/become.key +key -k /etc/become/become.key add -adsa become-dsa +key -k /etc/become/become.key extract -f -secret /etc/become/become.pubkey @end example @noindent -generates a 128-bit key and writes it to @file{/etc/become/become.key} in a -format which Become can read. - -The @code{keygen} program works by measuring the time between keystrokes. It -also tries to obtain some randomness from the environment, and mixes all of -this noise together before it outputs the key file. +will generate a suitable DSA key, and extract the public part. You should +install the public key on all of your client computers, writable only by +root. The private key should be only on the server, and readable or writable +only by root. -Having generated a key, it must be distributed to all of the other hosts -which will use this server. The author recommends using the @code{scp} -program, distributed with the @code{SSH} (Secure Shell) package, for doing -this. +If you have multiple servers, they can all have different private keys. +You'll need to put all of the public keys in the +@file{/etc/become/become.pubkey} file. -Being able to read a key file enables a user to assume root privileges. The -author recommends that only the super-user be able to read key files. -@menu -* Invoking keygen:: How to use the @code{keygen} program -@end menu - - -@node Invoking keygen, , Setting up keys, Setting up keys -@subsubsection Invoking @code{keygen} - -@example -keygen [@var{option}@dots{}] -@end example - -By default, @code{keygen} generates a 128-bit key, and writes it to standard -output in a hexadecimal format. This behaviour can be modified by passing -options: - -@table @code -@item -h -@itemx --help -Write a summary of @code{keygen}'s usage instructions to standard output and -exits. - -@item -b @var{bits} -@itemx --bits=@var{bits} -Generate a @var{bits}-bit key, instead of the default 128 bits. - -@item -o @var{file} -@itemx --output=@var{file} -Write the key to @var{file} instead of standard output. - -@item -f @var{format} -@itemx --format=@var{format} -Set the format in which @code{keygen} outputs the generated key. If the -@var{format} is @samp{hex} (or @samp{tx}), the key is output in Become's -hexadecimal format; @samp{binary} writes the key as a raw binary dump; and -@samp{base64} writes the key using the Base64 encoding. -@end table - - - -@node Random number files, Issuing a new key, Setting up keys, Networked configuration -@subsection Random number files - -Become uses random numbers to generate session keys when it's communicating -with a server. When it's finished, it stores the state of its random number -generator in a file, usually @code{/etc/become/become.random}. If this file -doesn't exist, Become creates it automatically, using noise collected from -the environment. It's probably not worth your while creating randomness -files by hand. - - -@node Issuing a new key, , Random number files, Networked configuration +@node Issuing a new key, , Setting up keys, Networked configuration @subsection Issuing a new key When you're sending out a new key, you run a risk of disrupting service. The server reads a new key; the clients still have the old one. -The author's recommendation is to run two servers. Update the key on one. -Then send the new key to all of the clients. Finally, update the key on the -other server. Because of the way Become works, a client will always get a -response from one of the servers, depending on whether the new key has -reached it yet. - -A similar method is handy if Become's protocol ever changes. (This is quite -likely at the moment. The current protocol doesn't include any version -information, and the MAC isn't as good as it could be.) +We used to recommend running two servers. Now, however, you can generate the +new key, install the new public key on the clients in addition to the old +one, and then install the new private key on the server. The clients try all +valid public keys when attempting to authenticate a response, so this +approach will work. @c -------------------------------------------------------------------------- diff --git a/src/Makefile.am b/src/Makefile.am index aaaf90a..57a4751 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,7 +1,7 @@ ## Process this file with `automake' to generate `Makefile.in' ## -*-makefile-*- ## -## $Id: Makefile.am,v 1.13 1999/05/04 16:50:59 mdw Exp $ +## $Id: Makefile.am,v 1.14 2003/10/12 00:14:55 mdw Exp $ ## ## Makefile for `become' ## @@ -29,6 +29,10 @@ ##----- Revision history ---------------------------------------------------- ## ## $Log: Makefile.am,v $ +## Revision 1.14 2003/10/12 00:14:55 mdw +## Major overhaul. Now uses DSA signatures rather than the bogus symmetric +## encrypt-and-hope thing. Integrated with mLib and Catacomb. +## ## Revision 1.13 1999/05/04 16:50:59 mdw ## Change library to `libbecome.a', for aesthetic reasons. ## @@ -78,7 +82,7 @@ ## --- What to make --- -bin_PROGRAMS = become keygen bcquery +bin_PROGRAMS = become bcquery noinst_LIBRARIES = libbecome.a ##----- Building the main code ---------------------------------------------- @@ -88,21 +92,12 @@ noinst_LIBRARIES = libbecome.a libbecome_a_SOURCES = \ check.c daemon.c \ lexer.l parser.y \ - class.c name.c netg.c rule.c sym.c userdb.c ypstuff.c \ - crypt.c \ - noise.c rand.c \ - icrypt.c blowfish.c md5.c \ - mdwopt.c tx.c utils.c \ + class.c name.c netg.c rule.c userdb.c ypstuff.c \ \ become.h \ check.h daemon.h \ lexer.h parse.h \ - class.h name.h netg.h rule.h sym.h userdb.h ypstuff.h \ - crypt.h \ - noise.h rand.h \ - icrypt.h blowfish.h blowfish-sbox.h md5.h \ - mdwopt.h tx.h utils.h \ - dbutils.h + class.h name.h netg.h rule.h userdb.h ypstuff.h BUILT_SOURCES = \ parser.c parser.h lexer.c @@ -121,11 +116,9 @@ dist-hook: LDADD = libbecome.a @LEXLIB@ become_SOURCES = become.c -keygen_SOURCES = keygen.c bcquery_SOURCES = bcquery.c become_DEPENDENCIES = libbecome.a -keygen_DEPENDENCIES = libbecome.a bcquery_DEPENDENCIES = libbecome.a ##----- Become must be setuid root ------------------------------------------ diff --git a/src/bcquery.c b/src/bcquery.c index 18354c9..2d07ad3 100644 --- a/src/bcquery.c +++ b/src/bcquery.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: bcquery.c,v 1.3 1999/05/04 16:17:11 mdw Exp $ + * $Id: bcquery.c,v 1.4 2003/10/12 00:14:55 mdw Exp $ * * Query and dump Become's configuration file * @@ -29,6 +29,10 @@ /*----- Revision history --------------------------------------------------* * * $Log: bcquery.c,v $ + * Revision 1.4 2003/10/12 00:14:55 mdw + * Major overhaul. Now uses DSA signatures rather than the bogus symmetric + * encrypt-and-hope thing. Integrated with mLib and Catacomb. + * * Revision 1.3 1999/05/04 16:17:11 mdw * Change to header file name for parser. See log for `parse.h' for * details. @@ -70,6 +74,14 @@ #include #include +/* --- mLib headers --- */ + +#include +#include +#include +#include +#include + /* --- Local headers --- */ #include "become.h" @@ -77,13 +89,10 @@ #include "config.h" #include "daemon.h" #include "lexer.h" -#include "mdwopt.h" #include "name.h" #include "netg.h" #include "parse.h" #include "rule.h" -#include "sym.h" -#include "utils.h" #include "userdb.h" /*----- Type definitions --------------------------------------------------*/ @@ -265,7 +274,7 @@ again: bit = cat_what; goto setbits; default: - die("unknown column specifier `%c'", *p); + die(1, "unknown column specifier `%c'", *p); break; setbits: if (mode == m_replace) { @@ -277,7 +286,7 @@ again: else if (mode == m_remove) outmask &= ~bit; else - die("bad mode while setting output mask: %u", mode); + die(1, "bad mode while setting output mask: %u", mode); break; } p++; @@ -285,7 +294,7 @@ again: goto again; } case '?': - die("type `%s --help' for usage information", quis()); + die(1, "type `%s --help' for usage information", quis()); case 0: if (optarg[0] && optarg[1] == 0) switch (optarg[0]) { case '(': case ')': @@ -294,7 +303,7 @@ again: break; } if (!opt) - die("unexpected text `%s' found", optarg); + die(1, "unexpected text `%s' found", optarg); break; } @@ -322,7 +331,7 @@ static qnode *qparse_atom(void) nextopt(); q = qparse_expr(); if (opt != ')') - die("syntax error: expected `)', found `%s'", optname()); + die(1, "syntax error: expected `)', found `%s'", optname()); nextopt(); return (q); } @@ -331,7 +340,7 @@ static qnode *qparse_atom(void) qnode *q = xmalloc(sizeof(*q)); h = gethostbyname(optarg); if (!h) - die("unknown host `%s'", optarg); + die(1, "unknown host `%s'", optarg); q->q_cat = cat_where; memcpy(&q->q_in, h->h_addr, sizeof(q->q_in)); nextopt(); @@ -352,7 +361,7 @@ static qnode *qparse_atom(void) } pw = userdb_userByName(optarg); if (!pw) - die("unknown user `%s'", optarg); + die(1, "unknown user `%s'", optarg); q->q_uid = pw->pw_uid; } nextopt(); @@ -366,7 +375,7 @@ static qnode *qparse_atom(void) return (q); } default: - die("unexpected token: `%s'", optname()); + die(1, "unexpected token: `%s'", optname()); } return (0); } @@ -436,7 +445,7 @@ static qnode *qparse(void) return (0); q = qparse_expr(); if (opt != EOF) - die("syntax error: `%s' unexpected", optname()); + die(1, "syntax error: `%s' unexpected", optname()); return (q); } @@ -538,7 +547,7 @@ again: /* --- Anything else is bogus (and a bug) --- */ - die("unexpected cat code %u in checkrule", q->q_cat); + die(1, "unexpected cat code %u in checkrule", q->q_cat); return (-1); } @@ -577,7 +586,7 @@ static void classfirstrow(class_node *c, const char *fmt, sym_iter *i, break; case clNode_hash: { sym_base *b; - sym_createIter(i, &c->v.t); + sym_mkiter(i, &c->v.t); b = sym_next(i); if (!b) { printf(fmt, ""); @@ -613,7 +622,7 @@ static void showclass(class_node *c, case clNode_hash: { sym_iter i; sym_base *b; - sym_createIter(&i, &c->v.t); + sym_mkiter(&i, &c->v.t); fputc('(', stdout); if ((b = sym_next(&i)) != 0) { sh(b); @@ -821,7 +830,7 @@ int main(int argc, char *argv[]) int ok; if (!fp) - die("couldn't open configuration file `%s': %s", cf, strerror(errno)); + die(1, "couldn't open configuration file `%s': %s", cf, strerror(errno)); lexer_scan(fp); ok = parse(); if (flags & f_check) @@ -866,7 +875,7 @@ int main(int argc, char *argv[]) /* --- Done --- */ if (!(flags & f_match)) - die("no match"); + die(1, "no match"); return (0); } diff --git a/src/become.c b/src/become.c index 6236855..d383084 100644 --- a/src/become.c +++ b/src/become.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: become.c,v 1.21 1999/07/28 09:31:01 mdw Exp $ + * $Id: become.c,v 1.22 2003/10/12 00:14:55 mdw Exp $ * * Main code for `become' * @@ -29,6 +29,10 @@ /*----- Revision history --------------------------------------------------* * * $Log: become.c,v $ + * Revision 1.22 2003/10/12 00:14:55 mdw + * Major overhaul. Now uses DSA signatures rather than the bogus symmetric + * encrypt-and-hope thing. Integrated with mLib and Catacomb. + * * Revision 1.21 1999/07/28 09:31:01 mdw * Empty path components are equivalent to `.'. * @@ -146,6 +150,15 @@ extern char **environ; +/* --- mLib --- */ + +#include +#include +#include +#include +#include +#include + /* --- Local headers --- */ #include "become.h" @@ -153,12 +166,9 @@ extern char **environ; #include "check.h" #include "daemon.h" #include "lexer.h" -#include "mdwopt.h" #include "name.h" #include "parse.h" #include "rule.h" -#include "sym.h" -#include "utils.h" #include "userdb.h" /*----- Type definitions --------------------------------------------------*/ @@ -464,7 +474,7 @@ static void bc__help(FILE *fp, int suid) "-f FILE, --config-file=FILE In daemon mode, read config from FILE\n" #endif ); -#ifdef TRACING +#ifndef NTRACE bc__write(fp, "\n"); if (!suid) { bc__write(fp, @@ -550,7 +560,7 @@ int main(int argc, char *argv[]) { char **p; - sym_createTable(&bc__env); + sym_create(&bc__env); for (p = environ; *p; p++) bc__putenv(0, *p, 0, 0); } @@ -597,7 +607,7 @@ int main(int argc, char *argv[]) /* --- Tracing options --- */ -#ifdef TRACING +#ifndef NTRACE { "impersonate", gFlag_argReq, 0, 'I' }, { "trace", gFlag_argOpt, 0, 'T' }, { "trace-level", gFlag_argOpt, 0, 'L' }, @@ -619,7 +629,7 @@ int main(int argc, char *argv[]) #ifndef NONETWORK "dp:f:" /* Server options */ #endif -#ifdef TRACING +#ifndef NTRACE "I:T::L::" /* Tracing options */ #endif , @@ -664,7 +674,7 @@ int main(int argc, char *argv[]) else { struct group *gr = getgrnam(optarg); if (!gr) - die("unknown group `%s'", optarg); + die(1, "unknown group `%s'", optarg); group = gr->gr_gid; } flags |= f_havegroup; @@ -695,7 +705,7 @@ int main(int argc, char *argv[]) else { struct servent *s = getservbyname(optarg, "udp"); if (!s) - die("unknown service name `%s'", optarg); + die(1, "unknown service name `%s'", optarg); port = s->s_port; } break; @@ -713,7 +723,7 @@ int main(int argc, char *argv[]) * allow it if we're running setuid. Disable the actual login anyway. */ -#ifdef TRACING +#ifndef NTRACE case 'I': if (flags & f_setuid) @@ -725,7 +735,7 @@ int main(int argc, char *argv[]) else pw = getpwnam(optarg); if (!pw) - die("can't impersonate unknown user `%s'", optarg); + die(1, "can't impersonate unknown user `%s'", optarg); from_pw = userdb_copyUser(pw); rq.from = from_pw->pw_uid; flags |= f_dummy; @@ -740,7 +750,7 @@ int main(int argc, char *argv[]) * to! */ -#ifdef TRACING +#ifndef TRACE case 'T': { FILE *fp; @@ -756,12 +766,12 @@ int main(int argc, char *argv[]) if (seteuid(ru)) #endif { - die("couldn't temporarily give up privileges: %s", + die(1, "couldn't temporarily give up privileges: %s", strerror(errno)); } if ((fp = fopen(optarg, "w")) == 0) { - die("couldn't open trace file `%s' for writing: %s", + die(1, "couldn't open trace file `%s' for writing: %s", optarg, strerror(errno)); } @@ -770,9 +780,9 @@ int main(int argc, char *argv[]) #else if (seteuid(eu)) #endif - die("couldn't regain privileges: %s", strerror(errno)); + die(1, "couldn't regain privileges: %s", strerror(errno)); } - traceon(fp, TRACE_DFL); + trace_on(fp, TRACE_DFL); trace(TRACE_MISC, "become: tracing enabled"); } break; @@ -780,22 +790,13 @@ int main(int argc, char *argv[]) /* --- Setting trace levels --- */ -#ifdef TRACING +#ifndef NTRACE case 'L': { - int sense = 1; - unsigned int lvl = 0, l; - const char *p = optarg; /* --- Table of tracing facilities --- */ - typedef struct tr { - char ch; - unsigned int l; - const char *help; - } tr; - - static tr lvltbl[] = { + static trace_opt lvltbl[] = { { 'm', TRACE_MISC, "miscellaneous messages" }, { 's', TRACE_SETUP, "building the request block" }, { 'r', TRACE_RULE, "ruleset scanning" }, @@ -811,51 +812,11 @@ int main(int argc, char *argv[]) { 'A', TRACE_ALL, "all tracing options" }, { 0, 0, 0 } }; - tr *tp; /* --- Output some help if there's no arguemnt --- */ - if (!optarg) { - bc__banner(stdout); - bc__write(stdout, - "\n" - "Tracing options:\n" - "\n"); - for (tp = lvltbl; tp->l; tp++) { - if ((flags & f_setuid) == 0 || tp->l & ~TRACE_PRIV) - printf("%c -- %s\n", tp->ch, tp->help); - } - bc__write(stdout, -"\n" -"Also, `+' and `-' options are recognised to turn on and off various\n" -"tracing options. For example, `A-r' enables everything except ruleset\n" -"tracing, and `A-D+c' is everything except the defaults, but with request\n" -"check tracing.\n" -); - exit(0); - } - - while (*p) { - if (*p == '+') - sense = 1; - else if (*p == '-') - sense = 0; - else { - for (tp = lvltbl; tp->l && *p != tp->ch; tp++) - ; - l = tp->l; - if (flags & f_setuid) - l &= ~TRACE_PRIV; - if (l) - lvl = sense ? (lvl | l) : (lvl & ~l); - else - moan("unknown trace option `%c'", *p); - } - p++; - } - - tracesetlvl(lvl); - yydebug = ((lvl & TRACE_YACC) != 0); + trace_level(traceopt(lvltbl, optarg, TRACE_DFL, + (flags & f_setuid) ? TRACE_PRIV : 0)); } break; #endif @@ -950,7 +911,7 @@ done_options: else pw = getpwnam(who); if (!pw) - die("unknown user `%s'", who); + die(1, "unknown user `%s'", who); to_pw = userdb_copyUser(pw); rq.to = pw->pw_uid; } @@ -963,7 +924,7 @@ done_options: rq.from = getuid(); pw = getpwuid(rq.from); if (!pw) - die("who are you? (can't find user %li)", (long)rq.from); + die(1, "who are you? (can't find user %li)", (long)rq.from); from_pw = userdb_copyUser(pw); } @@ -974,7 +935,7 @@ done_options: struct hostent *he; uname(&u); if ((he = gethostbyname(u.nodename)) == 0) - die("who am I? (can't resolve `%s')", u.nodename); + die(1, "who am I? (can't resolve `%s')", u.nodename); memcpy(&rq.host, he->h_addr, sizeof(rq.host)); } @@ -996,7 +957,7 @@ done_options: /* --- Check that it's valid --- */ if (group != from_pw->pw_gid && group != to_pw->pw_gid) - die("invalid default group"); + die(1, "invalid default group"); #else @@ -1055,7 +1016,7 @@ done_options: if (group == to_gr[i]) goto group_ok; } - die("invalid default group"); + die(1, "invalid default group"); group_ok:; } @@ -1328,7 +1289,7 @@ done_options: sz = 0; - for (sym_createIter(&i, &bc__env); (e = sym_next(&i)) != 0; ) { + for (sym_mkiter(&i, &bc__env); (e = sym_next(&i)) != 0; ) { /* --- Login style expunges all unpreserved variables --- */ @@ -1357,7 +1318,7 @@ done_options: env = qq = xmalloc((sz + 1) * sizeof(*qq)); - for (sym_createIter(&i, &bc__env); (e = sym_next(&i)) != 0; ) + for (sym_mkiter(&i, &bc__env); (e = sym_next(&i)) != 0; ) *qq++ = e->val; *qq++ = 0; } @@ -1415,7 +1376,7 @@ done_options: } if (!p) - die("couldn't find `%s' in path", todo[0]); + die(1, "couldn't find `%s' in path", todo[0]); binary = rq.cmd; free(path); } @@ -1434,7 +1395,7 @@ done_options: q = binary; if (*q != '/') { if (!getcwd(b, sizeof(b))) - die("couldn't read current directory: %s", strerror(errno)); + die(1, "couldn't read current directory: %s", strerror(errno)); p += strlen(p); *p++ = '/'; } @@ -1450,7 +1411,7 @@ done_options: */ if (p >= b + sizeof(b) - 1) - die("internal error: buffer overflow while canonifying path"); + die(1, "internal error: buffer overflow while canonifying path"); /* --- Reduce multiple slashes to just one --- */ @@ -1522,7 +1483,7 @@ done_options: rq.cmd); if (!a) - die("permission denied"); + die(1, "permission denied"); } /* --- Now do the job --- */ @@ -1536,13 +1497,13 @@ done_options: #ifdef HAVE_SETGROUPS if (setgroups(ngroups, groups) < 0) - die("couldn't set groups: %s", strerror(errno)); + die(1, "couldn't set groups: %s", strerror(errno)); #endif if (setgid(group) < 0) - die("couldn't set default group: %s", strerror(errno)); + die(1, "couldn't set default group: %s", strerror(errno)); if (setuid(rq.to) < 0) - die("couldn't set uid: %s", strerror(errno)); + die(1, "couldn't set uid: %s", strerror(errno)); /* --- If this was a login, change current directory --- */ @@ -1558,7 +1519,7 @@ done_options: fflush(0); closelog(); execve(rq.cmd, todo, env); - die("couldn't exec `%s': %s", rq.cmd, strerror(errno)); + die(1, "couldn't exec `%s': %s", rq.cmd, strerror(errno)); return (127); } diff --git a/src/blowfish-sbox.h b/src/blowfish-sbox.h deleted file mode 100644 index 5c45bbc..0000000 --- a/src/blowfish-sbox.h +++ /dev/null @@ -1,326 +0,0 @@ -/* -*-c-*- - * - * $Id: blowfish-sbox.h,v 1.3 1998/01/12 16:45:43 mdw Exp $ - * - * Blowfish encryption routines - * - * (c) 1998 Mark Wooding - */ - -/*----- Licencing notice --------------------------------------------------* - * - * This file is part of `become' - * - * `Become' is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * `Become' is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with `become'; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/*----- Revision history --------------------------------------------------* - * - * $Log: blowfish-sbox.h,v $ - * Revision 1.3 1998/01/12 16:45:43 mdw - * Fix copyright date. - * - * Revision 1.2 1997/08/04 10:24:20 mdw - * Sources placed under CVS control. - * - * Revision 1.1 1997/07/21 13:47:54 mdw - * Initial revision - * - */ - -/*----- Blowfish initialisation tables ------------------------------------*/ - -/* --- These are just digits of %$\pi$% --- */ - -static const blowfish_key blowfish__init = { - - /* --- P-array of round-specific subkeys --- */ - - { 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, - 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, - 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, - 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, - 0x9216d5d9, 0x8979fb1b }, - - /* --- First S-box --- */ - - { 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, - 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, - 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, - 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, - 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, - 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, - 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, - 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, - 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, - 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, - 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, - 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, - 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, - 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, - 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, - 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, - 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, - 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, - 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, - 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, - 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, - 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, - 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, - 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, - 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, - 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, - 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, - 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, - 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, - 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, - 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, - 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, - 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, - 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, - 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, - 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, - 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, - 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, - 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, - 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, - 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, - 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, - 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, - 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, - 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, - 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, - 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, - 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, - 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, - 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, - 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, - 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, - 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, - 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, - 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, - 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, - 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, - 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, - 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, - 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, - 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, - 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, - 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, - 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a }, - - /* --- Second S-box --- */ - - { 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, - 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, - 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, - 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, - 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, - 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, - 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, - 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, - 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, - 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, - 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, - 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, - 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, - 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, - 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, - 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, - 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, - 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, - 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, - 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, - 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, - 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, - 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, - 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, - 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, - 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, - 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, - 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, - 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, - 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, - 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, - 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, - 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, - 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, - 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, - 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, - 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, - 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, - 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, - 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, - 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, - 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, - 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, - 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, - 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, - 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, - 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, - 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, - 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, - 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, - 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, - 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, - 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, - 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, - 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, - 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, - 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, - 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, - 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, - 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, - 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, - 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, - 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, - 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7 }, - - /* --- Third S-box --- */ - - { 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, - 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, - 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, - 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, - 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, - 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, - 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, - 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, - 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, - 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, - 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, - 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, - 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, - 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, - 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, - 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, - 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, - 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, - 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, - 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, - 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, - 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, - 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, - 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, - 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, - 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, - 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, - 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, - 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, - 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, - 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, - 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, - 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, - 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, - 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, - 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, - 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, - 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, - 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, - 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, - 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, - 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, - 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, - 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, - 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, - 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, - 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, - 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, - 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, - 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, - 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, - 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, - 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, - 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, - 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, - 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, - 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, - 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, - 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, - 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, - 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, - 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, - 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, - 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0 }, - - /* --- Fourth and final S-box --- */ - - { 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, - 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, - 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, - 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, - 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, - 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, - 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, - 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, - 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, - 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, - 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, - 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, - 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, - 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, - 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, - 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, - 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, - 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, - 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, - 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, - 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, - 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, - 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, - 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, - 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, - 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, - 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, - 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, - 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, - 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, - 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, - 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, - 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, - 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, - 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, - 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, - 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, - 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, - 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, - 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, - 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, - 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, - 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, - 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, - 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, - 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, - 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, - 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, - 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, - 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, - 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, - 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, - 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, - 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, - 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, - 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, - 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, - 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, - 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, - 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, - 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, - 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, - 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, - 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 } -}; - -/*----- That's all, folks -------------------------------------------------*/ diff --git a/src/blowfish.c b/src/blowfish.c deleted file mode 100644 index 83aeeb5..0000000 --- a/src/blowfish.c +++ /dev/null @@ -1,622 +0,0 @@ -/* -*-c-*- - * - * $Id: blowfish.c,v 1.5 1998/01/12 16:43:48 mdw Exp $ - * - * Blowfish encryption routines - * - * (c) 1998 Mark Wooding - */ - -/*----- Licencing notice --------------------------------------------------* - * - * This file is part of `become' - * - * `Become' is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * `Become' is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with `become'; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/*----- Revision history --------------------------------------------------* - * - * $Log: blowfish.c,v $ - * Revision 1.5 1998/01/12 16:43:48 mdw - * Include required header files. Fix copyright date. - * - * Revision 1.4 1997/12/08 15:29:50 mdw - * Formatting fixes. Very boring. - * - * Revision 1.3 1997/08/07 09:42:58 mdw - * Fix address of the FSF. - * - * Revision 1.2 1997/08/04 10:24:20 mdw - * Sources placed under CVS control. - * - * Revision 1.1 1997/07/21 13:47:53 mdw - * Initial revision - * - */ - -/*----- Header files ------------------------------------------------------*/ - -/* --- ANSI headers --- */ - -#include -#include -#include - -/* --- Local headers --- */ - -#include "config.h" -#include "blowfish.h" -#include "utils.h" - -/*----- Define the initial S-box values -----------------------------------*/ - -#include "blowfish-sbox.h" - -/*----- Useful macros -----------------------------------------------------*/ - -/* --- The Blowfish round function --- * - * - * This is why I like this cipher. The round function is microscopic. And - * very fast. - */ - -#define ROUND(L, R, K) \ - ((L) ^= k->p[K], \ - (R) ^= ((((k->s0[((L) >> 24) & 0xFF]) + \ - k->s1[((L) >> 16) & 0xFF]) ^ \ - k->s2[((L) >> 8) & 0xFF]) + \ - k->s3[((L) >> 0) & 0xFF])) - -/*----- Main code ---------------------------------------------------------*/ - -/* --- @blowfish_encrypt@ --- * - * - * Arguments: @const blowfish_key *k@ = pointer to key block - * @const void *from@ = block to encrypt from - * @void *to@ = block to encrypt to - * - * Returns: --- - * - * Use: Encrypts a block using the Blowfish algorithm. - */ - -void blowfish_encrypt(const blowfish_key *k, const void *from, void *to) -{ - uint_32 l, r; - const unsigned char *f = from; - unsigned char *t = to; - - /* --- Extract left and right block halves --- */ - - l = load32(f + 0); - r = load32(f + 4); - - /* --- Now run the round function on these values --- */ - - ROUND(l, r, 0); - ROUND(r, l, 1); - ROUND(l, r, 2); - ROUND(r, l, 3); - ROUND(l, r, 4); - ROUND(r, l, 5); - ROUND(l, r, 6); - ROUND(r, l, 7); - ROUND(l, r, 8); - ROUND(r, l, 9); - ROUND(l, r, 10); - ROUND(r, l, 11); - ROUND(l, r, 12); - ROUND(r, l, 13); - ROUND(l, r, 14); - ROUND(r, l, 15); - - /* --- Final transformation --- */ - - l ^= k->p[16]; - r ^= k->p[17]; - - /* --- Store the encrypted value --- */ - - store32(t + 0, r); - store32(t + 4, l); -} - -/* --- @blowfish_decrypt@ --- * - * - * Arguments: @const blowfish_key *k@ = pointer to key block - * @const void *from@ = block to decrypt from - * @void *to@ = block to decrypt to - * - * Returns: --- - * - * Use: Decrypts a block using the Blowfish algorithm. - */ - -void blowfish_decrypt(const blowfish_key *k, const void *from, void *to) -{ - uint_32 l, r; - const unsigned char *f = from; - unsigned char *t = to; - - /* --- Extract left and right block halves --- */ - - l = load32(f + 0); - r = load32(f + 4); - - /* --- Now run the round function on these values --- */ - - ROUND(l, r, 17); - ROUND(r, l, 16); - ROUND(l, r, 15); - ROUND(r, l, 14); - ROUND(l, r, 13); - ROUND(r, l, 12); - ROUND(l, r, 11); - ROUND(r, l, 10); - ROUND(l, r, 9); - ROUND(r, l, 8); - ROUND(l, r, 7); - ROUND(r, l, 6); - ROUND(l, r, 5); - ROUND(r, l, 4); - ROUND(l, r, 3); - ROUND(r, l, 2); - - /* --- Final transformation --- */ - - l ^= k->p[1]; - r ^= k->p[0]; - - /* --- Store the decrypted value --- */ - - store32(t + 0, r); - store32(t + 4, l); -} - -/* --- @blowfish__qcrypt@ --- * - * - * Arguments: @const blowfish_key *k@ = pointer to a key block - * @uint_32 *p@ = pointer to block to mangle - * - * Returns: --- - * - * Use: Mangles a block using the Blowfish algorithm. - */ - -static void blowfish__qcrypt(blowfish_key *k, uint_32 *p) -{ - uint_32 l = p[0], r = p[1]; - - /* --- Run the round function --- */ - - ROUND(l, r, 0); - ROUND(r, l, 1); - ROUND(l, r, 2); - ROUND(r, l, 3); - ROUND(l, r, 4); - ROUND(r, l, 5); - ROUND(l, r, 6); - ROUND(r, l, 7); - ROUND(l, r, 8); - ROUND(r, l, 9); - ROUND(l, r, 10); - ROUND(r, l, 11); - ROUND(l, r, 12); - ROUND(r, l, 13); - ROUND(l, r, 14); - ROUND(r, l, 15); - - /* --- Output transformation --- */ - - l ^= k->p[16]; - r ^= k->p[17]; - - /* --- Store the new values --- */ - - p[0] = r; - p[1] = l; -} - -/* --- @blowfish__buildKey@ --- * - * - * Arguments: @blowfish_key *k@ = pointer to a key block to set up - * - * Returns: --- - * - * Use: Sets up the P-array and S-boxes once a key has been mixed - * into the P-array. Use a local copy of the Blowfish - * encryption routine, to avoid penalising the main code too - * much with having to veneer onto a general args-in-words - * function, and to avoid me messing about with transforming - * values backwards and forwards between char arrays and - * integers. - */ - -static void blowfish__buildKey(blowfish_key *k) -{ - uint_32 b[2] = { 0, 0 }; - int i; - - /* --- First, run through the P-array --- */ - - for (i = 0; i < 18; i += 2) { - blowfish__qcrypt(k, b); - k->p[i] = b[0]; - k->p[i + 1] = b[1]; - } - - /* --- Now do the S-boxes --- */ - - for (i = 0; i < 256; i += 2) { - blowfish__qcrypt(k, b); - k->s0[i] = b[0]; - k->s0[i + 1] = b[1]; - } - - for (i = 0; i < 256; i += 2) { - blowfish__qcrypt(k, b); - k->s1[i] = b[0]; - k->s1[i + 1] = b[1]; - } - - for (i = 0; i < 256; i += 2) { - blowfish__qcrypt(k, b); - k->s2[i] = b[0]; - k->s2[i + 1] = b[1]; - } - - for (i = 0; i < 256; i += 2) { - blowfish__qcrypt(k, b); - k->s3[i] = b[0]; - k->s3[i + 1] = b[1]; - } -} - -/* --- @blowfish_setKey@ --- * - * - * Arguments: @blowfish_key *kb@ = pointer to key block to fill - * @void *k@ = pointer to key data - * @size_t sz@ = length of data in bytes - * - * Returns: --- - * - * Use: Expands a key which isn't represented as a number of whole - * words. This is a nonstandard extension, although it can be - * used to support 40-bit keys, which some governments might - * find more palatable than 160-bit (or 448-bit!) keys. - */ - -void blowfish_setKey(blowfish_key *kb, const void *k, size_t sz) -{ - int i, j, l; - const unsigned char *p = k; - uint_32 a; - - memcpy(kb, &blowfish__init, sizeof(blowfish__init)); - - j = 0; - for (i = 0; i < 18; i++) { - a = 0; - for (l = 0; l < 4; l++) { - a = (a << 8) | p[j]; - j++; - if (j >= sz) - j = 0; - } - kb->p[i] ^= a; - } - - blowfish__buildKey(kb); -} - -/*----- Test rig ----------------------------------------------------------*/ - -#ifdef TEST_RIG - -int main(void) -{ - /* --- Stage one: ECB tests --- */ - - { - static struct { - uint_32 k[2]; - uint_32 p[2]; - uint_32 c[2]; - } table[] = { - { { 0x00000000u, 0x00000000u }, - { 0x00000000u, 0x00000000u }, - { 0x4EF99745u, 0x6198DD78u } }, - - { { 0xFFFFFFFFu, 0xFFFFFFFFu }, - { 0xFFFFFFFFu, 0xFFFFFFFFu }, - { 0x51866FD5u, 0xB85ECB8Au } }, - - { { 0x30000000u, 0x00000000u }, - { 0x10000000u, 0x00000001u }, - { 0x7D856F9Au, 0x613063F2u } }, - - { { 0x11111111u, 0x11111111u }, - { 0x11111111u, 0x11111111u }, - { 0x2466DD87u, 0x8B963C9Du } }, - - { { 0x01234567u, 0x89ABCDEFu }, - { 0x11111111u, 0x11111111u }, - { 0x61F9C380u, 0x2281B096u } }, - - { { 0x11111111u, 0x11111111u }, - { 0x01234567u, 0x89ABCDEFu }, - { 0x7D0CC630u, 0xAFDA1EC7u } }, - - { { 0x00000000u, 0x00000000u }, - { 0x00000000u, 0x00000000u }, - { 0x4EF99745u, 0x6198DD78u } }, - - { { 0xFEDCBA98u, 0x76543210u }, - { 0x01234567u, 0x89ABCDEFu }, - { 0x0ACEAB0Fu, 0xC6A0A28Du } }, - - { { 0x7CA11045u, 0x4A1A6E57u }, - { 0x01A1D6D0u, 0x39776742u }, - { 0x59C68245u, 0xEB05282Bu } }, - - { { 0x0131D961u, 0x9DC1376Eu }, - { 0x5CD54CA8u, 0x3DEF57DAu }, - { 0xB1B8CC0Bu, 0x250F09A0u } }, - - { { 0x07A1133Eu, 0x4A0B2686u }, - { 0x0248D438u, 0x06F67172u }, - { 0x1730E577u, 0x8BEA1DA4u } }, - - { { 0x3849674Cu, 0x2602319Eu }, - { 0x51454B58u, 0x2DDF440Au }, - { 0xA25E7856u, 0xCF2651EBu } }, - - { { 0x04B915BAu, 0x43FEB5B6u }, - { 0x42FD4430u, 0x59577FA2u }, - { 0x353882B1u, 0x09CE8F1Au } }, - - { { 0x0113B970u, 0xFD34F2CEu }, - { 0x059B5E08u, 0x51CF143Au }, - { 0x48F4D088u, 0x4C379918u } }, - - { { 0x0170F175u, 0x468FB5E6u }, - { 0x0756D8E0u, 0x774761D2u }, - { 0x432193B7u, 0x8951FC98u } }, - - { { 0x43297FADu, 0x38E373FEu }, - { 0x762514B8u, 0x29BF486Au }, - { 0x13F04154u, 0xD69D1AE5u } }, - - { { 0x07A71370u, 0x45DA2A16u }, - { 0x3BDD1190u, 0x49372802u }, - { 0x2EEDDA93u, 0xFFD39C79u } }, - - { { 0x04689104u, 0xC2FD3B2Fu }, - { 0x26955F68u, 0x35AF609Au }, - { 0xD887E039u, 0x3C2DA6E3u } }, - - { { 0x37D06BB5u, 0x16CB7546u }, - { 0x164D5E40u, 0x4F275232u }, - { 0x5F99D04Fu, 0x5B163969u } }, - - { { 0x1F08260Du, 0x1AC2465Eu }, - { 0x6B056E18u, 0x759F5CCAu }, - { 0x4A057A3Bu, 0x24D3977Bu } }, - - { { 0x58402364u, 0x1ABA6176u }, - { 0x004BD6EFu, 0x09176062u }, - { 0x452031C1u, 0xE4FADA8Eu } }, - - { { 0x02581616u, 0x4629B007u }, - { 0x480D3900u, 0x6EE762F2u }, - { 0x7555AE39u, 0xF59B87BDu } }, - - { { 0x49793EBCu, 0x79B3258Fu }, - { 0x437540C8u, 0x698F3CFAu }, - { 0x53C55F9Cu, 0xB49FC019u } }, - - { { 0x4FB05E15u, 0x15AB73A7u }, - { 0x072D43A0u, 0x77075292u }, - { 0x7A8E7BFAu, 0x937E89A3u } }, - - { { 0x49E95D6Du, 0x4CA229BFu }, - { 0x02FE5577u, 0x8117F12Au }, - { 0xCF9C5D7Au, 0x4986ADB5u } }, - - { { 0x018310DCu, 0x409B26D6u }, - { 0x1D9D5C50u, 0x18F728C2u }, - { 0xD1ABB290u, 0x658BC778u } }, - - { { 0x1C587F1Cu, 0x13924FEFu }, - { 0x30553228u, 0x6D6F295Au }, - { 0x55CB3774u, 0xD13EF201u } }, - - { { 0x01010101u, 0x01010101u }, - { 0x01234567u, 0x89ABCDEFu }, - { 0xFA34EC48u, 0x47B268B2u } }, - - { { 0x1F1F1F1Fu, 0x0E0E0E0Eu }, - { 0x01234567u, 0x89ABCDEFu }, - { 0xA7907951u, 0x08EA3CAEu } }, - - { { 0xE0FEE0FEu, 0xF1FEF1FEu }, - { 0x01234567u, 0x89ABCDEFu }, - { 0xC39E072Du, 0x9FAC631Du } }, - - { { 0x00000000u, 0x00000000u }, - { 0xFFFFFFFFu, 0xFFFFFFFFu }, - { 0x014933E0u, 0xCDAFF6E4u } }, - - { { 0xFFFFFFFFu, 0xFFFFFFFFu }, - { 0x00000000u, 0x00000000u }, - { 0xF21E9A77u, 0xB71C49BCu } }, - - { { 0x01234567u, 0x89ABCDEFu }, - { 0x00000000u, 0x00000000u }, - { 0x24594688u, 0x5754369Au } }, - - { { 0xFEDCBA98u, 0x76543210u }, - { 0xFFFFFFFFu, 0xFFFFFFFFu }, - { 0x6B5C5A9Cu, 0x5D9E0A5Au } } - }; - - int f = 1; - int i; - - printf("*** stage one: "); - fflush(stdout); - - for (i = 0; i < sizeof(table) / sizeof(table[0]); i++) { - char kb[8], p[8], c[8]; - blowfish_key k; - - store32(kb + 0, table[i].k[0]); - store32(kb + 4, table[i].k[1]); - blowfish_setKey(&k, kb, 8); - - store32(p + 0, table[i].p[0]); - store32(p + 4, table[i].p[1]); - blowfish_encrypt(&k, p, c); - - if (load32(c + 0) != table[i].c[0] || - load32(c + 4) != table[i].c[1]) { - printf("\n" - "!!! bad encryption\n" - " key = %08lx-%08lx\n" - " plaintext = %08lx-%08lx\n" - " expected ciphertext = %08lx-%08lx\n" - " calculated ciphertext = %08lx-%08lx\n", - (unsigned long)table[i].k[0], - (unsigned long)table[i].k[1], - (unsigned long)table[i].p[0], - (unsigned long)table[i].p[1], - (unsigned long)table[i].c[0], - (unsigned long)table[i].c[1], - (unsigned long)load32(c + 0), - (unsigned long)load32(c + 4)); - f = 0; - } - - blowfish_decrypt(&k, c, p); - if (load32(p + 0) != table[i].p[0] || - load32(p + 4) != table[i].p[1]) { - printf("\n" - "!!! bad decryption\n" - " key = %08lx-%08lx\n" - " ciphertext = %08lx-%08lx\n" - " expected plaintext = %08lx-%08lx\n" - " calculated plaintext = %08lx-%08lx\n", - (unsigned long)table[i].k[0], - (unsigned long)table[i].k[1], - (unsigned long)table[i].c[0], - (unsigned long)table[i].c[1], - (unsigned long)table[i].p[0], - (unsigned long)table[i].p[1], - (unsigned long)load32(p + 0), - (unsigned long)load32(p + 4)); - f = 0; - } - - putchar('.'); - fflush(stdout); - } - putchar('\n'); - if (f) - printf("*** stage one ok\n"); - } - - /* --- Stage 2: key scheduling --- */ - - { - static struct { - uint_32 c[2]; - } table[] = { - {{ 0xF9AD597Cu, 0x49DB005Eu }}, - {{ 0xE91D21C1u, 0xD961A6D6u }}, - {{ 0xE9C2B70Au, 0x1BC65CF3u }}, - {{ 0xBE1E6394u, 0x08640F05u }}, - {{ 0xB39E4448u, 0x1BDB1E6Eu }}, - {{ 0x9457AA83u, 0xB1928C0Du }}, - {{ 0x8BB77032u, 0xF960629Du }}, - {{ 0xE87A244Eu, 0x2CC85E82u }}, - {{ 0x15750E7Au, 0x4F4EC577u }}, - {{ 0x122BA70Bu, 0x3AB64AE0u }}, - {{ 0x3A833C9Au, 0xFFC537F6u }}, - {{ 0x9409DA87u, 0xA90F6BF2u }}, - {{ 0x884F8062u, 0x5060B8B4u }}, - {{ 0x1F85031Cu, 0x19E11968u }}, - {{ 0x79D9373Au, 0x714CA34Fu }}, - {{ 0x93142887u, 0xEE3BE15Cu }}, - {{ 0x03429E83u, 0x8CE2D14Bu }}, - {{ 0xA4299E27u, 0x469FF67Bu }}, - {{ 0xAFD5AED1u, 0xC1BC96A8u }}, - {{ 0x10851C0Eu, 0x3858DA9Fu }}, - {{ 0xE6F51ED7u, 0x9B9DB21Fu }}, - {{ 0x64A6E14Au, 0xFD36B46Fu }}, - {{ 0x80C7D7D4u, 0x5A5479ADu }}, - {{ 0x05044B62u, 0xFA52D080u }}, - }; - - unsigned char kk[] = { - 0xF0, 0xE1, 0xD2, 0xC3, 0xB4, 0xA5, 0x96, 0x87, - 0x78, 0x69, 0x5A, 0x4B, 0x3C, 0x2D, 0x1E, 0x0F, - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 - }; - - int i; - int f = 1; - - printf("*** stage two: "); - fflush(stdout); - - for (i = 0; i < sizeof(kk); i++) { - blowfish_key k; - unsigned char p[8] = { 0xFE, 0xDC, 0xBA, 0x98, - 0x76, 0x54, 0x32, 0x10 }; - - blowfish_setKey(&k, kk, i + 1); - blowfish_encrypt(&k, p, p); - - if (load32(p + 0) != table[i].c[0] || - load32(p + 4) != table[i].c[1]) { - printf("!!! bad encryption\n" - " key length = %i\n" - " expected = %08lx-%08lx\n" - " calculated = %08lx-%08lx\n", - i + 1, - (unsigned long)table[i].c[0], - (unsigned long)table[i].c[1], - (unsigned long)load32(p + 0), - (unsigned long)load32(p + 4)); - f = 0; - } - - putchar('.'); - fflush(stdout); - } - - putchar('\n'); - - if (f) - printf("*** stage two ok\n"); - } - - return (0); - -} - -#endif - -/*----- That's all, folks -------------------------------------------------*/ diff --git a/src/blowfish.h b/src/blowfish.h deleted file mode 100644 index d008988..0000000 --- a/src/blowfish.h +++ /dev/null @@ -1,137 +0,0 @@ -/* -*-c-*- - * - * $Id: blowfish.h,v 1.5 1998/01/12 16:45:45 mdw Exp $ - * - * Blowfish encryption routines - * - * (c) 1998 Mark Wooding - */ - -/*----- Licensing notice --------------------------------------------------* - * - * This file is part of `become' - * - * `Become' is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * `Become' is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with `become'; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/*----- Revision history --------------------------------------------------* - * - * $Log: blowfish.h,v $ - * Revision 1.5 1998/01/12 16:45:45 mdw - * Fix copyright date. - * - * Revision 1.4 1997/09/26 09:14:57 mdw - * Merged blowfish branch into trunk. - * - * Revision 1.3.2.1 1997/09/26 09:07:59 mdw - * Use the Blowfish encryption algorithm instead of IDEA. This is partly - * because I prefer Blowfish (without any particularly strong evidence) but - * mainly because IDEA is patented and Blowfish isn't. - * - * Revision 1.3 1997/08/07 09:43:20 mdw - * Fix address of the FSF. - * - * Revision 1.2 1997/08/04 10:24:20 mdw - * Sources placed under CVS control. - * - * Revision 1.1 1997/07/21 13:47:53 mdw - * Initial revision - * - */ - -#ifndef BLOWFISH_H -#define BLOWFISH_H - -#ifdef __cplusplus - extern "C" { -#endif - -/*----- Required headers --------------------------------------------------*/ - -#ifndef CONFIG_H -# include "config.h" -#endif - -/*----- Type definitions --------------------------------------------------*/ - -/* --- A blowfish expanded key --- */ - -typedef struct blowfish_key { - uint_32 p[18]; - uint_32 s0[256]; - uint_32 s1[256]; - uint_32 s2[256]; - uint_32 s3[256]; -} blowfish_key; - -/* --- Size of a blowfish block --- */ - -#define BLOWFISH_BLKSIZE (8u) - -/*----- Functions provided ------------------------------------------------*/ - -/* --- @blowfish_encrypt@ --- * - * - * Arguments: @const blowfish_key *k@ = pointer to key block - * @const voic *from@ = block to encrypt from - * @void *to@ = block to encrypt to - * - * Returns: --- - * - * Use: Encrypts a block using the Blowfish algorithm. - */ - -extern void blowfish_encrypt(const blowfish_key */*k*/, - const void */*from*/, void */*to*/); - - -/* --- @blowfish_decrypt@ --- * - * - * Arguments: @const blowfish_key *k@ = pointer to key block - * @const void *from@ = block to decrypt from - * @void *to@ = block to decrypt to - * - * Returns: --- - * - * Use: Decrypts a block using the Blowfish algorithm. - */ - -extern void blowfish_decrypt(const blowfish_key */*k*/, - const void */*from*/, void */*to*/); - -/* --- @blowfish_setKey@ --- * - * - * Arguments: @blowfish_key *kb@ = pointer to key block to fill - * @void *k@ = pointer to key data - * @size_t sz@ = length of data in bytes - * - * Returns: --- - * - * Use: Expands a key which isn't represented as a number of whole - * words. This is a nonstandard extension, although it can be - * used to support 40-bit keys, which some governments might - * find more palatable than 160-bit (or 448-bit!) keys. - */ - -extern void blowfish_setKey(blowfish_key */*kb*/, - const void */*k*/, size_t /*sz*/); - -/*----- That's all, folks -------------------------------------------------*/ - -#ifdef __cplusplus - } -#endif - -#endif diff --git a/src/check.c b/src/check.c index f4ac5e9..5b29b72 100644 --- a/src/check.c +++ b/src/check.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: check.c,v 1.10 1999/05/04 16:17:12 mdw Exp $ + * $Id: check.c,v 1.11 2003/10/12 00:14:55 mdw Exp $ * * Check validity of requests * @@ -29,6 +29,10 @@ /*----- Revision history --------------------------------------------------* * * $Log: check.c,v $ + * Revision 1.11 2003/10/12 00:14:55 mdw + * Major overhaul. Now uses DSA signatures rather than the bogus symmetric + * encrypt-and-hope thing. Integrated with mLib and Catacomb. + * * Revision 1.10 1999/05/04 16:17:12 mdw * Change to header file name for parser. See log for `parse.h' for * details. @@ -94,20 +98,34 @@ #include #include +/* --- mLib headers --- */ + +#include +#include +#include +#include +#include + +/* --- Catacomb headers --- */ + +#include +#include +#include +#include +#include +#include +#include + /* --- Local headers --- */ #include "become.h" -#include "blowfish.h" #include "config.h" -#include "crypt.h" #include "lexer.h" #include "name.h" #include "netg.h" #include "rule.h" #include "parse.h" -#include "tx.h" #include "userdb.h" -#include "utils.h" /*----- Client-end network support ----------------------------------------*/ @@ -115,7 +133,8 @@ /* --- @check__send@ --- * * - * Arguments: @unsigned char *crq@ = pointer to encrypted request + * Arguments: @char *buf@ = pointer to encrypted request + * @size_t sz@ = size of request * @int fd@ = socket to send from * @struct sockaddr_in *serv@ = pointer to table of servers * @size_t n_serv@ = number of servers @@ -127,7 +146,7 @@ * reported. */ -static void check__send(unsigned char *crq, int fd, +static void check__send(char *buf, size_t sz, int fd, struct sockaddr_in *serv, size_t n_serv) { size_t i; @@ -135,7 +154,7 @@ static void check__send(unsigned char *crq, int fd, int err = 0; for (i = 0; i < n_serv; i++) { - if (sendto(fd, (char *)crq, crq_size, 0, + if (sendto(fd, buf, sz, 0, (struct sockaddr *)(serv + i), sizeof(serv[i])) < 0) { T( trace(TRACE_CLIENT, "client: send to %s failed: %s", inet_ntoa(serv[i].sin_addr), strerror(errno)); ) @@ -145,7 +164,7 @@ static void check__send(unsigned char *crq, int fd, } if (!ok) - die("couldn't send request to server: %s", strerror(err)); + die(1, "couldn't send request to server: %s", strerror(err)); } /* --- @check__ask@ --- * @@ -162,181 +181,188 @@ static void check__send(unsigned char *crq, int fd, static int check__ask(request *rq, struct sockaddr_in *serv, size_t n_serv) { + static int tbl[] = { 0, 5, 10, 20, -1 }; + + char buff[2048], rbuff[2048]; + size_t rqlen; + octet hmsg[SHA_HASHSZ]; + octet h[SHA_HASHSZ]; + key_packstruct kps[DSA_PUBFETCHSZ]; + key_packdef *kp; + dsa_pub kpub; + buf b; + sha_ctx hc; int fd; - unsigned char crq[crq_size]; - unsigned char sk[BLOWFISH_KEYSIZE]; - time_t t; - pid_t pid; - - /* --- First, build the encrypted request packet --- */ - - { - unsigned char k[BLOWFISH_KEYSIZE]; - FILE *fp; + struct sockaddr_in sin; + socklen_t slen; + ssize_t sz; + int ans; + fd_set fds; + struct timeval start, now, tv; + mp *m, *r, *s; + key_file f; + key *k; + key_iter ki; + int ind; + size_t i; - /* --- Read in the encryption key --- */ + /* --- Open the public keyring --- */ - if ((fp = fopen(file_KEY, "r")) == 0) { - die("couldn't open key file `%s': %s", file_KEY, - strerror(errno)); - } - if (fcntl(fileno(fp), F_SETFD, 1) < 0) { - die("couldn't set close-on-exec on key file `%s': %s", file_KEY, - strerror(errno)); - } - tx_getBits(k, 128, fp); - fclose(fp); + if ((key_open(&f, file_PUBKEY, KOPEN_READ, key_moan, 0)) != 0) + die(1, "couldn't open public keyring"); + kp = key_fetchinit(dsa_pubfetch, kps, &kpub); - /* --- Now build a request packet --- */ + /* --- Build the request packet --- */ - t = time(0); - pid = getpid(); - crypt_packRequest(rq, crq, t, pid, k, sk); - burn(k); - T( trace(TRACE_CLIENT, "client: encrypted request packet"); ) - } + rand_noisesrc(RAND_GLOBAL, &noise_source); + rand_seed(RAND_GLOBAL, 160); + buf_init(&b, buff, sizeof(buff)); + rand_get(RAND_GLOBAL, buf_get(&b, SHA_HASHSZ), SHA_HASHSZ); + buf_putu32(&b, rq->from); + buf_putu32(&b, rq->to); + buf_putu16(&b, strlen(rq->cmd)); + buf_put(&b, rq->cmd, strlen(rq->cmd)); + rqlen = BLEN(&b); + sha_init(&hc); + sha_hash(&hc, buff, rqlen); + sha_done(&hc, hmsg); /* --- Create my socket --- */ - { - struct sockaddr_in sin; + if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) + die(1, "couldn't create socket: %s", strerror(errno)); + if (fcntl(fd, F_SETFD, 1) < 0) + die(1, "couldn't set close-on-exec flag for socket: %s", strerror(errno)); - if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) - die("couldn't create socket: %s", strerror(errno)); - if (fcntl(fd, F_SETFD, 1) < 0) - die("couldn't set close-on-exec flag for socket: %s", strerror(errno)); + /* --- Bind myself to some address --- */ - /* --- Bind myself to some address --- */ + sin.sin_family = AF_INET; + sin.sin_port = 0; + sin.sin_addr.s_addr = htonl(INADDR_ANY); - sin.sin_family = AF_INET; - sin.sin_port = 0; - sin.sin_addr.s_addr = htonl(INADDR_ANY); + if (bind(fd, (struct sockaddr *)&sin, sizeof(sin)) < 0) + die(1, "couldn't bind socket to address: %s", strerror(errno)); - if (bind(fd, (struct sockaddr *)&sin, sizeof(sin)) < 0) - die("couldn't bind socket to address: %s", strerror(errno)); - } + /* --- Find out when we are --- */ - /* --- Now wait for a reply --- */ + gettimeofday(&start, 0); + ind = 0; - { - fd_set fds; - struct timeval start, now, tv; - int ind; - size_t i; + /* --- Now loop until everything's done --- */ + + for (;;) { + gettimeofday(&now, 0); - /* --- State table for waiting for replies --- * + /* --- If the current timer has expired, find one that hasn't --- * * - * For each number, send off the request to our servers, and wait for - * that many seconds to have elapsed since we started. If the number is - * %$-1$% then it's time to give up. + * Also resend the request after I've found a timer which is still + * extant. If there aren't any, report an error. */ - static int tbl[] = { 0, 5, 10, 20, -1 }; + if (now.tv_sec >= start.tv_sec + tbl[ind] && + now.tv_usec >= start.tv_usec) { + do { + ind++; + if (tbl[ind] < 0) + die(1, "no reply from servers"); + } while (now.tv_sec >= start.tv_sec + tbl[ind] && + now.tv_usec >= start.tv_usec); + check__send(buff, rqlen, fd, serv, n_serv); + T( trace(TRACE_CLIENT, "client: send request to servers"); ) + } + + /* --- Now wait for a packet to arrive --- */ - /* --- Find out when we are --- */ + if (now.tv_usec > start.tv_usec) { + now.tv_usec -= 1000000; + now.tv_sec += 1; + } + tv.tv_sec = start.tv_sec + tbl[ind] - now.tv_sec; + tv.tv_usec = start.tv_usec - now.tv_usec; - gettimeofday(&start, 0); - ind = 0; + /* --- Sort out file descriptors to watch --- */ - /* --- Now loop until everything's done --- */ + FD_ZERO(&fds); + FD_SET(fd, &fds); - for (;;) { - gettimeofday(&now, 0); + /* --- Wait for them --- */ - /* --- If the current timer has expired, find one that hasn't --- * - * - * Also resend the request after I've found a timer which is still - * extant. If there aren't any, report an error. - */ + i = select(FD_SETSIZE, &fds, 0, 0, &tv); + if (i == 0 || (i < 0 && errno == EINTR)) + continue; + if (i < 0) + die(1, "error waiting for reply: %s", strerror(errno)); - if (now.tv_sec >= start.tv_sec + tbl[ind] && - now.tv_usec >= start.tv_usec) { - do { - ind++; - if (tbl[ind] < 0) - die("no reply from servers"); - } while (now.tv_sec >= start.tv_sec + tbl[ind] && - now.tv_usec >= start.tv_usec); - check__send(crq, fd, serv, n_serv); - T( trace(TRACE_CLIENT, "client: send request to servers"); ) - } + /* --- Read the reply data --- */ - /* --- Now wait for a packet to arrive --- */ + slen = sizeof(sin); + if ((sz = recvfrom(fd, (char *)rbuff, sizeof(rbuff), 0, + (struct sockaddr *)&sin, &slen)) < 0) + die(1, "error reading server's reply: %s", strerror(errno)); - if (now.tv_usec > start.tv_usec) { - now.tv_usec -= 1000000; - now.tv_sec += 1; - } - tv.tv_sec = start.tv_sec + tbl[ind] - now.tv_sec; - tv.tv_usec = start.tv_usec - now.tv_usec; - - /* --- Sort out file descriptors to watch --- */ - - FD_ZERO(&fds); - FD_SET(fd, &fds); - - /* --- Wait for them --- */ - - i = select(FD_SETSIZE, &fds, 0, 0, &tv); - if (i == 0 || (i < 0 && errno == EINTR)) - continue; - if (i < 0) - die("error waiting for reply: %s", strerror(errno)); - - /* --- A reply should be waiting now --- */ - - { - struct sockaddr_in sin; - int slen = sizeof(sin); - unsigned char buff[256]; - int answer; - - /* --- Read the reply data --- */ - - if (recvfrom(fd, (char *)buff, sizeof(buff), 0, - (struct sockaddr *)&sin, &slen) < 0) - die("error reading server's reply: %s", strerror(errno)); - - IF_TRACING(TRACE_CLIENT, { - struct hostent *h = gethostbyaddr((char *)&sin.sin_addr, - sizeof(sin.sin_addr), AF_INET); - trace(TRACE_CLIENT, "client: reply received from %s port %i", - h ? h->h_name : inet_ntoa(sin.sin_addr), - ntohs(sin.sin_port)); - }) - - /* --- Verify the sender --- * - * - * This is more to avoid confusion than for security: an active - * attacker is quite capable of forging the source address. We rely - * on the checksum in the reply packet for authentication. - */ - - for (i = 0; i < n_serv; i++) { - if (sin.sin_addr.s_addr == serv[i].sin_addr.s_addr && - sin.sin_port == serv[i].sin_port) - break; - } - if (i >= n_serv) { - T( trace(TRACE_CLIENT, "client: reply from unknown host"); ) - continue; - } - - /* --- Unpack and verify the response --- */ - - answer = crypt_unpackReply(buff, sk, t, pid); - if (answer < 0) { - T( trace(TRACE_CLIENT, - "client: invalid or corrupt reply packet"); ) - continue; - } + IF_TRACING(TRACE_CLIENT, { + struct hostent *h = gethostbyaddr((char *)&sin.sin_addr, + sizeof(sin.sin_addr), AF_INET); + trace(TRACE_CLIENT, "client: reply received from %s port %i", + h ? h->h_name : inet_ntoa(sin.sin_addr), + ntohs(sin.sin_port)); + }) + + /* --- Verify the sender --- * + * + * This is more to avoid confusion than for security: an active + * attacker is quite capable of forging the source address. We rely + * on the signature in the reply packet for authentication. + */ + + for (i = 0; i < n_serv; i++) { + if (sin.sin_addr.s_addr == serv[i].sin_addr.s_addr && + sin.sin_port == serv[i].sin_port) + break; + } + if (i >= n_serv) { + T( trace(TRACE_CLIENT, "client: reply from unknown host"); ) + continue; + } + + /* --- Unpack and verify the response --- */ + + buf_init(&b, rbuff, sz); + if (buf_ensure(&b, sizeof(hmsg))) goto bad; + if (memcmp(BCUR(&b), hmsg, sizeof(hmsg)) != 0) goto bad; + BSTEP(&b, sizeof(hmsg)); + if ((ans = buf_getbyte(&b)) < 0) goto bad; + + sha_init(&hc); + sha_hash(&hc, BBASE(&b), BLEN(&b)); + sha_done(&hc, h); + if ((r = buf_getmp(&b)) == 0 || (s = buf_getmp(&b)) == 0) goto bad; + m = mp_loadb(MP_NEW, h, sizeof(h)); + + key_mkiter(&ki, &f); + while ((k = key_next(&ki)) != 0) { + if (key_expired(k)) continue; + if (strcmp(k->type, "become-dsa") != 0) continue; + if (key_fetch(kp, k)) continue; + i = dsa_vrfy(&kpub.dp, kpub.y, m, r, s); + dsa_pubfree(&kpub); + if (i) { + key_fetchdone(kp); + key_close(&f); close(fd); - return (answer); + mp_drop(m); + mp_drop(r); + mp_drop(s); + return (ans); } } + + bad: + T( trace(TRACE_CLIENT, + "client: invalid or corrupt reply packet"); ) } - die("internal error: can't get here in check__ask"); + die(1, "internal error: can't get here in check__ask"); return (0); } @@ -428,7 +454,7 @@ int check__client(request *rq, FILE *fp) case st_host: if (p == l) - die("string too long in `" file_SERVER "'"); + die(1, "string too long in `" file_SERVER "'"); if (ch != EOF && !isspace((unsigned char)ch) && ch != ':') { *p++ = ch; ch = getc(fp); @@ -437,7 +463,7 @@ int check__client(request *rq, FILE *fp) *p++ = 0; if ((h = gethostbyname(buff)) == 0) - die("unknown host `%s' in `" file_SERVER "'", buff); + die(1, "unknown host `%s' in `" file_SERVER "'", buff); memcpy(&t_host, h->h_addr, sizeof(t_host)); state = st_colon; } @@ -475,7 +501,7 @@ int check__client(request *rq, FILE *fp) case st_port: if (p == l) - die("string too long in `" file_SERVER "'"); + die(1, "string too long in `" file_SERVER "'"); if (ch != EOF && !isspace((unsigned char)ch) && ch != ':') { *p++ = ch; ch = getc(fp); @@ -487,7 +513,7 @@ int check__client(request *rq, FILE *fp) if (!s && isdigit((unsigned char)buff[0])) t_port = htons(atoi(buff)); else if (!s) - die("unknown service `%s' in `" file_SERVER "'", buff); + die(1, "unknown service `%s' in `" file_SERVER "'", buff); else t_port = s->s_port; state = st_commit; @@ -499,7 +525,8 @@ int check__client(request *rq, FILE *fp) case st_commit: if (n_serv == max_serv) { max_serv *= 2; - serv = xrealloc(serv, max_serv * sizeof(*serv)); + serv = xrealloc(serv, n_serv * sizeof(*serv), + max_serv * sizeof(*serv)); } serv[n_serv].sin_family = AF_INET; serv[n_serv].sin_addr = t_host; @@ -513,7 +540,7 @@ int check__client(request *rq, FILE *fp) /* --- A safety net for a broken parser --- */ default: - die("internal error: can't get here in check__client"); + die(1, "internal error: can't get here in check__client"); break; } } @@ -524,7 +551,7 @@ int check__client(request *rq, FILE *fp) /* --- Now start sending requests --- */ if (!n_serv) - die("no servers specified in `" file_SERVER "'"); + die(1, "no servers specified in `" file_SERVER "'"); IF_TRACING(TRACE_CLIENT, { size_t i; @@ -564,7 +591,7 @@ int check(request *rq) /* --- Otherwise do this all the old-fashioned way --- */ if ((fp = fopen(file_RULES, "r")) == 0) { - die("couldn't read configuration file `%s': %s", + die(1, "couldn't read configuration file `%s': %s", file_RULES, strerror(errno)); } diff --git a/src/class.c b/src/class.c index 31d6de6..f41e17e 100644 --- a/src/class.c +++ b/src/class.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: class.c,v 1.8 1998/06/08 11:20:36 mdw Exp $ + * $Id: class.c,v 1.9 2003/10/12 00:14:55 mdw Exp $ * * Handling classes of things nicely * @@ -29,6 +29,10 @@ /*----- Revision history --------------------------------------------------* * * $Log: class.c,v $ + * Revision 1.9 2003/10/12 00:14:55 mdw + * Major overhaul. Now uses DSA signatures rather than the bogus symmetric + * encrypt-and-hope thing. Integrated with mLib and Catacomb. + * * Revision 1.8 1998/06/08 11:20:36 mdw * (class__wildMatch) Fixed bug which overran pattern string, spotted by * Mark Rison. @@ -74,12 +78,16 @@ #include +/* --- mLib headers --- */ + +#include +#include +#include + /* --- Local headers --- */ #include "become.h" #include "class.h" -#include "sym.h" -#include "utils.h" /*----- Global variables --------------------------------------------------*/ @@ -213,7 +221,7 @@ void class_dec(class_node *c) free(c->v.s); break; case clNode_hash: - sym_destroyTable(&c->v.t); + sym_destroy(&c->v.t); break; case clNode_union: case clNode_diff: @@ -249,7 +257,7 @@ class_node *class_mod(class_node *c) cc->ref = 1; switch (c->type & clNode_mask) { case clNode_any: - die("internal error: class_mod called on non-modifiable class node"); + die(1, "internal: class_mod called on non-modifiable class node"); break; case clNode_immed: @@ -263,8 +271,8 @@ class_node *class_mod(class_node *c) sym_iter i; sym_base *b; - sym_createTable(&cc->v.t); - for (sym_createIter(&i, &c->v.t); (b = sym_next(&i)) != 0; ) + sym_create(&cc->v.t); + for (sym_mkiter(&i, &c->v.t); (b = sym_next(&i)) != 0; ) sym_find(&cc->v.t, b->name, b->len, sizeof(sym_base), 0); } break; @@ -300,9 +308,9 @@ static class_node *class__hashify(class_node *c) /* --- Some sanity checking --- */ if (~c->type & clFlag_friendly) - die("internal error: class__hashify can't hashify unfriendly nodes"); + die(1, "internal: class__hashify can't hashify unfriendly nodes"); if ((c->type & clNode_mask) != clNode_immed) - die("internal error: class__hashify can't hashify non-immediate nodes"); + die(1, "internal: class__hashify can't hashify non-immediate nodes"); /* --- Split off a private copy of the node --- */ @@ -312,11 +320,11 @@ static class_node *class__hashify(class_node *c) if (c->type & clType_user) { uid_t u = c->v.u; - sym_createTable(&c->v.t); + sym_create(&c->v.t); sym_find(&c->v.t, (char *)&u, sizeof(u), sizeof(sym_base), 0); } else { char *s = c->v.s; - sym_createTable(&c->v.t); + sym_create(&c->v.t); sym_find(&c->v.t, s, -1, sizeof(sym_base), 0); free(s); } @@ -465,7 +473,7 @@ class_node *class__binop(class_node *l, class_node *r, int op) sym_iter i; sym_base *b; - for (sym_createIter(&i, &r->v.t); (b = sym_next(&i)) != 0; ) + for (sym_mkiter(&i, &r->v.t); (b = sym_next(&i)) != 0; ) sym_find(&l->v.t, b->name, b->len, sizeof(sym_base), 0); } break; @@ -486,7 +494,7 @@ class_node *class__binop(class_node *l, class_node *r, int op) sym_iter i; sym_base *b, *f; - for (sym_createIter(&i, &r->v.t); (b = sym_next(&i)) != 0; ) { + for (sym_mkiter(&i, &r->v.t); (b = sym_next(&i)) != 0; ) { if ((f = sym_find(&l->v.t, b->name, b->len, 0, 0)) != 0) sym_remove(&l->v.t, f); } @@ -515,7 +523,7 @@ class_node *class__binop(class_node *l, class_node *r, int op) sym_iter i; sym_base *b; - for (sym_createIter(&i, &l->v.t); (b = sym_next(&i)) != 0; ) { + for (sym_mkiter(&i, &l->v.t); (b = sym_next(&i)) != 0; ) { if (!sym_find(&r->v.t, b->name, b->len, 0, 0)) sym_remove(&l->v.t, b); } @@ -535,7 +543,7 @@ class_node *class__binop(class_node *l, class_node *r, int op) class_dec(r); - sym_createIter(&i, &l->v.t); + sym_mkiter(&i, &l->v.t); if ((b = sym_next(&i)) == 0) { class_dec(l); return (class_none); @@ -543,12 +551,12 @@ class_node *class__binop(class_node *l, class_node *r, int op) if (!sym_next(&i)) { if (type & clType_user) { uid_t u = *(uid_t *)b->name; - sym_destroyTable(&l->v.t); + sym_destroy(&l->v.t); l->type = (l->type & ~clNode_mask) | clNode_immed; l->v.u = u; } else { char *s = xstrdup(b->name); - sym_destroyTable(&l->v.t); + sym_destroy(&l->v.t); l->type = (l->type & ~clNode_mask) | clNode_immed; l->v.s = s; } @@ -772,7 +780,7 @@ int class_matchUser(class_node *c, uid_t u) } } - die("internal error: can't get here in class_matchUser"); + die(1, "internal: can't get here in class_matchUser"); return (0); } @@ -820,7 +828,7 @@ int class_matchCommand(class_node *c, const char *s) } } - die("internal error: can't get here in class_matchCommand"); + die(1, "internal: can't get here in class_matchCommand"); return (0); } @@ -888,7 +896,7 @@ static int class__doMatchHost(class_node *c, const char *ip, } } - die("internal error: can't get here in class_matchUser"); + die(1, "internal: can't get here in class_matchUser"); return (0); } @@ -976,7 +984,7 @@ void class_dump(class_node *c, int indent) sym_iter i; sym_base *b; - for (sym_createIter(&i, &c->v.t); (b = sym_next(&i)) != 0; ) { + for (sym_mkiter(&i, &c->v.t); (b = sym_next(&i)) != 0; ) { if (c->type & clType_user) { trace(TRACE_RULE, "rule:%*s user %lu", indent * 2, "", (unsigned long)*(uid_t *)b->name); diff --git a/src/class.h b/src/class.h index 79965f3..25d661f 100644 --- a/src/class.h +++ b/src/class.h @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: class.h,v 1.5 1998/04/23 13:22:44 mdw Exp $ + * $Id: class.h,v 1.6 2003/10/12 00:14:55 mdw Exp $ * * Handling classes of things nicely * @@ -29,6 +29,10 @@ /*----- Revision history --------------------------------------------------* * * $Log: class.h,v $ + * Revision 1.6 2003/10/12 00:14:55 mdw + * Major overhaul. Now uses DSA signatures rather than the bogus symmetric + * encrypt-and-hope thing. Integrated with mLib and Catacomb. + * * Revision 1.5 1998/04/23 13:22:44 mdw * Fix value of clNode_binop, required for bcquery. * @@ -61,9 +65,7 @@ #include #include -#ifndef SYM_H -# include "sym.h" -#endif +#include /*----- Data structures ---------------------------------------------------*/ diff --git a/src/crypt.c b/src/crypt.c deleted file mode 100644 index 549e94b..0000000 --- a/src/crypt.c +++ /dev/null @@ -1,542 +0,0 @@ -/* -*-c-*- - * - * $Id: crypt.c,v 1.5 1998/06/18 15:08:49 mdw Exp $ - * - * Cryptographic transfer of `become' requests - * - * (c) 1998 EBI - */ - -/*----- Licensing notice --------------------------------------------------* - * - * This file is part of `become' - * - * `Become' is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * `Become' is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with `become'; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/*----- Revision history --------------------------------------------------* - * - * $Log: crypt.c,v $ - * Revision 1.5 1998/06/18 15:08:49 mdw - * Paranoia: set close-on-exec flag for seed file. - * - * Revision 1.4 1998/01/12 16:45:55 mdw - * Fix copyright date. - * - * Revision 1.3 1997/09/26 09:14:58 mdw - * Merged blowfish branch into trunk. - * - * Revision 1.2.2.1 1997/09/26 09:08:02 mdw - * Use the Blowfish encryption algorithm instead of IDEA. This is partly - * because I prefer Blowfish (without any particularly strong evidence) but - * mainly because IDEA is patented and Blowfish isn't. - * - * Revision 1.2 1997/08/04 10:24:21 mdw - * Sources placed under CVS control. - * - * Revision 1.1 1997/07/21 13:47:51 mdw - * Initial revision - * - */ - -/*----- Header files ------------------------------------------------------*/ - -/* --- ANSI headers --- */ - -#include -#include -#include -#include -#include -#include - -/* --- Unix headers --- */ - -#include -#include -#include -#include -#include - -/* --- Local headers --- */ - -#include "become.h" -#include "blowfish.h" -#include "config.h" -#include "crypt.h" -#include "icrypt.h" -#include "md5.h" -#include "noise.h" -#include "rand.h" -#include "tx.h" -#include "utils.h" - -/*----- Magic numbers -----------------------------------------------------*/ - -#define crypt__timeError 60 /* Seconds error to permit */ - -/*----- Main code ---------------------------------------------------------*/ - -/* --- @crypt__sessionKey@ --- * - * - * Arguments: @const char *seedfile@ = pointer to name of seed file - * @unsigned char *k@ = our secret key - * @unsigned *sk@ = where to store the session key - * @unsigned char *iv@ = where to store the IV - * - * Returns: --- - * - * Use: Decides on a random session key and initialisation vector. - */ - -static void crypt__sessionKey(const char *seedfile, unsigned char *k, - unsigned char *sk, unsigned char *iv) -{ - FILE *fp; /* File handle for reading */ - struct flock l; - int ok = 1; - - /* --- Open the random seed file --- * - * - * If I can't manage that, create a new one. - */ - - if ((fp = fopen(seedfile, "r+")) == 0) { - ok = 0; - if ((fp = fopen(seedfile, "w+")) == 0) - die("can't create random number file: %s", strerror(errno)); - rand_clear(); - } - if (fcntl(fileno(fp), F_SETFD, 1) < 0) { - die("can't set close-on-exec for random number file: %s", - strerror(errno)); - } - - /* --- Lock the seed file against concurrency problems --- */ - - l.l_type = F_WRLCK; - l.l_whence = SEEK_SET; - l.l_start = 0; - l.l_len = 0; - if (fcntl(fileno(fp), F_SETLKW, &l) < 0) - die("can't lock random number file: %s", strerror(errno)); - - /* --- Now read the file, and launder the seed --- */ - - if (ok) - rand_read(fp); - - /* --- Encrypt the pool using the secret key --- */ - - { - icrypt_job j; - icrypt_init(&j, k, BLOWFISH_KEYSIZE, 0); - rand_encrypt(&j); - burn(j); - } - - /* --- Generate the session key and IV --- */ - - noise_acquire(); - rand_extract(sk, BLOWFISH_KEYSIZE); - rand_extract(iv, BLOWFISH_BLKSIZE); - - IF_TRACING(TRACE_CRYPTO, - traceblk(TRACE_CRYPTO, "crypto: session key:", sk, BLOWFISH_KEYSIZE); - traceblk(TRACE_CRYPTO, "crypto: initialisation vector:", - iv, BLOWFISH_BLKSIZE); - ); - - /* --- Write the seed back --- */ - - rewind(fp); - rand_write(fp); - fclose(fp); - -} - -/* --- @crypt_packRequest@ --- * - * - * Arguments: @request *rq@ = pointer to request block - * @unsigned char *buff@ = pointer to a buffer - * @time_t t@ = the current time - * @pid_t pid@ = my process ID - * @unsigned char *k@ = pointer to 128-bit key - * @unsigned char *sk@ = where to put the session key - * - * Returns: --- - * - * Use: Packs a request block into a buffer. The buffer should have - * space for at least @crq_size@ bytes. The buffer comes back - * encrypted and ready to send. - */ - -void crypt_packRequest(request *rq, unsigned char *buff, - time_t t, pid_t pid, - unsigned char *k, unsigned char *sk) -{ - /* --- First, build the easy stuff in the block --- */ - - buff[crq_cryptType] = cryptType_blowfish; - store32(buff + crq_time, t); - store32(buff + crq_pid, pid); - store32(buff + crq_from, rq->from); - store32(buff + crq_to, rq->to); - - /* --- Now generate session keys and things --- */ - - crypt__sessionKey(file_RANDSEED, k, sk, buff + crq_iv); - memcpy(buff + crq_session, sk, BLOWFISH_KEYSIZE); - - /* --- The string causes a few problems --- * - * - * There's a good chance that the string will be a good deal shorter than - * the space allowed for it. This will probably mean lots of zeroes, and a - * very easy known-plaintext job for a potential attacker. (An early - * version of this code used @strncpy@ which is even worse!) - * - * I'll fill the block with random (from @rand@(3) -- nothing too - * elaborate) and then encrypt it using Blowfish in CFB mode, using the - * first few bytes as the key. This should provide a sufficiently - * unpredictable background for the block. - */ - - { - icrypt_job j; - unsigned char *p; - unsigned u; - md5 md; - unsigned char qk[BLOWFISH_KEYSIZE]; - - /* --- Initialise the buffer with junk --- */ - - srand((unsigned int)(t ^ pid)); /* Seed the (bad) RNG */ - for (p = buff + crq_cmd; p < buff + crq_cmd + CMDLEN_MAX; p++) { - u = rand(); *p = u ^ (u >> 8); - } - - /* --- Now make the junk a whole lot harder to predict --- */ - - p = buff + crq_cmd; - md5_init(&md); md5_buffer(&md, p, CMDLEN_MAX); md5_final(&md, qk); - icrypt_init(&j, qk, BLOWFISH_KEYSIZE, 0); - icrypt_encrypt(&j, p, p, CMDLEN_MAX); - burn(j); burn(qk); burn(md); - - /* --- Copy the string into here --- */ - - strcpy((char *)buff + crq_cmd, rq->cmd); - } - - /* --- Checksum the finished data --- */ - - { - md5 md; - unsigned char mdbuf[MD5_HASHSIZE]; - - md5_init(&md); - md5_buffer(&md, buff + crq_cipher, crq_check - crq_cipher); - md5_final(&md, mdbuf); - memcpy(buff + crq_check, mdbuf, 4); - burn(md); burn(mdbuf); - } - - /* --- Encrypt the block --- * - * - * First, encrypt the session key using the master key. Since the session - * key is effectively random, this makes cracking the master key much - * harder. The rest of the block is then encrypted with the session key, - * using the IV left over from encrypting the session key. - */ - - { - icrypt_job j; - - T( traceblk(TRACE_CRYPTO, "crypto: plaintext request:", - buff, crq_size); ) - - T( traceblk(TRACE_CRYPTO, "crypto: master key:", k, BLOWFISH_KEYSIZE); ) - T( traceblk(TRACE_CRYPTO, "crypto: initial iv:", - buff + crq_iv, BLOWFISH_BLKSIZE); ) - T( traceblk(TRACE_CRYPTO, "crypto: session key:", - sk, BLOWFISH_KEYSIZE); ) - - icrypt_init(&j, k, BLOWFISH_KEYSIZE, buff + crq_iv); - - icrypt_encrypt(&j, buff + crq_session, - buff + crq_session, BLOWFISH_KEYSIZE); - T( traceblk(TRACE_CRYPTO, "crypto: encrypted session key:", - buff + crq_session, BLOWFISH_KEYSIZE); ) - - icrypt_reset(&j, sk, BLOWFISH_KEYSIZE, 0); - - T( traceblk(TRACE_CRYPTO, "crypto: partial iv:", - j.iv, BLOWFISH_BLKSIZE); ) - - icrypt_encrypt(&j, buff + crq_cipher, - buff + crq_cipher, crq_size - crq_cipher); - burn(j); - - T( traceblk(TRACE_CRYPTO, "crypto: ciphertext request:", - buff, crq_size); ) - } -} - -/* --- @crypt_unpackRequest@ --- * - * - * Arguments: @reqest *rq@ = pointer to destination request block - * @unsigned char *buff@ = pointer to source buffer - * @unsigned char *k@ = pointer to encryption key - * @unsigned char *sk@ = pointer to where to store session key - * @unsigned char *rpl@ = where to start building reply - * - * Returns: Nonzero if it was decrypted OK - * - * Use: Decrypts and unpacks a request buffer. - */ - -int crypt_unpackRequest(request *rq, unsigned char *buff, - unsigned char *k, unsigned char *sk, - unsigned char *rpl) -{ - { - /* --- Check the encryption format --- */ - - if (buff[crq_cryptType] != cryptType_blowfish) - return (0); - } - - { - /* --- First things first: decrypt the block --- */ - - icrypt_job j; - - T( traceblk(TRACE_CRYPTO, "crypto: ciphertext request:", - buff, crq_size); ) - - T( traceblk(TRACE_CRYPTO, "crypto: master key:", k, BLOWFISH_KEYSIZE); ) - T( traceblk(TRACE_CRYPTO, "crypto: initial iv:", - buff + crq_iv, BLOWFISH_BLKSIZE); ) - - icrypt_init(&j, k, BLOWFISH_KEYSIZE, buff + crq_iv); - T( traceblk(TRACE_CRYPTO, "crypto: job block:", &j, sizeof(j)); ) - - T( traceblk(TRACE_CRYPTO, "crypto: encrypted session key:", - buff + crq_session, BLOWFISH_KEYSIZE); ) - icrypt_decrypt(&j, buff + crq_session, - buff + crq_session, BLOWFISH_KEYSIZE); - memcpy(sk, buff + crq_session, BLOWFISH_KEYSIZE); - T( traceblk(TRACE_CRYPTO, "crypto: session key:", - sk, BLOWFISH_KEYSIZE); ) - - icrypt_reset(&j, sk, BLOWFISH_KEYSIZE, 0); - - T( traceblk(TRACE_CRYPTO, "crypto: partial iv:", - j.iv, BLOWFISH_BLKSIZE); ) - - icrypt_decrypt(&j, buff + crq_cipher, - buff + crq_cipher, crq_size - crq_cipher); - icrypt_saveIV(&j, rpl + crp_iv); - - T( traceblk(TRACE_CRYPTO, "crypto: plaintext request:", - buff, crq_size); ) - - memset(buff + crq_session, 0, BLOWFISH_KEYSIZE); /* Burn, baby, burn */ - burn(j); - } - - { - /* --- Check the validity of the data therein --- */ - - md5 md; - unsigned char mdbuf[MD5_HASHSIZE]; - - md5_init(&md); - md5_buffer(&md, buff + crq_cipher, crq_check - crq_cipher); - md5_final(&md, mdbuf); - if (memcmp(mdbuf, buff + crq_check, 4) != 0) { - syslog(LOG_INFO, "packet rejected: bad checksum"); - T( trace(TRACE_CRYPTO, "crypto: bad checksum on incoming request"); ) - return (0); - } - burn(md); burn(mdbuf); - } - - { - /* --- Extract fields from the block --- */ - - rq->from = load32(buff + crq_from); - rq->to = load32(buff + crq_to); - memcpy(rq->cmd, buff + crq_cmd, CMDLEN_MAX); - } - - { - /* --- Fill in bits of the reply block --- */ - - long t = (long)time(0); - long u = (long)load32(buff + crq_time); - - if (t - u > crypt__timeError || u - t > crypt__timeError) { - syslog(LOG_INFO, "packet rejected: bad time"); - T( trace(TRACE_CRYPTO, "crypto: bad time on incoming request"); ) - return (0); - } - memcpy(rpl + crp_time, buff + crq_time, 8); - } - - /* --- Done --- */ - - T( trace(TRACE_CRYPTO, "crypto: valid request received"); ) - return (1); -} - -/* --- @crypt_packReply@ --- * - * - * Arguments: @char *buff@ = pointer to reply block - * @unsigned char *sk@ = pointer to session key - * @int answer@ = yes or no - * - * Returns: --- - * - * Use: Packs and encrypts a reply block. - */ - -void crypt_packReply(unsigned char *buff, unsigned char *sk, int answer) -{ - { - /* --- Store the answer --- */ - - buff[crp_answer] = (answer != 0); - } - - { - /* --- Build the checksum --- */ - - md5 md; - unsigned char mdbuf[MD5_HASHSIZE]; - - md5_init(&md); - md5_buffer(&md, buff + crp_cipher, crp_check - crp_cipher); - md5_final(&md, mdbuf); - memcpy(buff + crp_check, mdbuf, 4); - burn(md); burn(mdbuf); - } - - { - /* --- Encrypt the buffer --- */ - - icrypt_job j; - - T( traceblk(TRACE_CRYPTO, "crypto: plaintext reply:", buff, crp_size); ) - - icrypt_init(&j, sk, BLOWFISH_KEYSIZE, buff + crp_iv); - icrypt_encrypt(&j, buff + crp_cipher, - buff + crp_cipher, crp_size - crp_cipher); - burn(j); - - T( traceblk(TRACE_CRYPTO, "crypto: ciphertext reply:", buff, crp_size); ) - } -} - -/* --- @crypt_unpackReply@ --- * - * - * Arguments: @unsigned char *buff@ = pointer to reply buffer - * @unsigned char *sk@ = pointer to session key - * @time_t t@ = time at which request was sent - * @pid_t pid@ = my process ID - * - * Returns: >0 if request granted, zero if denied, <0 if reply rejected - * - * Use: Unpacks a reply block, and informs the caller of the outcome. - */ - -int crypt_unpackReply(unsigned char *buff, unsigned char *sk, - time_t t, pid_t pid) -{ - { - /* --- Decrypt my reply block --- */ - - icrypt_job j; - - T( traceblk(TRACE_CRYPTO, "crypto: ciphertext reply:", buff, crp_size); ) - - icrypt_init(&j, sk, BLOWFISH_KEYSIZE, buff + crp_iv); - icrypt_decrypt(&j, buff + crp_cipher, - buff + crp_cipher, crp_size - crp_cipher); - burn(j); - - T( traceblk(TRACE_CRYPTO, "crypto: plaintext reply:", buff, crp_size); ) - } - - { - /* --- Check validity --- */ - - md5 md; - unsigned char mdbuf[MD5_HASHSIZE]; - char b[8]; - - /* --- Check the checksum --- */ - - md5_init(&md); - md5_buffer(&md, buff + crp_cipher, crp_check - crp_cipher); - md5_final(&md, mdbuf); - if (memcmp(buff + crp_check, mdbuf, 4) != 0) { - syslog(LOG_INFO, "reply rejected: bad checksum"); - T( trace(TRACE_CRYPTO, "crypto: bad checksum on reply"); ) - return (-1); - } - - /* --- Check the identifier --- */ - - store32(b + 0, t); store32(b + 4, pid); - if (memcmp(b, buff + crp_time, sizeof(b)) != 0) { - syslog(LOG_INFO, "reply rejected: bad identification marker"); - T( trace(TRACE_CRYPTO, "crypto: bad id on reply"); ) - return (-1); - } - } - - /* --- Return the value --- */ - - T( trace(TRACE_CRYPTO, "crypto: valid reply received"); ) - return (buff[crp_answer]); -} - -/*----- Test rig ----------------------------------------------------------*/ - -#ifdef TEST_RIG - -int main(int argc, char *argv[]) -{ - unsigned char buff[8]; - unsigned char sk[BLOWFISH_KEYSIZE], k[BLOWFISH_KEYSIZE]; - FILE *fp; - - ego(argv[0]); - traceon(stdout, TRACE_CRYPTO); - if (argc < 3) - die("bad args"); - fp = fopen(argv[1], "r"); - if (!fp) - die("fopen: %s", strerror(errno)); - tx_getBits(k, 128, fp); - fclose(fp); - crypt__sessionKey(argv[2], k, sk, buff); - return (0); -} - -#endif - -/*----- That's all, folks -------------------------------------------------*/ diff --git a/src/crypt.h b/src/crypt.h deleted file mode 100644 index a0d81fd..0000000 --- a/src/crypt.h +++ /dev/null @@ -1,191 +0,0 @@ -/* -*-c-*- - * - * $Id: crypt.h,v 1.4 1998/01/12 16:45:57 mdw Exp $ - * - * Cryptographic transfer of `become' requests - * - * (c) 1998 EBI - */ - -/*----- Licensing notice --------------------------------------------------* - * - * This file is part of `become' - * - * `Become' is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * `Become' is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with `become'; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/*----- Revision history --------------------------------------------------* - * - * $Log: crypt.h,v $ - * Revision 1.4 1998/01/12 16:45:57 mdw - * Fix copyright date. - * - * Revision 1.3 1997/09/26 09:14:58 mdw - * Merged blowfish branch into trunk. - * - * Revision 1.2.2.1 1997/09/26 09:08:04 mdw - * Use the Blowfish encryption algorithm instead of IDEA. This is partly - * because I prefer Blowfish (without any particularly strong evidence) but - * mainly because IDEA is patented and Blowfish isn't. - * - * Revision 1.2 1997/08/04 10:24:21 mdw - * Sources placed under CVS control. - * - * Revision 1.1 1997/07/21 13:47:51 mdw - * Initial revision - * - */ - -#ifndef CRYPT_H -#define CRYPT_H - -#ifdef __cplusplus - extern "C" { -#endif - -/*----- Required headers --------------------------------------------------*/ - -#include - -#ifndef BECOME_H -# include "become.h" -#endif - -#ifndef CONFIG_H -# include "config.h" -#endif - -/*----- Type definitions and data structures ------------------------------*/ - -/* --- Encryption formats --- */ - -enum { - cryptType_blowfish, /* Symmetric Blowfish encryption */ - cryptType_rsa /* Public key RSA (later project) */ -}; - -/* --- Blowfish has a variable key size --- * - * - * Fix a key size here. - */ - -#define BLOWFISH_KEYSIZE (16u) - -/* --- Encrypted buffer format --- * - * - * C structures are no good here. Time for some explicit offsets. - */ - -enum { - crq_cryptType = 0, /* Encryption type (1 byte) */ - crq_iv = crq_cryptType + 1, /* Plaintext IV (8 bytes) */ - crq_session = crq_iv + 8, /* Session key (16 bytes) */ - crq_cipher = crq_session + 16, /* Where to start encrypting */ - crq_time = crq_cipher, /* Time stamp (4 bytes) */ - crq_pid = crq_time + 4, /* Process ID (4 bytes) */ - crq_from = crq_pid + 4, /* From user id (4 bytes) */ - crq_to = crq_from + 4, /* To user id (4 bytes) */ - crq_cmd = crq_to + 4, /* Command string (lots of bytes) */ - crq_check = crq_cmd + CMDLEN_MAX, /* Checksum for request (4 bytes) */ - crq_size = crq_check + 4 /* Size of encrypted request */ -}; - -/* --- Encrypted result format --- */ - -enum { - crp_iv = 0, /* Plaintext IV (8 bytes) */ - crp_cipher = crp_iv + 8, /* Where to start encrypting */ - crp_time = crp_cipher, /* Time of request (4 bytes) */ - crp_pid = crp_time + 4, /* Process ID of client (4 bytes) */ - crp_answer = crp_pid + 4, /* Answer (1 or 0) (1 byte) */ - crp_check = crp_answer + 1, /* Checksum for reply (4 bytes) */ - crp_size = crp_check + 4 /* Size of encrypted reply */ -}; - -/*----- Functions provided ------------------------------------------------*/ - -/* --- @crypt_packRequest@ --- * - * - * Arguments: @request *rq@ = pointer to request block - * @unsigned char *buff@ = pointer to a buffer - * @time_t t@ = the current time - * @pid_t pid@ = my process ID - * @unsigned char *k@ = pointer to 128-bit key - * @unsigned char *sk@ = where to put the session key - * - * Returns: The number of bytes written. - * - * Use: Packs a request block into a buffer. The buffer should have - * space for at least @crq_size@ bytes. The buffer comes back - * encrypted and ready to send. - */ - -extern void crypt_packRequest(request */*rq*/, unsigned char */*buff*/, - time_t /*t*/, pid_t /*pid*/, - unsigned char */*k*/, unsigned char */*sk*/); - -/* --- @crypt_unpackRequest@ --- * - * - * Arguments: @reqest *rq@ = pointer to destination request block - * @unsigned char *buff@ = pointer to source buffer - * @unsigned char *k@ = pointer to encryption key - * @unsigned char *sk@ = pointer to where to store session key - * @unsigned char *rpl@ = where to start building reply - * - * Returns: --- - * - * Use: Decrypts and unpacks a request buffer. - */ - -extern int crypt_unpackRequest(request */*rq*/, unsigned char */*buff*/, - unsigned char */*k*/, unsigned char */*sk*/, - unsigned char */*rpl*/); - -/* --- @crypt_packReply@ --- * - * - * Arguments: @unsigned char *buff@ = pointer to reply block - * @unsigned char *sk@ = pointer to session key - * @int answer@ = yes or no - * - * Returns: --- - * - * Use: Packs and encrypts a reply block. - */ - -extern void crypt_packReply(unsigned char */*buff*/, unsigned char */*sk*/, - int /*answer*/); - -/* --- @crypt_unpackReply@ --- * - * - * Arguments: @unsigned char *buff@ = pointer to reply buffer - * @unsigned char *sk@ = pointer to session key - * @time_t t@ = time at which request was sent - * @pid_t pid@ = my process ID - * - * Returns: >0 if request granted, zero if denied, <0 if reply rejected - * - * Use: Unpacks a reply block, and informs the caller of the outcome. - */ - -extern int crypt_unpackReply(unsigned char */*buff*/, unsigned char */*sk*/, - time_t /*t*/, pid_t /*pid*/); - -/*----- That's all, folks -------------------------------------------------*/ - -#ifdef __cplusplus - } -#endif - -#endif diff --git a/src/daemon.c b/src/daemon.c index 5b0d832..8d69510 100644 --- a/src/daemon.c +++ b/src/daemon.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: daemon.c,v 1.11 1999/05/04 16:17:12 mdw Exp $ + * $Id: daemon.c,v 1.12 2003/10/12 00:14:55 mdw Exp $ * * Running a `become' daemon * @@ -29,6 +29,10 @@ /*----- Revision history --------------------------------------------------* * * $Log: daemon.c,v $ + * Revision 1.12 2003/10/12 00:14:55 mdw + * Major overhaul. Now uses DSA signatures rather than the bogus symmetric + * encrypt-and-hope thing. Integrated with mLib and Catacomb. + * * Revision 1.11 1999/05/04 16:17:12 mdw * Change to header file name for parser. See log for `parse.h' for * details. @@ -75,7 +79,6 @@ #include #include -#include #include #include #include @@ -94,35 +97,53 @@ #include #include +/* --- mLib headers --- */ + +#include +#include +#include +#include +#include +#include +#include + +/* --- Catacomb headers --- */ + +#include +#include +#include +#include +#include +#include +#include +#include + /* --- Local headers --- */ #include "become.h" -#include "blowfish.h" #include "config.h" -#include "crypt.h" #include "daemon.h" #include "lexer.h" #include "name.h" #include "netg.h" #include "parse.h" #include "rule.h" -#include "tx.h" #include "userdb.h" -#include "utils.h" /*----- Arbitrary constants -----------------------------------------------*/ -#define daemon__awakeEvery (30 * 60) /* Awaken this often to rescan */ +#define daemon__awakeEvery (5 * 60) /* Awaken this often to rescan */ /*----- Static variables --------------------------------------------------*/ -static int daemon__running = 0; /* Am I running as a daemon? */ static int daemon__port = -1; /* No particular port yet */ -static volatile sig_atomic_t daemon__rescan = 0; /* Rescan as soon as poss */ -#define daemon__signum daemon__rescan /* Alias for readbility */ static int daemon__readKey = 0; /* Have I read a key? */ -static unsigned char daemon__key[BLOWFISH_KEYSIZE]; /* Encryption key */ -static jmp_buf daemon__dieBuf; /* Jump here to kill the daemon */ +static fwatch daemon__watch; +static sel_timer daemon__timer; /* Timer for reading */ +static sel_state daemon__sel; /* Select context */ +static sel_file daemon__listen; /* Listening socket selector */ +static const char *daemon__config; /* Configuration file for daemon */ +static dsa_priv daemon__key; /* The key data */ /*----- Main code ---------------------------------------------------------*/ @@ -140,30 +161,60 @@ void daemon_usePort(int port) daemon__port = port; } +/* --- @daemon__moan@ --- * + * + * Arguments: @const char *f@ = offending file name + * @int line@ = offending line of the file + * @const char *msg@ = message + * @void *p@ = ignored + * + * Returns: --- + * + * Use: Reports an error message about a key file. + */ + +static void daemon__moan(const char *f, int line, const char *msg, void *p) +{ + syslog(LOG_ERR, "key file error: %s: %d: %s", f, line, msg); +} + /* --- @daemon_readKey@ --- * * - * Arguments: @const char *kf@ = name of file containing key + * Arguments: @const char *kf@ = pointer to key file name to use * * Returns: --- * - * Use: Instructs the daemon to read the named key file. + * Use: Loads the private key from the key file. */ void daemon_readKey(const char *kf) { - FILE *fp; + key_packstruct kps[DSA_PRIVFETCHSZ]; + key_packdef *kp; + key_file f; + key *k; + int err; - if (!daemon__running) + if (daemon__readKey) return; - - if ((fp = fopen(kf, "r")) == 0) { - syslog(LOG_WARNING, "couldn't read key file: %e"); + if (key_open(&f, kf, KOPEN_READ, daemon__moan, 0)) return; + kp = key_fetchinit(dsa_privfetch, kps, &daemon__key); + if ((k = key_bytype(&f, "become-dsa")) == 0) + err = KERR_NOTFOUND; + else + err = key_fetch(kp, k); + if (err) + syslog(LOG_ERR, "couldn't load key: %s", key_strerror(err)); + else { + mp_copy(daemon__key.dp.p); + mp_copy(daemon__key.dp.q); + mp_copy(daemon__key.dp.g); + mp_copy(daemon__key.x); + mp_copy(daemon__key.y); } - tx_getBits(daemon__key, 128, fp); - fclose(fp); - daemon__readKey = 1; - return; + key_fetchdone(kp); + key_close(&f); } /* --- @daemon__readConfig@ --- * @@ -187,116 +238,205 @@ static int daemon__readConfig(const char *cf) fclose(fp); if (!daemon__readKey) daemon_readKey(file_KEY); - daemon__rescan = 0; T( trace(TRACE_DAEMON, "daemon: read config file"); ) return (0); } -/* --- @daemon__restart@ --- * - * - * Arguments: @int sig@ = the signal number - * - * Returns: --- - * - * Use: Handles signals. Causes the configuration file to be reread. - */ - -static void daemon__restart(int sig) -{ - daemon__rescan = 1; - signal(sig, daemon__restart); -} - -/* --- @daemon__die@ --- * - * - * Arguments: @int sig@ = the signal number - * - * Returns: via @longjmp@ - * - * Use: Handles other signals. Causes the daemon to die. - */ - -static void daemon__die(int sig) -{ - daemon__signum = sig; - longjmp(daemon__dieBuf, 1); -} - /* --- @daemon__read@ --- * * * Arguments: @int fd@ = socket handle + * @unsigned mode@ = ignored + * @void *p@ = ignored * * Returns: --- * * Use: Examines a buffer, and returns a response. */ -void daemon__read(int fd) +void daemon__read(int fd, unsigned mode, void *p) { unsigned char buff[65536]; /* Buffer for incoming packets */ - unsigned char rpl[crp_size]; /* Buffer for outgoing replies */ struct sockaddr_in sin; /* Address of packet sender */ char sender[64]; /* Sender's hostname (resolved) */ - unsigned char sk[BLOWFISH_KEYSIZE]; /* Session key for reply */ + octet h[SHA_HASHSZ]; /* Hash of the transmission buffer */ + sha_ctx hc; /* Hashing context */ request rq; /* Request buffer for verification */ + ssize_t sz; /* Length of incoming message */ + socklen_t slen; /* Length of incoming address */ + uint32 u; /* Scratch integer */ + uint16 ul; /* And another */ + struct hostent *he; /* Resolve structure */ + mp *m, *k, *r, *s; /* Integers for signing */ + int ans; /* Answer from the check */ + buf b; /* Buffer for parsing request */ - /* --- Read the message --- */ + /* --- Kick some randomness in the pot --- */ - { - int slen = sizeof(sin); + noise_timer(RAND_GLOBAL); - if (recvfrom(fd, (char *)buff, sizeof(buff), 0, - (struct sockaddr *)&sin, &slen) < 0) { - T( trace(TRACE_DAEMON, "daemon: error reading packet: %s", - strerror(errno)); ) - syslog(LOG_INFO, "duff packet received: %e"); - return; - } + /* --- Read the message --- */ + + slen = sizeof(sin); + if ((sz = recvfrom(fd, (char *)buff, sizeof(buff), 0, + (struct sockaddr *)&sin, &slen)) < 0) { + T( trace(TRACE_DAEMON, "daemon: error reading packet: %s", + strerror(errno)); ) + syslog(LOG_INFO, "duff packet received: %e"); + return; } /* --- Resolve the host name --- */ - { - struct hostent *he = gethostbyaddr((char *)&sin.sin_addr, - sizeof(sin.sin_addr), - AF_INET); - sender[0] = 0; - strncat(sender, - he ? he->h_name : inet_ntoa(sin.sin_addr), - sizeof(sender)); - syslog(LOG_DEBUG, "packet received from %s", sender); - T( trace(TRACE_DAEMON, "daemon: received request from %s", sender); ) - } + he = gethostbyaddr((char *)&sin.sin_addr, sizeof(sin.sin_addr), AF_INET); + sender[0] = 0; + strncat(sender, he ? he->h_name : inet_ntoa(sin.sin_addr), + sizeof(sender) - 1); + syslog(LOG_DEBUG, "packet received from %s", sender); + T( trace(TRACE_DAEMON, "daemon: received request from %s", sender); ) /* --- Unpack the block --- */ - if (crypt_unpackRequest(&rq, buff, daemon__key, sk, rpl) == 0) { - burn(buff); - T( trace(TRACE_DAEMON, "daemon: received corrupt or invalid request"); ) - syslog(LOG_INFO, "packet from %s rejected", sender); - return; - } - burn(buff); - - /* --- Fill in the sender's address in the request block --- */ - rq.host = sin.sin_addr; + buf_init(&b, buff, sz); + if (buf_ensure(&b, SHA_HASHSZ)) goto fail; BSTEP(&b, SHA_HASHSZ); + if (buf_getu32(&b, &u)) goto fail; rq.from = u; + if (buf_getu32(&b, &u)) goto fail; rq.to = u; + if (buf_getu16(&b, &ul) || buf_ensure(&b, ul) || ul >= sizeof(rq.cmd)) + goto fail; + memcpy(rq.cmd, BCUR(&b), ul); + rq.cmd[ul] = 0; + BSTEP(&b, ul); + if (BLEFT(&b)) goto fail; + + /* --- Hash the request block --- */ + + sha_init(&hc); + sha_hash(&hc, buff, sz); + sha_done(&hc, h); /* --- Build a reply block --- */ - { - int answer = rule_check(&rq); - syslog(LOG_INFO, "request from %s for %i to become %i to run %s %s", - sender, rq.from, rq.to, rq.cmd, answer ? "granted" : "denied"); - crypt_packReply(rpl, sk, answer); - burn(sk); - } + ans = rule_check(&rq); + syslog(LOG_INFO, "request from %s for %i to become %i to run %s %s", + sender, rq.from, rq.to, rq.cmd, ans ? "granted" : "denied"); + buf_init(&b, buff, sizeof(buff)); + if (buf_put(&b, h, sizeof(h)) || buf_putbyte(&b, ans)) + goto fail; + + /* --- Sign the reply block --- */ + + sha_init(&hc); + sha_hash(&hc, BBASE(&b), BLEN(&b)); + sha_done(&hc, h); + m = mp_loadb(MP_NEW, h, sizeof(h)); + rand_get(RAND_GLOBAL, h, sizeof(h)); + k = mp_loadb(MP_NEWSEC, h, sizeof(h)); + r = s = MP_NEW; + dsa_mksig(&daemon__key.dp, daemon__key.x, m, k, &r, &s); + buf_putmp(&b, r); + buf_putmp(&b, s); + mp_drop(m); + mp_drop(k); + mp_drop(r); + mp_drop(s); + if (BBAD(&b)) + goto fail; /* --- Send the reply off --- */ - sendto(fd, (char *)rpl, crp_size, 0, (struct sockaddr *)&sin, sizeof(sin)); + sendto(fd, BBASE(&b), BLEN(&b), 0, (struct sockaddr *)&sin, sizeof(sin)); T( trace(TRACE_DAEMON, "daemon: reply sent"); ) - burn(rpl); + return; + +fail: + syslog(LOG_ERR, "couldn't respond to query"); + T( trace(TRACE_DAEMON, "daemon: failed to answer query"); ) +} + +/* --- @daemon__die@ --- * + * + * Arguments: @int n@ = signal number + * @void *p@ = ignored + * + * Returns: Doesn't. + * + * Use: Exits the daemon. + */ + +static void daemon__die(int n, void *p) +{ + T( trace(TRACE_DAEMON, "daemon: killed by signal %i", n); ) + syslog(LOG_NOTICE, "killed by signal type %i", n); + remove(file_PID); + exit(0); +} + +/* --- @daemon__setTimer@ --- * + * + * Arguments: --- + * + * Returns: --- + * + * Use: Sets the interval timer up. + */ + +static void daemon__wakeUp(struct timeval *tv, void *p); + +static void daemon__setTimer(void) +{ + struct timeval tv; + + gettimeofday(&tv, 0); + tv.tv_sec += daemon__awakeEvery; + sel_addtimer(&daemon__sel, &daemon__timer, &tv, daemon__wakeUp, 0); +} + +/* --- @daemon__rescan@ --- * + * + * Arguments: @int n@ = signal number + * @void *p@ = ignored + * + * Returns: --- + * + * Use: Forces a rescan of the daemon's configuration. + */ + +static void daemon__rescan(int n, void *p) +{ + syslog(LOG_INFO, "rescanning configuration file"); + name_end(); + rule_end(); + netg_end(); + userdb_end(); + dsa_privfree(&daemon__key); + userdb_init(); + userdb_local(); + userdb_yp(); + netg_init(); + rule_init(); + name_init(); + if (daemon__readConfig(daemon__config)) + syslog(LOG_ERR, "error reading configuration file"); + sel_rmtimer(&daemon__timer); + daemon__setTimer(); + fwatch_update(&daemon__watch, daemon__config); +} + +/* --- @daemon__wakeUp@ --- * + * + * Arguments: @struct timeval *tv@ = ignored + * @void *p@ = ignored + * + * Returns: --- + * + * Use: Wakes up periodically to check the configuration file. + */ + +static void daemon__wakeUp(struct timeval *tv, void *p) +{ + rand_seed(RAND_GLOBAL, 160); + if (fwatch_update(&daemon__watch, daemon__config)) + daemon__rescan(0, 0); } /* --- @daemon_init@ --- * @@ -312,6 +452,19 @@ void daemon__read(int fd) void daemon_init(const char *cf, int port) { int s; + int i; + + static struct sigvec { + int sig; + void (*proc)(int n, void *p); + sig s; + } sigs[] = { + { SIGHUP, daemon__rescan }, + { SIGINT, daemon__die }, + { SIGTERM, daemon__die }, + { SIGQUIT, daemon__die }, + { 0, 0 } + }; /* --- Remove my root privileges --- * * @@ -321,10 +474,17 @@ void daemon_init(const char *cf, int port) setuid(getuid()); + /* --- Initialize the random number generator --- */ + + rand_noisesrc(RAND_GLOBAL, &noise_source); + rand_seed(RAND_GLOBAL, 160); + /* --- Initialise bits of the program --- */ - daemon__running = 1; + daemon__config = cf; daemon__port = port; + sel_init(&daemon__sel); + sig_init(&daemon__sel); userdb_init(); userdb_local(); userdb_yp(); @@ -334,8 +494,9 @@ void daemon_init(const char *cf, int port) openlog(quis(), 0, LOG_DAEMON); syslog(LOG_NOTICE, "starting up"); - if (daemon__readConfig(cf)) - die("couldn't read configuration file"); + if (daemon__readConfig(daemon__config)) + die(1, "couldn't read configuration file"); + fwatch_init(&daemon__watch, daemon__config); /* --- Decide on a port to use --- * * @@ -346,7 +507,7 @@ void daemon_init(const char *cf, int port) if (daemon__port == 0) { struct servent *se = getservbyname(quis(), "udp"); if (!se) - die("no idea which port to listen to"); + die(1, "no idea which port to listen to"); daemon__port = se->s_port; } @@ -356,12 +517,12 @@ void daemon_init(const char *cf, int port) struct sockaddr_in sin; if ((s = socket(PF_INET, SOCK_DGRAM, 0)) == -1) - die("couldn't create socket: %s", strerror(errno)); + die(1, "couldn't create socket: %s", strerror(errno)); sin.sin_family = AF_INET; sin.sin_port = daemon__port; sin.sin_addr.s_addr = htonl(INADDR_ANY); if (bind(s, (struct sockaddr *)&sin, sizeof(sin))) { - die("couldn't bind socket to port %i: %s", + die(1, "couldn't bind socket to port %i: %s", ntohs(daemon__port), strerror(errno)); } } @@ -376,7 +537,7 @@ void daemon_init(const char *cf, int port) /* --- Make a background process --- */ if (pid == -1) - die("couldn't fork daemon: %s", strerror(errno)); + die(1, "couldn't fork daemon: %s", strerror(errno)); else if (pid != 0) return; @@ -394,87 +555,29 @@ void daemon_init(const char *cf, int port) } #endif - /* --- Program in daemon death mode --- */ - - if (setjmp(daemon__dieBuf)) { -#ifdef TRACING - if (daemon__signum == SIGQUIT && tracing() & TRACE_RULE) { - T( rule_dump(); ) - signal(SIGQUIT, daemon__die); - } else -#endif - { - T( trace(TRACE_DAEMON, "daemon: killed by signal %i", - daemon__signum); ) - syslog(LOG_NOTICE, "killed by signal type %i", daemon__signum); - remove(file_PID); - exit(0); - } - } else { - - /* --- Set signal handlers --- */ - - signal(SIGHUP, daemon__restart); - signal(SIGQUIT, daemon__die); - signal(SIGINT, daemon__die); - signal(SIGTERM, daemon__die); - signal(SIGSEGV, daemon__die); - signal(SIGFPE, daemon__die); - signal(SIGBUS, daemon__die); - } - - /* --- Now wait for something exciting to happen --- * - * - * Actually, every so often (5 minutes, perhaps) I need to wake up and - * rescan the users to see whether they've changed. Time to play with - * @select@. - */ - - { - time_t when; - - /* --- Find when I am, and thus when I need to be awoken again --- */ - - when = time(0) + daemon__awakeEvery; - - for (;;) { - fd_set fds; - int i; - - /* --- Set up the file descriptor tables --- */ + /* --- Set signal handlers --- */ - FD_ZERO(&fds); - FD_SET(s, &fds); + for (i = 0; sigs[i].proc; i++) + sig_add(&sigs[i].s, sigs[i].sig, sigs[i].proc, 0); - /* --- Now wait for something interesting --- */ + /* --- Set the timer for rescanning the file --- */ - T( trace(TRACE_DAEMON, "daemon: waiting for requests"); ) - i = select(FD_SETSIZE, &fds, 0, 0, 0); + daemon__setTimer(); - /* --- Now, see if I need to rescan the config --- */ + /* --- Watch for input --- */ - if (daemon__rescan || time(0) - when > 0) { - daemon__rescan = 0; - syslog(LOG_INFO, "rescanning configuration file"); - name_end(); - rule_end(); - netg_end(); - userdb_end(); - userdb_init(); - userdb_local(); - userdb_yp(); - netg_init(); - rule_init(); - name_init(); - if (daemon__readConfig(cf)) - syslog(LOG_ERR, "error reading configuration file"); - when = time(0) + daemon__awakeEvery; - } + sel_initfile(&daemon__sel, &daemon__listen, s, SEL_READ, + daemon__read, 0); + sel_addfile(&daemon__listen); - /* --- Read the data from the request --- */ + /* --- Now wait for something exciting to happen --- */ - if (i > 0) - daemon__read(s); + for (;;) { + if (sel_select(&daemon__sel)) { + if (errno == EINTR || errno == EAGAIN) + continue; + syslog(LOG_ERR, "error from select: %s", strerror(errno)); + exit(1); } } } diff --git a/src/icrypt.c b/src/icrypt.c deleted file mode 100644 index b2dc21f..0000000 --- a/src/icrypt.c +++ /dev/null @@ -1,337 +0,0 @@ -/* -*-c-*- - * - * $Id: icrypt.c,v 1.4 1998/01/12 16:46:02 mdw Exp $ - * - * Higher level encryption functions - * - * (c) 1998 Mark Wooding - */ - -/*----- Licensing notice --------------------------------------------------* - * - * This file is part of `become' - * - * `Become' is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * `Become' is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with `become'; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/*----- Revision history --------------------------------------------------* - * - * $Log: icrypt.c,v $ - * Revision 1.4 1998/01/12 16:46:02 mdw - * Fix copyright date. - * - * Revision 1.3 1997/09/26 09:14:58 mdw - * Merged blowfish branch into trunk. - * - * Revision 1.2.2.1 1997/09/26 09:08:07 mdw - * Use the Blowfish encryption algorithm instead of IDEA. This is partly - * because I prefer Blowfish (without any particularly strong evidence) but - * mainly because IDEA is patented and Blowfish isn't. - * - * Revision 1.2 1997/08/04 10:24:22 mdw - * Sources placed under CVS control. - * - * Revision 1.1 1997/07/21 13:47:49 mdw - * Initial revision - * - */ - -/*----- Header files ------------------------------------------------------*/ - -/* --- ANSI headers --- */ - -#include -#include -#include - -/* --- Local headers --- */ - -#include "blowfish.h" -#include "config.h" -#include "icrypt.h" - -/*----- Main code ---------------------------------------------------------*/ - -/* --- @icrypt_init@ --- * - * - * Arguments: @icrypt_job *j@ = pointer to job context block - * @unsigned char *k@ = pointer to key data - * @size_t sz@ = size of the key data - * @const unsigned char *iv@ = pointer to IV - * - * Returns: --- - * - * Use: Primes the context block ready for encryption. - */ - -void icrypt_init(icrypt_job *j, unsigned char *k, - size_t sz, const unsigned char *iv) -{ - blowfish_setKey(&j->k, k, sz); - if (iv) - memcpy(j->iv, iv, BLOWFISH_BLKSIZE); - else - memset(j->iv, 0, BLOWFISH_BLKSIZE); - j->i = 8; -} - -/* --- @icrypt_encrypt@ --- * - * - * Arguments: @icrypt_job *j@ = job handle - * @const void *src@ = pointer to source buffer - * @void *dest@ = pointer to destination buffer - * @size_t sz@ = size of buffers to handle - * - * Returns: --- - * - * Use: Encrypts data from the source to the destination, using the - * key attached to the job handle. - */ - -void icrypt_encrypt(icrypt_job *j, const void *src, void *dest, size_t sz) -{ - const unsigned char *s = src; - unsigned char *d = dest; - int i; - - /* --- First, use up bytes in the buffer --- */ - - while (j->i < BLOWFISH_BLKSIZE && sz > 0) { - *d++ = j->iv[j->i++] ^= *s++; - sz--; - } - if (!sz) return; - - /* --- Now encrypt larger chunks at a time --- */ - - while (sz >= BLOWFISH_BLKSIZE) { - - /* --- Freshen the IV --- */ - - blowfish_encrypt(&j->k, j->iv, j->iv); - - /* --- Now encrypt some more bytes --- */ - - for (i = 0; i < BLOWFISH_BLKSIZE; i++) { - *d++ = j->iv[i] ^= *s++; - } - sz -= BLOWFISH_BLKSIZE; - } - if (!sz) return; - - /* --- Do the tail-end bits --- */ - - blowfish_encrypt(&j->k, j->iv, j->iv); - j->i = 0; - while (sz) { - *d++ = j->iv[j->i++] ^= *s++; - sz--; - } -} - -/* --- @icrypt_decrypt@ --- * - * - * Arguments: @icrypt_job *j@ = job handle - * @const void *src@ = pointer to source buffer - * @void *dest@ = pointer to destination buffer - * @size_t sz@ = size of buffers to handle - * - * Returns: --- - * - * Use: Decrypts data from the source to the destination, using - * the key attached to the job handle. - */ - -void icrypt_decrypt(icrypt_job *j, const void *src, void *dest, size_t sz) -{ - unsigned const char *s = src; - unsigned char *d = dest; - int i; - unsigned char c; - - /* --- First, use up bytes in the buffer --- */ - - while (j->i < BLOWFISH_BLKSIZE && sz > 0) { - c = *s++; - *d++ = j->iv[j->i] ^ c; - j->iv[j->i++] = c; - sz--; - } - if (!sz) return; - - /* --- Now encrypt larger chunks at a time --- */ - - while (sz >= BLOWFISH_BLKSIZE) { - - /* --- Freshen the IV --- */ - - blowfish_encrypt(&j->k, j->iv, j->iv); - - /* --- Now encrypt some more bytes --- */ - - for (i = 0; i < BLOWFISH_BLKSIZE; i++) { - c = *s++; - *d++ = j->iv[i] ^ c; - j->iv[i] = c; - } - sz -= BLOWFISH_BLKSIZE; - } - if (!sz) return; - - /* --- Do the tail-end bits --- */ - - blowfish_encrypt(&j->k, j->iv, j->iv); - j->i = 0; - while (sz) { - c = *s++; - *d++ = j->iv[j->i] ^ c; - j->iv[j->i++] = c; - sz--; - } -} - -/* --- @icrypt_reset@ --- * - * - * Arguments: @icrypt_job *j@ = pointer to job context block - * @unsigned char *k@ = pointer to key data, or zero for - * no change - * @size_t sz@ = size of the key in bytes - * @const unsigned char *iv@ = pointer to IV, or zero - * - * Returns: --- - * - * Use: Alters the context block. This can be used after recovery - * of a session key, for example. - */ - -void icrypt_reset(icrypt_job *j, unsigned char *k, - size_t sz, const unsigned char *iv) -{ - if (k) - blowfish_setKey(&j->k, k, sz); - if (iv) - memcpy(j->iv, iv, BLOWFISH_BLKSIZE); - else { - unsigned char b[BLOWFISH_BLKSIZE]; - int n = j->i, o = BLOWFISH_BLKSIZE - j->i; - - memcpy(b, j->iv, sizeof(b)); - memcpy(j->iv, b + n, o); - memcpy(j->iv + o, b, n); - } - j->i = 8; -} - -/* --- @icrypt_saveIV@ --- * - * - * Arguments: @icrypt_job *j@ = pointer to job context block - * @unsigned char *iv@ = where to store the IV - * - * Returns: --- - * - * Use: Writes out the job's IV after munging it a little. - */ - -void icrypt_saveIV(icrypt_job *j, unsigned char *iv) -{ - int n = j->i, o = BLOWFISH_BLKSIZE - j->i; - - memcpy(j->iv, iv + n, o); - memcpy(j->iv + o, iv, n); - blowfish_encrypt(&j->k, iv, iv); -} - -/*----- Test rig ----------------------------------------------------------*/ - -#ifdef TEST_RIG - -#include -#include -#include -#include "crypt.h" -#include "mdwopt.h" -#include "md5.h" -#include "utils.h" - -void icrypt(icrypt_job *j, - void (*proc)(icrypt_job *j, - const void *src, - void *dest, - size_t sz), - FILE *fp) -{ - char buff[71]; - size_t r; - - for (;;) { - r = fread(buff, 1, sizeof(buff), fp); - if (!r) break; - proc(j, buff, buff, r); - fwrite(buff, 1, r, stdout); - } -} - -int main(int argc, char *argv[]) -{ - icrypt_job j; - md5 md; - void (*proc)(icrypt_job *j, - const void *src, - void *dest, - size_t sz) = icrypt_encrypt; - - ego(argv[0]); - - for (;;) { - int i = getopt(argc, argv, "d"); - if (i < 0) - break; - if (i == 'd') - proc = icrypt_decrypt; - } - - { - char *pass = getpass("Password: "); - unsigned char k[BLOWFISH_KEYSIZE]; - md5_init(&md); - md5_buffer(&md, pass, strlen(pass)); - memset(pass, 0, strlen(pass)); - md5_final(&md, k); - - icrypt_init(&j, k, BLOWFISH_KEYSIZE, 0); - } - - if (optind >= argc) - icrypt(&j, proc, stdin); - - while (optind < argc) { - char *p = argv[optind++]; - if (strcmp(p, "-") == 0) - icrypt(&j, proc, stdin); - else { - FILE *fp = fopen(p, "rb"); - if (!fp) - die("couldn't open `%s': %s", p, strerror(errno)); - icrypt(&j, proc, fp); - fclose(fp); - } - } - - return (0); -} - -#endif - -/*----- That's all, folks -------------------------------------------------*/ diff --git a/src/icrypt.h b/src/icrypt.h deleted file mode 100644 index dd7fa11..0000000 --- a/src/icrypt.h +++ /dev/null @@ -1,156 +0,0 @@ -/* -*-c-*- - * - * $Id: icrypt.h,v 1.4 1998/01/12 16:46:03 mdw Exp $ - * - * Higher level encryption functions - * - * (c) 1998 Mark Wooding - */ - -/*----- Licensing notice --------------------------------------------------* - * - * This file is part of `become' - * - * `Become' is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * `Become' is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with `become'; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/*----- Revision history --------------------------------------------------* - * - * $Log: icrypt.h,v $ - * Revision 1.4 1998/01/12 16:46:03 mdw - * Fix copyright date. - * - * Revision 1.3 1997/09/26 09:14:58 mdw - * Merged blowfish branch into trunk. - * - * Revision 1.2.2.1 1997/09/26 09:08:08 mdw - * Use the Blowfish encryption algorithm instead of IDEA. This is partly - * because I prefer Blowfish (without any particularly strong evidence) but - * mainly because IDEA is patented and Blowfish isn't. - * - * Revision 1.2 1997/08/04 10:24:22 mdw - * Sources placed under CVS control. - * - * Revision 1.1 1997/07/21 13:47:49 mdw - * Initial revision - * - */ - -#ifndef ICRYPT_H -#define ICRYPT_H - -#ifdef __cplusplus - extern "C" { -#endif - -/*----- Required headers --------------------------------------------------*/ - -#include - -#ifndef BLOWFISH_H -# include "blowfish.h" -#endif - -#ifndef CONFIG_H -# include "config.h" -#endif - -/*----- Type definitions --------------------------------------------------*/ - -/* --- @icrypt_job@ --- */ - -typedef struct icrypt_job { - blowfish_key k; /* Key for en/decrypting */ - int i; /* Index into the IV buffer */ - unsigned char iv[BLOWFISH_BLKSIZE]; /* IV bytes for encrypting */ -} icrypt_job; - -/*----- Functions provided ------------------------------------------------*/ - -extern void icrypt_init(icrypt_job */*j*/, - unsigned char */*k*/, - size_t /*sz*/, - const unsigned char */*iv*/); - -/* --- @icrypt_encrypt@ --- * - * - * Arguments: @icrypt_job *j@ = job handle - * @const void *src@ = pointer to source buffer - * @void *dest@ = pointer to destination buffer - * @size_t sz@ = size of buffers to handle - * - * Returns: --- - * - * Use: Encrypts data from the source to the destination, using the - * key attached to the job handle. - */ - -extern void icrypt_encrypt(icrypt_job */*j*/, const void */*src*/, - void */*dest*/, size_t /*sz*/); - -/* --- @icrypt_decrypt@ --- * - * - * Arguments: @icrypt_job *j@ = job handle - * @const void *src@ = pointer to source buffer - * @void *dest@ = pointer to destination buffer - * @size_t sz@ = size of buffers to handle - * - * Returns: --- - * - * Use: Decrypts data from the source to the destination, using - * the key attached to the job handle. - */ - -extern void icrypt_decrypt(icrypt_job */*j*/, const void */*src*/, - void */*dest*/, size_t /*sz*/); - -/* --- @icrypt_reset@ --- * - * - * Arguments: @icrypt_job *j@ = pointer to job context block - * @unsigned char *k@ = pointer to key data, or zero for - * no change - * @size_t sz@ = size of the key in bytes - * @const unsigned char *iv@ = pointer to IV, or zero - * - * Returns: --- - * - * Use: Alters the context block. This can be used after recovery - * of a session key, for example. - */ - -extern void icrypt_reset(icrypt_job */*j*/, - unsigned char */*k*/, - size_t /*sz*/, - const unsigned char */*iv*/); - -/* --- @icrypt_saveIV@ --- * - * - * Arguments: @icrypt_job *j@ = pointer to job context block - * @unsigned char *iv@ = where to store the IV - * - * Returns: --- - * - * Use: Writes out the job's IV after munging it a little. - */ - -extern void icrypt_saveIV(icrypt_job */*j*/, unsigned char */*iv*/); - -/*----- That's all, folks -------------------------------------------------*/ - -#ifdef __cplusplus - } -#endif - -#endif diff --git a/src/keygen.c b/src/keygen.c deleted file mode 100644 index 825a595..0000000 --- a/src/keygen.c +++ /dev/null @@ -1,680 +0,0 @@ -/* -*-c-*- - * - * $Id: keygen.c,v 1.6 2003/09/17 13:17:23 mdw Exp $ - * - * Key generation - * - * (c) 1998 EBI - */ - -/*----- Licensing notice --------------------------------------------------* - * - * This file is part of `become' - * - * `Become' is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * `Become' is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with `become'; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/*----- Revision history --------------------------------------------------* - * - * $Log: keygen.c,v $ - * Revision 1.6 2003/09/17 13:17:23 mdw - * Make it build\! - * - * Revision 1.5 1998/01/12 16:46:05 mdw - * Fix copyright date. - * - * Revision 1.4 1997/12/08 15:29:27 mdw - * Major update: make random number sources configurable. Generate - * warnings if there isn't enough randomness available. - * - * Revision 1.3 1997/09/17 15:29:28 mdw - * Mix the noise from the key timings with some other environmental noise - * (obtained from `noise_acquire') for a little bit more randomness. - * - * Revision 1.2 1997/08/04 10:24:23 mdw - * Sources placed under CVS control. - * - * Revision 1.1 1997/07/21 13:47:48 mdw - * Initial revision - * - */ - -/*----- Header files ------------------------------------------------------*/ - -/* --- ANSI headers --- */ - -#include -#include -#include -#include -#include -#include -#include - -/* --- Unix headers --- */ - -#include -#include -#include - -#include -#include - -/* --- Local headers --- */ - -#include "config.h" -#include "mdwopt.h" -#include "noise.h" -#include "rand.h" -#include "tx.h" -#include "utils.h" - -/*----- Static variables --------------------------------------------------*/ - -static struct termios kg__raw, kg__old; /* Terminal settings */ -static int kg__tty; /* File handle for the terminal */ -static FILE *kg__ttyfp; /* Stream pointer for terminal */ -static unsigned int kg__flags; /* Various interesting flags */ - -enum { - kgFlag__cbreak = 1 /* Terminal is in cbreak mode */ -}; - -/*----- Main code ---------------------------------------------------------*/ - -/* --- @kg__cbreak@ --- * - * - * Arguments: --- - * - * Returns: --- - * - * Use: Makes the terminal return characters as soon as they're - * asked for. - */ - -void kg__cbreak(void) -{ - /* --- Don't do this if I don't have to --- */ - - if (kg__flags & kgFlag__cbreak) - return; - - /* --- Fetch the old attributes, and remember them --- */ - - if (tcgetattr(kg__tty, &kg__old)) - die("couldn't read terminal attributes: %s", strerror(errno)); - memcpy(&kg__raw, &kg__old, sizeof(kg__raw)); - - /* --- Now modify them for raw mode --- */ - - kg__raw.c_lflag &= ~(ICANON | ECHO); - kg__raw.c_cc[VTIME] = 0; - kg__raw.c_cc[VMIN] = 1; - - /* --- Remember the new state, and away we go --- */ - - kg__flags |= kgFlag__cbreak; - if (tcsetattr(kg__tty, TCSAFLUSH, &kg__raw)) - die("couldn't set terminal attributes: %s", strerror(errno)); -} - -/* --- @kg__crepair@ --- * - * - * Arguments: --- - * - * Returns: --- - * - * Use: Unbreaks a cbroken tty. Obvious, innit? - */ - -static void kg__crepair(void) -{ - /* --- Don't do this if I don't have to --- */ - - if (~kg__flags & kgFlag__cbreak) - return; - - /* --- Reset the old attributes --- */ - - tcsetattr(kg__tty, TCSAFLUSH, &kg__old); - kg__flags &= ~kgFlag__cbreak; -} - -/* --- @kg__signal@ --- * - * - * Arguments: @int sig@ = signal number - * - * Returns: --- - * - * Use: Tidies up if I get a signal. - */ - -static void kg__signal(int sig) -{ - kg__crepair(); - signal(sig, SIG_DFL); - raise(sig); -} - -/* --- @kgFmt__binary@ --- * - * - * Arguments: @unsigned char *k@ = pointer to key buffer - * @size_t bits@ = number of bits to write - * @FILE *fp@ = stream to write on - * - * Returns: --- - * - * Use: Writes bits on a stream. - */ - -static void kgFmt__binary(unsigned char *k, size_t bits, FILE *fp) -{ - fwrite(k, 1, bits / 8, fp); -} - -/* --- @kgFmt__base64@ --- * - * - * Arguments: @unsigned char *k@ = pointer to key buffer - * @size_t bits@ = number of bits to write - * @FILE *fp@ = stream to write on - * - * Returns: --- - * - * Use: Writes bits on a stream in an encoded way. - */ - -static void kgFmt__base64(unsigned char *k, size_t bits, FILE *fp) -{ - static const char xlt[64] = { "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789+/" }; - unsigned long b; - int ll = 0; - - while (bits > 24) { - b = ((k[0] & 0xffu) << 16) | ((k[1] & 0xffu) << 8) | (k[2] & 0xffu); - k += 3; - bits -= 24; - putc(xlt[(b >> 18) & 0x3fu], fp); - putc(xlt[(b >> 12) & 0x3fu], fp); - putc(xlt[(b >> 6) & 0x3fu], fp); - putc(xlt[(b >> 0) & 0x3fu], fp); - if ((ll += 4) > 70) { - putc('\n', fp); - ll = 0; - } - } - - b = 0; - switch (bits) { - case 24: - b = *k++ & 0xffu; - case 16: - b = (b << 8) | (*k++ & 0xffu); - case 8: - b = (b << 8) | (*k++ & 0xffu); - } - b <<= (24 - bits); - putc(xlt[(b >> 18) & 0x3fu], fp); - putc(xlt[(b >> 12) & 0x3fu], fp); - switch (bits) { - case 24: - putc(xlt[(b >> 6) & 0x3fu], fp); - putc(xlt[(b >> 0) & 0x3fu], fp); - break; - case 16: - putc(xlt[(b >> 6) & 0x3fu], fp); - putc('=', fp); - break; - case 8: - fputs("==", fp); - break; - } - - putc('\n', fp); -} - -/* --- @kg__gen@ --- * - * - * Arguments: @unsigned char *ui@ = pointer to array to fill in - * @size_t sz@ = number of bits to generate - * - * Returns: --- - * - * Use: Uses key timings to generate random numbers. Maybe. - */ - -static void kg__gen(unsigned char *ui, size_t sz) -{ - int bits = 32 < sz ? 32 : sz; - size_t wsz = (sz + 31u) & ~31u; - unsigned long last, ldiff = 0; - unsigned long a = 0; - unsigned long fact = 1000000 / CLOCKS_PER_SEC; - - fprintf(kg__ttyfp, -"I need to get %lu random bits; I'll do this by timing your keypresses.\n" -"Please type some arbitrary text until I say `done'.\n", - (unsigned long)sz); - - { - struct timeval tv; - gettimeofday(&tv, 0); - last = tv.tv_usec / fact + tv.tv_sec * fact; - } - - while (sz) { - int useful; - uint_32 orr, xor; - - /* --- Print current status --- */ - - fprintf(kg__ttyfp, "\r%5lu...", (unsigned long)sz); - fflush(kg__ttyfp); - - /* --- Read the next character --- */ - - { - char buff[16]; - if (read(kg__tty, buff, sizeof(buff)) < 0) - die("couldn't read from terminal: %s", strerror(errno)); - } - - /* --- Fiddle with times --- * - * - * Read the time now. Turn it into 32 bits of useful information, and - * find the difference between that and the previous time. Compare this - * with the difference between the previous pair of keypresses. - */ - - { - struct timeval tv; - uint_32 n, nd; - - gettimeofday(&tv, 0); - n = tv.tv_usec / fact + tv.tv_sec * fact; - if (!ldiff) { - ldiff = n - last; - last = n; - continue; - } - nd = n - last; - orr = nd | ldiff; - xor = nd ^ ldiff; - D( printf("\nlast = %08lx, next = %08lx, ldiff = %08lx, nd = %08lx\n", - (unsigned long)last, (unsigned long)n, - (unsigned long)ldiff, (unsigned long)nd); - printf("xor = %08lx\n", (unsigned long)xor); ) - ldiff = nd; - last = n; - } - - /* --- Find the useful bits in this value --- * - * - * Find the least significant set bit in @bowl@ and chop it off. Then - * find the most significant set bit and chop that off two. The rest is - * probably interesting. - */ - - { - unsigned long i; - - if (!orr || !xor) - continue; /* erk! */ - - useful = 30; - - i = 0x80000000ul; - if (xor & i) { - while (i && (xor & i) != 0) { - i >>= 1; - useful--; - } - } else { - while (i && (xor & i) == 0) { - i >>= 1; - useful--; - } - } - xor &= ~-i; - - while ((orr & 1) == 0) { - useful--; - orr >>= 1; - xor >>= 1; - } - xor >>= 1; - - if (useful < 1) - continue; - } - - /* --- Now add the bits in the mixing bowl to my stash --- * - * - * There are two cases: - * - * 1. I have more bits than will fit into the accumulator. Then I must - * put as many bits into the accumulator as will fit, store the - * accumulator, and remove the spent bits. - * - * 2. I have too few bits to fit in the accumulator. Then shift them - * in and return. - */ - - while (sz && useful) { - - D( printf("got %i bits, need %i/%i: %8lx\n", - useful, bits, sz, (unsigned long)xor); ) - - if (useful >= bits) { - - D( printf("shifted acc = %08lx\n" - " new bits = %08lx\n" - " result = %08lx\n", - (unsigned long)(a << bits), - (unsigned long)(xor >> (useful - bits)), - (unsigned long)((a << bits) | (xor >> (useful - bits)))); ) - - a = (a << bits) | (xor >> (useful - bits)); - - sz -= bits; - wsz -= bits; - useful -= bits; - - if (sz == 0) { - a <<= wsz; - bits = 32 - wsz; - } else - bits = 32; - - while (bits > 0) { - D( printf("writing %02x\n", (a >> 24) & 0xffu); ) - *ui++ = (a >> 24) & 0xffu; - a <<= 8; - bits -= 8; - } - a = 0; - - bits = 32 < sz ? 32 : sz; - - } else { - - D( printf("shifted acc = %08lx\n" - " new bits = %08lx\n" - " result = %08lx\n", - (unsigned long)(a << useful), - (unsigned long)(xor), - (unsigned long)((a << useful) | (xor))); ) - a = (a << useful) | xor; - bits -= useful; - sz -= useful; - wsz -= useful; - useful = 0; - } - } - } - - fputs("\rDone! \n", kg__ttyfp); - putc('\a', kg__ttyfp); fflush(kg__ttyfp); - sleep(1); -} - -/* --- @main@ --- * - * - * Arguments: @int argc@ = number of arguments - * @char *argv[]@ = array of arguments - * - * Returns: Zero if it worked, nonzero if it didn't. - * - * Use: Generates random numbers from the keyboard. - */ - -int main(int argc, char *argv[]) -{ - unsigned char *uip; - size_t sz = 128; - size_t keybits = 0; - unsigned f = 0; - const char *file = 0; - FILE *fp; - - enum { - f_envNoise = 1, - f_keyTimer = 2 - }; - - /* --- Formats table --- */ - - static struct { - const char *name; - void (*proc)(unsigned char *k, size_t bits, FILE *fp); - } format[] = { - { "tx", tx_putBits }, - { "hex", tx_putBits }, - { "binary", kgFmt__binary }, - { "base64", kgFmt__base64 }, - { 0, 0 } - }; - - void (*fmt)(unsigned char *, size_t, FILE *) = tx_putBits; - - /* --- Explain who I am --- */ - - ego(argv[0]); - - f |= f_envNoise | f_keyTimer; - - /* --- Read arguments --- */ - - for (;;) { - static struct option opts[] = { - { "help", 0, 0, 'h' }, - { "bits", gFlag_argReq, 0, 'b' }, - { "output", gFlag_argReq, 0, 'o' }, - { "format", gFlag_argReq, 0, 'f' }, - { "key-times", gFlag_negate|gFlag_argOpt, 0, 'k' }, - { "env-noise", gFlag_negate, 0, 'e' }, - { 0, 0, 0, 0 } - }; - - int i = mdwopt(argc, argv, "hb:o:f:k+::e+", opts, 0, 0, gFlag_negation); - - if (i < 0) - break; - switch (i) { - case 'h': - printf("" -"Usage: %s [-h] [-|+ek] [-b BITS] [-o FILE] [-f FORMAT]\n" -"\n" -"Generates BITS (by default, 128) random bits. The resulting number is\n" -"written to FILE, or standard output.\n\n" -"Randomness is taken from key-timings and environmental noise, although\n" -"you can disable either (or both) of these sources.\n\n" -"Options provided are:\n\n" -"-h, --help Display this help text\n" -"-b, --bits=BITS\t Generate BITS random bits instead of 128\n" -"-o, --output=FILE Write bits to FILE, not standard output\n" -"-f, --format=FORMAT Write bits in FORMAT:\n" -" tx, hex Hexadecimal\n" -" binary Raw binary\n" -" base64 Base64-encoded binary\n" -"-e, --[no-]env-noise Do [not] read environmental noise\n" -"-k, --[no-]key-times[=BITS] Do [not] read key timing information\n" -" (only read BITS bits from key timings)\n", - quis()); - exit(0); - break; - case 'b': - sz = atoi(optarg); - if (sz == 0) - die("bad number of bits (illegible or zero)"); - if (sz % 8) - die("can only generate a whole number of 8-bit bytes"); - break; - case 'o': - file = optarg; - break; - case 'f': - fmt = 0; - for (i = 0; format[i].name; i++) { - const char *p = format[i].name, *q = optarg; - for (;;) { - if (*q == 0) - break; - if (*p != *q) - break; - p++, q++; - } - if (!*q) { - if (fmt) - die("ambiguous format name: `%s'", optarg); - fmt = format[i].proc; - } - } - if (!fmt) - die("unknown format name: `%s'", optarg); - break; - case 'e': - f |= f_envNoise; - break; - case 'e' | gFlag_negated: - f &= ~f_envNoise; - break; - case 'k': - f |= f_keyTimer; - if (optarg) { - keybits = atoi(optarg); - if (keybits == 0) - die("bad number of bits (illegible or zero)"); - if (keybits % 8) - die("bad number of bits (must be multiple of 8)"); - } - else - keybits = 0; - break; - case 'k' | gFlag_negated: - f &= ~f_keyTimer; - break; - case '?': - exit(1); - break; - } - } - - /* --- Check the sanity of this request --- */ - - { - size_t bits = 0; - - if (f & f_keyTimer) { - if (!keybits) - keybits = sz; - bits += keybits; - } - if (f & f_envNoise) - bits += 384; /* Estimate */ - - if (bits == 0) - die("no randomness sources given"); - if (bits < sz) - moan("warning: randomness may not be sufficiently high"); - } - - if (optind < argc) { - fprintf(stderr, "Usage: %s [-opts]\n", quis()); - exit(1); - } - - /* --- Allocate memory --- */ - - { - size_t buff = sz / 8; - if (f & f_keyTimer && keybits > sz) - buff = keybits / 8; - uip = xmalloc(buff); - } - - rand_clear(); - - /* --- Fetch randomness from key timings --- */ - - if (f & f_keyTimer) { - - /* --- Open the terminal --- * - * - * I'd like to be able to @fprintf@ to the terminal, so use @fopen@. - */ - - if ((kg__ttyfp = fopen("/dev/tty", "r+")) == 0) - die("couldn't open terminal: %s", strerror(errno)); - kg__tty = fileno(kg__ttyfp); - - /* --- Tidy up nicely if I die --- */ - - signal(SIGINT, kg__signal); - signal(SIGTERM, kg__signal); - atexit(kg__crepair); - - /* --- Put the terminal into cbreak, read the key, and restore --- */ - - kg__cbreak(); - kg__gen(uip, keybits); - kg__crepair(); - rand_add(uip, keybits / 8); - rand_churn(); - } - - /* --- Find some noise from the environment too --- */ - - if (f & f_envNoise) { - noise_acquire(); - rand_churn(); - } - - /* --- Now write the number and exit --- */ - - rand_extract(uip, sz / 8); - D( fputs("*** ", fp); tx_putBits(uip, sz, stdout); ) - - /* --- Open the output file, if one is specified --- */ - - if (file) { - int fd; - - /* --- Open the file oddly --- * - * - * There's a good reason for this. I want to be able to @fprintf@ (for - * the benefit of @tx_putWords@ mainly) but I also want to ensure that - * only the user has read permissions for the file. So I'll use @open@ - * with an appropriate mode and then @fdopen@ the file descriptor to - * get a stream. Yuk. - */ - - if ((fd = open(file, O_WRONLY | O_CREAT | O_TRUNC, 0600)) < 0) - die("couldn't open output file: %s", strerror(errno)); - if ((fp = fdopen(fd, "w")) == 0) - die("couldn't attach stream to output file: %s", strerror(errno)); - } else - fp = stdout; - - fmt(uip, sz, fp); - if (file) - fclose(fp); - memset(uip, 0, sz / 8); /* Burn temporary buffer */ - rand_clear(); - return (0); -} - -/*----- That's all, folks -------------------------------------------------*/ diff --git a/src/md5.c b/src/md5.c deleted file mode 100644 index 242e14c..0000000 --- a/src/md5.c +++ /dev/null @@ -1,502 +0,0 @@ -/* -*-c-*- - * - * $Id: md5.c,v 1.3 1998/01/12 16:46:11 mdw Exp $ - * - * MD-5 secure hash routines - * Based on RSA MD-5 code - * - * (c) 1996-1998 Mark Wooding - */ - -/*----- Licensing notice --------------------------------------------------* - * - * This file is part of `become' - * - * `Become' is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * `Become' is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with `become'; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/*----- Revision history --------------------------------------------------* - * - * $Log: md5.c,v $ - * Revision 1.3 1998/01/12 16:46:11 mdw - * Fix copyright date. - * - * Revision 1.2 1997/08/04 10:24:23 mdw - * Sources placed under CVS control. - * - * Revision 1.1 1997/07/21 13:47:47 mdw - * Initial revision - * - */ - -/*----- Header files ------------------------------------------------------*/ - -#include -#include - -#include "config.h" -#include "md5.h" -#include "utils.h" - -/*----- Define MD-5 transform ---------------------------------------------*/ - -/* --- Low-level nonlinear functions --- */ - -#define f(x,y,z) (((x) & (y)) | ((~x) & (z))) -#define g(x,y,z) (((x) & (z)) | ((y) & (~z))) -#define h(x,y,z) ((x) ^ (y) ^ (z)) -#define i(x,y,z) ((y) ^ ((x) | (~z))) - -#define rol(x,b) (((x) << (b)) | ((x) >> (32-(b)))) - -/* --- Rotations applied at various stages --- */ - -#define S11 7u -#define S12 12u -#define S13 17 -#define S14 22u -#define S21 5u -#define S22 9u -#define S23 14u -#define S24 20u -#define S31 4u -#define S32 11u -#define S33 16u -#define S34 23u -#define S41 6u -#define S42 10u -#define S43 15u -#define S44 21u - -/* --- Higher level nonlinear functions --- */ - -#define ff(a, b, c, d, x, s, m) ( a += f(b, c, d) + x + m, \ - a = rol(a, s), a += b ) - -#define gg(a, b, c, d, x, s, m) ( a += g(b, c, d) + x + m, \ - a = rol(a, s), a += b ) - -#define hh(a, b, c, d, x, s, m) ( a += h(b, c, d) + x + m, \ - a = rol(a, s), a += b ) - -#define ii(a, b, c, d, x, s, m) ( a += i(b, c, d) + x + m, \ - a = rol(a, s), a += b ) - -/*----- Main code ---------------------------------------------------------*/ - -/* --- @md5__trans@ --- * - * - * Arguments: @uint_32 *v@ = pointer to chaining variables (updated) - * @const unsigned char *buf@ = pointer to a 64-byte block - * - * Returns: --- - * - * Use: Performs the main MD5 transform on a block of data. - */ - -static void md5__trans(uint_32 *v, const unsigned char *buf) -{ - uint_32 a, b, c, d; - uint_32 ib[16]; - size_t i; - - /* --- Initialise my internal registers --- */ - - a = v[0], b = v[1], c = v[2], d = v[3]; - - /* --- Turn the buffer into 32-bit words --- */ - - for (i = 0; i < 16; i++) - ib[i] = load32_l(buf + (i << 2)); - - /* --- Round one --- */ - - ff(a, b, c, d, ib[ 0], S11, 0xd76aa478); /* 1 */ - ff(d, a, b, c, ib[ 1], S12, 0xe8c7b756); /* 2 */ - ff(c, d, a, b, ib[ 2], S13, 0x242070db); /* 3 */ - ff(b, c, d, a, ib[ 3], S14, 0xc1bdceee); /* 4 */ - ff(a, b, c, d, ib[ 4], S11, 0xf57c0faf); /* 5 */ - ff(d, a, b, c, ib[ 5], S12, 0x4787c62a); /* 6 */ - ff(c, d, a, b, ib[ 6], S13, 0xa8304613); /* 7 */ - ff(b, c, d, a, ib[ 7], S14, 0xfd469501); /* 8 */ - ff(a, b, c, d, ib[ 8], S11, 0x698098d8); /* 9 */ - ff(d, a, b, c, ib[ 9], S12, 0x8b44f7af); /* 10 */ - ff(c, d, a, b, ib[10], S13, 0xffff5bb1); /* 11 */ - ff(b, c, d, a, ib[11], S14, 0x895cd7be); /* 12 */ - ff(a, b, c, d, ib[12], S11, 0x6b901122); /* 13 */ - ff(d, a, b, c, ib[13], S12, 0xfd987193); /* 14 */ - ff(c, d, a, b, ib[14], S13, 0xa679438e); /* 15 */ - ff(b, c, d, a, ib[15], S14, 0x49b40821); /* 16 */ - - /* --- Round two --- */ - - gg(a, b, c, d, ib[ 1], S21, 0xf61e2562); /* 17 */ - gg(d, a, b, c, ib[ 6], S22, 0xc040b340); /* 18 */ - gg(c, d, a, b, ib[11], S23, 0x265e5a51); /* 19 */ - gg(b, c, d, a, ib[ 0], S24, 0xe9b6c7aa); /* 20 */ - gg(a, b, c, d, ib[ 5], S21, 0xd62f105d); /* 21 */ - gg(d, a, b, c, ib[10], S22, 0x02441453); /* 22 */ - gg(c, d, a, b, ib[15], S23, 0xd8a1e681); /* 23 */ - gg(b, c, d, a, ib[ 4], S24, 0xe7d3fbc8); /* 24 */ - gg(a, b, c, d, ib[ 9], S21, 0x21e1cde6); /* 25 */ - gg(d, a, b, c, ib[14], S22, 0xc33707d6); /* 26 */ - gg(c, d, a, b, ib[ 3], S23, 0xf4d50d87); /* 27 */ - gg(b, c, d, a, ib[ 8], S24, 0x455a14ed); /* 28 */ - gg(a, b, c, d, ib[13], S21, 0xa9e3e905); /* 29 */ - gg(d, a, b, c, ib[ 2], S22, 0xfcefa3f8); /* 30 */ - gg(c, d, a, b, ib[ 7], S23, 0x676f02d9); /* 31 */ - gg(b, c, d, a, ib[12], S24, 0x8d2a4c8a); /* 32 */ - - /* --- Round three --- */ - - hh(a, b, c, d, ib[ 5], S31, 0xfffa3942); /* 33 */ - hh(d, a, b, c, ib[ 8], S32, 0x8771f681); /* 34 */ - hh(c, d, a, b, ib[11], S33, 0x6d9d6122); /* 35 */ - hh(b, c, d, a, ib[14], S34, 0xfde5380c); /* 36 */ - hh(a, b, c, d, ib[ 1], S31, 0xa4beea44); /* 37 */ - hh(d, a, b, c, ib[ 4], S32, 0x4bdecfa9); /* 38 */ - hh(c, d, a, b, ib[ 7], S33, 0xf6bb4b60); /* 39 */ - hh(b, c, d, a, ib[10], S34, 0xbebfbc70); /* 40 */ - hh(a, b, c, d, ib[13], S31, 0x289b7ec6); /* 41 */ - hh(d, a, b, c, ib[ 0], S32, 0xeaa127fa); /* 42 */ - hh(c, d, a, b, ib[ 3], S33, 0xd4ef3085); /* 43 */ - hh(b, c, d, a, ib[ 6], S34, 0x04881d05); /* 44 */ - hh(a, b, c, d, ib[ 9], S31, 0xd9d4d039); /* 45 */ - hh(d, a, b, c, ib[12], S32, 0xe6db99e5); /* 46 */ - hh(c, d, a, b, ib[15], S33, 0x1fa27cf8); /* 47 */ - hh(b, c, d, a, ib[ 2], S34, 0xc4ac5665); /* 48 */ - - /* --- Round four --- */ - - ii(a, b, c, d, ib[ 0], S41, 0xf4292244); /* 49 */ - ii(d, a, b, c, ib[ 7], S42, 0x432aff97); /* 50 */ - ii(c, d, a, b, ib[14], S43, 0xab9423a7); /* 51 */ - ii(b, c, d, a, ib[ 5], S44, 0xfc93a039); /* 52 */ - ii(a, b, c, d, ib[12], S41, 0x655b59c3); /* 53 */ - ii(d, a, b, c, ib[ 3], S42, 0x8f0ccc92); /* 54 */ - ii(c, d, a, b, ib[10], S43, 0xffeff47d); /* 55 */ - ii(b, c, d, a, ib[ 1], S44, 0x85845dd1); /* 56 */ - ii(a, b, c, d, ib[ 8], S41, 0x6fa87e4f); /* 57 */ - ii(d, a, b, c, ib[15], S42, 0xfe2ce6e0); /* 58 */ - ii(c, d, a, b, ib[ 6], S43, 0xa3014314); /* 59 */ - ii(b, c, d, a, ib[13], S44, 0x4e0811a1); /* 60 */ - ii(a, b, c, d, ib[ 4], S41, 0xf7537e82); /* 61 */ - ii(d, a, b, c, ib[11], S42, 0xbd3af235); /* 62 */ - ii(c, d, a, b, ib[ 2], S43, 0x2ad7d2bb); /* 63 */ - ii(b, c, d, a, ib[ 9], S44, 0xeb86d391); /* 64 */ - - /* --- Update the context --- */ - - v[0] += a, v[1] += b, v[2] += c, v[3] += d; -} - -/* --- @md5_trans@ --- * - * - * Arguments: @unsigned char *v@ = pointer to chaining block (updated) - * @const unsigned char *buf@ = pointer to input buffer - * - * Returns: --- - * - * Use: Performs the MD5 transformation on a chunk of data. This may - * be useful for using MD5 in MDC-type cipher constructions. - */ - -void md5_trans(unsigned char *v, const unsigned char *buf) -{ - uint_32 vv[4]; - - vv[0] = load32_l(v + 0); - vv[1] = load32_l(v + 4); - vv[2] = load32_l(v + 8); - vv[3] = load32_l(v + 12); - md5__trans(vv, buf); - store32_l(v + 0, vv[0]); - store32_l(v + 4, vv[1]); - store32_l(v + 8, vv[2]); - store32_l(v + 12, vv[3]); -} - -/* --- @md5_buffer@ --- * - * - * Arguments: @md5 *m@ = pointer to an MD5 context - * @const void *buff@ = pointer to buffer of data - * @size_t size@ = size of buffer - * - * Returns: --- - * - * Use: Hashes the buffer of data. You can call @md5_buffer@ - * lots of times during an MD5 job, to allow big files to be - * split into little ones. - */ - -void md5_buffer(md5 *m, const void *buff, size_t size) -{ - long int s = size; - const unsigned char *b = buff; - unsigned long x, y; - - /* --- Maybe there's some data already in the buffer --- */ - - if (x = m->size & 63, x) { - y = 64 - x; - if (y > s) { - memcpy(x + m->buf, b, s); - m->size += s; - return; - } - memcpy(x + m->buf, b, y); - md5__trans(m->val, m->buf); - s -= y, b += y; - } - - /* --- Now do whole buffers-full --- */ - - while (s >= 64) { - md5__trans(m->val, b); - s -= 64, b += 64; - } - - /* --- Tidy up the tail end --- */ - - if (s) - memcpy(m->buf, b, s); - m->size += size; -} - -/* --- @md5_key@ --- * - * - * Arguments: @md5 *m@ = pointer to an MD5 context - * @const unsigned char *k@ = pointer to a 4-word `key' - * - * Returns: --- - * - * Use: Initialises a context buffer, with a chosen initialisation - * string (instead of the standard MD5 value). This allows you - * to use NMAC message authentication, should the urge take you. - */ - -void md5_key(md5 *m, const unsigned char *k) -{ - m->size = 0; - m->val[0] = load32_l(k + 0); - m->val[0] = load32_l(k + 4); - m->val[0] = load32_l(k + 8); - m->val[0] = load32_l(k + 12); -} - -/* --- @md5_init@ --- * - * - * Arguments: @md5 *m@ = pointer to an MD5 context - * - * Returns: --- - * - * Use: Initialises the context buffer, so that you can do an - * MD5 job. - */ - -void md5_init(md5 *m) -{ - m->size = 0; - m->val[0] = 0x67452301; - m->val[1] = 0xefcdab89; - m->val[2] = 0x98badcfe; - m->val[3] = 0x10325476; -} - -/* --- @md5_final@ --- * - * - * Arguments: @md5 *m@ = pointer to context buffer - * @unsigned char *v@ = where to store the value - * - * Returns: --- - * - * Use: Finalises an MD5 buffer, so that you can use the result. - */ - -void md5_final(md5 *m, unsigned char *v) -{ - int s = m->size; - - /* --- Pad out the block --- */ - - { - const static unsigned char pad[64] = { 0x80 }; - int p = m->size & 63; - p = (p < 56) ? (p = 56 - p) : (p = 120 - p); - md5_buffer(m, pad, p); - } - - /* --- Append the length --- */ - - { - unsigned char b[8]; - - store32_l(b + 0, s << 3); - store32_l(b + 4, s >> 29); - md5_buffer(m, b, 8); - } - - /* --- Write out the value --- */ - - if (v) { - store32_l(v + 0, m->val[0]); - store32_l(v + 4, m->val[1]); - store32_l(v + 8, m->val[2]); - store32_l(v + 12, m->val[3]); - } -} - -/*----- Test driver -------------------------------------------------------*/ - -#ifdef TEST_RIG - -int main(int argc, char *argv[]) -{ - if (argc > 1 && strcmp(argv[1], "-x") == 0) { - - static struct { - const char *string; - uint_32 md[4]; - } table[] = { - "", { 0xd98c1dd4, 0x04b2008f, 0x980980e9, 0x7e42f8ec }, - "a", { 0xb975c10c, 0xa8b6f1c0, 0xe299c331, 0x61267769 }, - "abc", { 0x98500190, 0xb04fd23c, 0x7d3f96d6, 0x727fe128 }, - "message digest", { 0x7d696bf9, 0x8d93b77c, 0x312f5a52, 0xd061f1aa }, - "abcdefghijklmnopqrstuvwxyz", - { 0xd7d3fcc3, 0x00e49261, 0x6c49fb7d, 0x3be167ca }, - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", - { 0x98ab74d1, 0xf5d977d2, 0x2c1c61a5, 0x9f9d419f }, - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\n" - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\n" - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\n" - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\n" - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\n" - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\n" - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\n" - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\n" - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\n" - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\n" - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\n" - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\n" - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\n" - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\n" - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\n" - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\n" - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\n" - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\n" - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\n" - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\n" - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\n" - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\n" - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\n", - { 0xbaa7652b, 0x5e10cd4a, 0xde9acbf2, 0xfa0b9fbd } - }; - int steptbl[] = { 3, 18, 32, 37, 63, 64, 65, 256, 1024, -1 }; - - md5 m; - int i, j; - const char *p; - size_t sz, a, d; - int f = 1; - - for (i = 0; i < sizeof(table) / sizeof(table[0]); i++) { - sz = strlen(table[i].string); - for (j = 0; steptbl[j] < sz && steptbl[j] != -1; j++) { - p = table[i].string; - d = steptbl[j]; - md5_init(&m); - for (a = sz; a > d; a -= d) { - md5_buffer(&m, p, d); - p += d; - } - md5_buffer(&m, p, a); - md5_final(&m, 0); - if (m.val[0] != table[i].md[0] || - m.val[1] != table[i].md[1] || - m.val[2] != table[i].md[2] || - m.val[3] != table[i].md[3]) { - printf("!!! bad value, string == `%s', step size == %i\n" - "!!! expected %08lx-%08lx-%08lx-%08lx, found " - "%08lx-%08lx-%08lx-%08lx\n\n", - table[i].string, d, - (unsigned long)table[i].md[0], - (unsigned long)table[i].md[1], - (unsigned long)table[i].md[2], - (unsigned long)table[i].md[3], - (unsigned long)m.val[0], - (unsigned long)m.val[1], - (unsigned long)m.val[2], - (unsigned long)m.val[3]); - f = 0; - } - } - md5_init(&m); - md5_buffer(&m, table[i].string, sz); - md5_final(&m, 0); - if (m.val[0] != table[i].md[0] || - m.val[1] != table[i].md[1] || - m.val[2] != table[i].md[2] || - m.val[3] != table[i].md[3]) { - printf("!!! bad value, string == `%s', step size == entire string\n" - "!!! expected %08lx-%08lx-%08lx-%08lx, found " - "%08lx-%08lx-%08lx-%08lx\n\n", - table[i].string, - (unsigned long)table[i].md[0], - (unsigned long)table[i].md[1], - (unsigned long)table[i].md[2], - (unsigned long)table[i].md[3], - (unsigned long)m.val[0], - (unsigned long)m.val[1], - (unsigned long)m.val[2], - (unsigned long)m.val[3]); - f = 0; - } else { - printf("`%s' => %08lx-%08lx-%08lx-%08lx\n", - table[i].string, - (unsigned long)m.val[0], - (unsigned long)m.val[1], - (unsigned long)m.val[2], - (unsigned long)m.val[3]); - } - } - - } else { - - char buff[4096]; - md5 m; - int i; - int read; - - md5_init(&m); - while (read = fread(buff, 1, 4096, stdin), read) - md5_buffer(&m, buff, read); - md5_final(&m, 0); - - for (i = 0; i < 4; i++) - printf("%02lx%02lx%02lx%02lx", - (unsigned long)( (m.val[i] & 0x000000FF) >> 0 ), - (unsigned long)( (m.val[i] & 0x0000FF00) >> 8 ), - (unsigned long)( (m.val[i] & 0x00FF0000) >> 16 ), - (unsigned long)( (m.val[i] & 0xFF000000) >> 24 )); - putc('\n', stdout); - - } - - return (0); -} - -#endif - -/*----- That's all, folks -------------------------------------------------*/ diff --git a/src/md5.h b/src/md5.h deleted file mode 100644 index a914c09..0000000 --- a/src/md5.h +++ /dev/null @@ -1,152 +0,0 @@ -/* -*-c-*- - * - * $Id: md5.h,v 1.3 1998/01/12 16:46:13 mdw Exp $ - * - * MD-5 secure hash routines - * Based on RSA MD-5 code - * - * (c) 1996-1998 Mark Wooding - */ - -/*----- Licensing notice --------------------------------------------------* - * - * This file is part of `become' - * - * `Become' is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * `Become' is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with `become'; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/*----- Revision history --------------------------------------------------* - * - * $Log: md5.h,v $ - * Revision 1.3 1998/01/12 16:46:13 mdw - * Fix copyright date. - * - * Revision 1.2 1997/08/04 10:24:23 mdw - * Sources placed under CVS control. - * - * Revision 1.1 1997/07/21 13:47:47 mdw - * Initial revision - * - */ - -#ifndef MD5_H -#define MD5_H - -#ifdef __cplusplus - extern "C" { -#endif - -/*----- Required headers --------------------------------------------------*/ - -#include - -#ifndef CONFIG_H -# include "config.h" -#endif - -/*----- Useful constants --------------------------------------------------*/ - -#define MD5_HASHSIZE (16u) /* Size of an MD5 hash */ - -/*----- Type definitions --------------------------------------------------*/ - -/* --- MD5 context buffer --- */ - -typedef struct { - uint_32 val[4]; /* Result of the hash function */ - unsigned long size; /* Current size of data in bytes */ - unsigned char buf[64]; /* Buffer accumulating next block */ -} md5; - -/*----- Functions provided ------------------------------------------------*/ - -/* --- @md5_trans@ --- * - * - * Arguments: @unsigned char *v@ = pointer to chaining block (updated) - * @const unsigned char *buf@ = pointer to input buffer - * - * Returns: --- - * - * Use: Performs the MD5 transformation on a chunk of data. This may - * be useful for using MD5 in MDC-type cipher constructions. - */ - -extern void md5_trans(unsigned char */*v*/, const unsigned char */*buf*/); - -/* --- @md5_buffer@ --- * - * - * Arguments: @md5 *m@ = pointer to an MD5 context - * @const void *buff@ = pointer to buffer of data - * @size_t size@ = size of buffer - * - * Returns: --- - * - * Use: Hashes the buffer of data. You can call md5_buffer - * lots of times during an MD5 job, to allow big files to be - * split into little ones. - * - * This routine could be improved lots, to compare with the - * Straylight ARM assembler implementation, although that - * requires lots of work. Remember that the ARM version - * doesn't need to do endianness-fiddling. - */ - -extern void md5_buffer(md5 */*m*/, const void */*buff*/, size_t /*size*/); - -/* --- @md5_key@ --- * - * - * Arguments: @md5 *m@ = pointer to an MD5 context - * @const unsigned char *k@ = pointer to a 4-word `key' - * - * Returns: --- - * - * Use: Initialises a context buffer, with a chosen initialisation - * string (instead of the standard MD5 value). This allows you - * to use NMAC message authentication, should the urge take you. - */ - -extern void md5_key(md5 */*m*/, const unsigned char */*k*/); - -/* --- @md5_init@ --- * - * - * Arguments: @md5 *m@ = pointer to an MD5 context - * - * Returns: --- - * - * Use: Initialises the context buffer, so that you can do an - * MD5 job. - */ - -extern void md5_init(md5 */*m*/); - -/* --- @md5_final@ --- * - * - * Arguments: @md5 *m@ = pointer to context buffer - * @unsigned char *v@ = where to store the value - * - * Returns: --- - * - * Use: Finalises an MD5 buffer, so that you can use the result. - */ - -extern void md5_final(md5 */*m*/, unsigned char */*v*/); - -/*----- That's all, folks -------------------------------------------------*/ - -#ifdef __cplusplus - } -#endif - -#endif diff --git a/src/name.c b/src/name.c index 6599d45..bd49ab9 100644 --- a/src/name.c +++ b/src/name.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: name.c,v 1.7 1998/04/23 13:23:56 mdw Exp $ + * $Id: name.c,v 1.8 2003/10/12 00:14:55 mdw Exp $ * * Looking up of names in symbol tables * @@ -29,6 +29,10 @@ /*----- Revision history --------------------------------------------------* * * $Log: name.c,v $ + * Revision 1.8 2003/10/12 00:14:55 mdw + * Major overhaul. Now uses DSA signatures rather than the bogus symmetric + * encrypt-and-hope thing. Integrated with mLib and Catacomb. + * * Revision 1.7 1998/04/23 13:23:56 mdw * Fix bugs involving empty classes. * @@ -75,6 +79,11 @@ #include #include +/* --- mLib headers --- */ + +#include +#include + /* --- Local headers --- */ #include "config.h" @@ -83,9 +92,7 @@ #include "class.h" #include "name.h" #include "netg.h" -#include "sym.h" #include "userdb.h" -#include "utils.h" /*----- Static variables --------------------------------------------------*/ @@ -349,7 +356,7 @@ void name_init(void) { /* --- Initialise the name table --- */ - sym_createTable(&name__table); + sym_create(&name__table); /* --- Add everyone into the table --- */ @@ -396,7 +403,7 @@ void name_end(void) sym_iter i; name *n; - for (sym_createIter(&i, &name__table); (n = sym_next(&i)) != 0; ) { + for (sym_mkiter(&i, &name__table); (n = sym_next(&i)) != 0; ) { if (n->c) class_dec(n->c); } @@ -404,7 +411,7 @@ void name_end(void) /* --- Destroy and recreate the table --- */ - sym_destroyTable(&name__table); + sym_destroy(&name__table); } /* --- @name_find@ --- * @@ -444,7 +451,7 @@ void name_dump(void) name *n; trace(TRACE_DEBUG, "name: dumping names"); - for (sym_createIter(&i, &name__table); (n = sym_next(&i)) != 0; ) { + for (sym_mkiter(&i, &name__table); (n = sym_next(&i)) != 0; ) { trace(TRACE_DEBUG, "name: dumping `%s'", n->base.name); if (!n->c) trace(TRACE_DEBUG, "name: "); diff --git a/src/name.h b/src/name.h index fe7c221..666ce3b 100644 --- a/src/name.h +++ b/src/name.h @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: name.h,v 1.6 1998/04/23 13:24:21 mdw Exp $ + * $Id: name.h,v 1.7 2003/10/12 00:14:55 mdw Exp $ * * Looking up of names in symbol tables * @@ -29,6 +29,10 @@ /*----- Revision history --------------------------------------------------* * * $Log: name.h,v $ + * Revision 1.7 2003/10/12 00:14:55 mdw + * Major overhaul. Now uses DSA signatures rather than the bogus symmetric + * encrypt-and-hope thing. Integrated with mLib and Catacomb. + * * Revision 1.6 1998/04/23 13:24:21 mdw * Fix multiple inclusion guard macro name. * @@ -58,14 +62,12 @@ /*----- Required headers --------------------------------------------------*/ +#include + #ifndef CLASS_H # include "class.h" #endif -#ifndef SYM_H -# include "sym.h" -#endif - /*----- Data structures ---------------------------------------------------*/ typedef struct name { diff --git a/src/netg.c b/src/netg.c index c198219..f211389 100644 --- a/src/netg.c +++ b/src/netg.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: netg.c,v 1.4 1998/04/23 13:24:49 mdw Exp $ + * $Id: netg.c,v 1.5 2003/10/12 00:14:55 mdw Exp $ * * A local database of netgroups * @@ -29,6 +29,10 @@ /*----- Revision history --------------------------------------------------* * * $Log: netg.c,v $ + * Revision 1.5 2003/10/12 00:14:55 mdw + * Major overhaul. Now uses DSA signatures rather than the bogus symmetric + * encrypt-and-hope thing. Integrated with mLib and Catacomb. + * * Revision 1.4 1998/04/23 13:24:49 mdw * Switch to using the ypstuff interface to YP server. * @@ -67,14 +71,19 @@ #include #include +/* --- mLib headers --- */ + +#include +#include +#include +#include + /* --- Local headers --- */ #include "become.h" #include "config.h" #include "netg.h" -#include "sym.h" #include "userdb.h" -#include "utils.h" #include "ypstuff.h" /*----- Type definitions --------------------------------------------------*/ @@ -360,7 +369,7 @@ static int netg__foreach(int st, char *k, int ksz, * Use: Dumps the netgroup given. */ -#ifdef TRACING +#ifndef NTRACE static void netg__dumpGroup(netg__cons *c, int lev) { @@ -409,7 +418,7 @@ static void netg__dumpGroup(netg__cons *c, int lev) * Use: Dumps the netgroups table. */ -#ifdef TRACING +#ifndef NTRACE static void netg__dump(void) { @@ -417,7 +426,7 @@ static void netg__dump(void) netg__sym *sng; trace(TRACE_DEBUG, "debug: dumping netgroups file"); - for (sym_createIter(&i, &netg__table); (sng = sym_next(&i)) != 0; ) { + for (sym_mkiter(&i, &netg__table); (sng = sym_next(&i)) != 0; ) { trace(TRACE_DEBUG, "debug: netgroup `%s'...", sng->_base.name); sng->cons->f &= ~f_visit; netg__dumpGroup(sng->cons, 1); @@ -436,7 +445,7 @@ static void netg__dump(void) */ void netg_iterate(void) { netg_iterate_r(&netg__iter); } -void netg_iterate_r(netg_iter *i) { sym_createIter(i, &netg__table); } +void netg_iterate_r(netg_iter *i) { sym_mkiter(i, &netg__table); } /* --- @netg_next@, @netg_next_r@ --- * * @@ -557,7 +566,7 @@ void netg_init(void) { /* --- Initialise my symbol table --- */ - sym_createTable(&netg__table); + sym_create(&netg__table); /* --- Bind myself unto a YP server --- */ @@ -584,7 +593,7 @@ void netg_init(void) netg__cons *c; netg__atom *a; - for (sym_createIter(&i, &netg__table); (sng = sym_next(&i)) != 0; ) { + for (sym_mkiter(&i, &netg__table); (sng = sym_next(&i)) != 0; ) { for (c = sng->cons; c; c = c->cdr) { if ((c->f & f_cons) == 0 && c->car.atom->n) { a = c->car.atom; @@ -609,9 +618,9 @@ void netg_init(void) sym_iter i; netg__sym *sng; - for (sym_createIter(&i, &netg__table); (sng = sym_next(&i)) != 0; ) + for (sym_mkiter(&i, &netg__table); (sng = sym_next(&i)) != 0; ) sng->cons->f &= ~f_uncycled; - for (sym_createIter(&i, &netg__table); (sng = sym_next(&i)) != 0; ) + for (sym_mkiter(&i, &netg__table); (sng = sym_next(&i)) != 0; ) netg__breakCycle(sng->cons); } @@ -637,7 +646,7 @@ void netg_end(void) /* --- Remove all the old netgroups rubbish --- */ - for (sym_createIter(&i, &netg__table); (sng = sym_next(&i)) != 0; ) { + for (sym_mkiter(&i, &netg__table); (sng = sym_next(&i)) != 0; ) { c = sng->cons; while (c) { cc = c->cdr; @@ -654,7 +663,7 @@ void netg_end(void) sym_remove(&netg__table, sng); } - sym_destroyTable(&netg__table); + sym_destroy(&netg__table); } /*----- Test driver -------------------------------------------------------*/ diff --git a/src/netg.h b/src/netg.h index b0207b2..0c34fed 100644 --- a/src/netg.h +++ b/src/netg.h @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: netg.h,v 1.3 1998/01/12 16:46:18 mdw Exp $ + * $Id: netg.h,v 1.4 2003/10/12 00:14:55 mdw Exp $ * * A local database of netgroups * @@ -29,6 +29,10 @@ /*----- Revision history --------------------------------------------------* * * $Log: netg.h,v $ + * Revision 1.4 2003/10/12 00:14:55 mdw + * Major overhaul. Now uses DSA signatures rather than the bogus symmetric + * encrypt-and-hope thing. Integrated with mLib and Catacomb. + * * Revision 1.3 1998/01/12 16:46:18 mdw * Fix copyright date. * @@ -49,9 +53,7 @@ /*----- Required headers --------------------------------------------------*/ -#ifndef SYM_H -# include "sym.h" -#endif +#include /*----- Type definitions --------------------------------------------------*/ diff --git a/src/noise.c b/src/noise.c deleted file mode 100644 index 2945be0..0000000 --- a/src/noise.c +++ /dev/null @@ -1,324 +0,0 @@ -/* -*-c-*- - * - * $Id: noise.c,v 1.6 1998/06/18 15:08:14 mdw Exp $ - * - * Collection of environmental noise - * - * (c) 1998 EBI - */ - -/*----- Licensing notice --------------------------------------------------* - * - * This file is part of `become' - * - * `Become' is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * `Become' is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with `become'; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/*----- Revision history --------------------------------------------------* - * - * $Log: noise.c,v $ - * Revision 1.6 1998/06/18 15:08:14 mdw - * Improve signal handling when accumulating noise from child processes. - * - * Revision 1.5 1998/04/23 13:25:23 mdw - * Try to reduce the amount of `ps'ing done under OSF/1, because /dev/kmem - * seems very slow. - * - * Revision 1.4 1998/02/20 17:52:32 mdw - * Don't use `df' for noise gathering, because it gets upset when NFS - * servers aren't responding. - * - * Revision 1.3 1998/01/12 16:46:19 mdw - * Fix copyright date. - * - * Revision 1.2 1997/08/20 16:19:57 mdw - * Fix test for `/dev/random' so that it doesn't close `stdin' if it fails! - * - * Revision 1.1 1997/08/07 09:45:26 mdw - * New source file added to acquire environmental noise and add it to the - * randomness pool (see `rand.c'). - * - */ - -/*----- Header files ------------------------------------------------------*/ - -/* --- ANSI headers --- */ - -#include -#include -#include -#include -#include -#include -#include - -/* --- Unix headers --- */ - -#include -#include - -#include "config.h" -#if defined(HAVE_GETRUSAGE) -# include -#elif defined(HAVE_VTIMES) -# include -#endif - -#include - -#include -#include - -/* --- Local headers --- */ - -#include "noise.h" -#include "rand.h" -#include "utils.h" - -/*----- Main code ---------------------------------------------------------*/ - -/* --- @noise__shell@ --- * - * - * Arguments: @const char *cmd@ = pointer to a shell command - * - * Returns: --- - * - * Use: Adds the output of the shell command to the randomness pool. - * Some care is taken to do the Right Thing when running setuid. - */ - -static void noise__shell(const char *cmd) -{ - int pfd[2]; - pid_t pid; - -#ifdef HAVE_SIGPROCMASK - sigset_t ob, nb; -#endif - - /* --- Create a pipe for talking to the child --- */ - - if (pipe(pfd)) - return; - - /* --- Sort out the signal handling for the parent --- * - * - * Block @SIGCHLD@ while this is going on. Unlike the standard @system@ - * function, I won't disable @SIGINT@ and @SIGQUIT@. Then, if the user - * stops the child with a terminal signal, the parent (i.e., me) gets - * killed too, and I don't end up with a tiny dribble of entropy when I'm - * expecting quite a lot. - */ - -#ifdef HAVE_SIGPROCMASK - sigemptyset(&nb); - sigaddset(&nb, SIGCHLD); - if (sigprocmask(SIG_BLOCK, &nb, &ob)) - goto fail_0; -#endif - - /* --- Create the child process --- */ - - pid = fork(); - if (pid < 0) - goto fail_1; - - if (pid == 0) { - int fd; - char *argv[] = { "/bin/sh", "-c", 0, 0 }; - char *env[] = { - "PATH=/bin:/usr/bin:/usr/ucb:/usr/etc:/sbin:/usr/sbin", - 0 - }; - - /* --- Restore signal handling things --- */ - -#ifdef HAVE_SIGPROCMASK - sigprocmask(SIG_SETMASK, &nb, 0); -#endif - - /* --- Become nobody --- * - * - * This assumes that @-2@ is a safe user to be. It shouldn't be root, - * because it doesn't need to be, and nothing should be done as root - * which could be done as someone else. It shouldn't be the user who - * invoked me, because that would enable her to kill the children before - * I've read enough entropy from them, and that wouldn't be good. - */ - - setuid(-2); - - /* --- Close the old standard streams --- */ - - close(0); - close(1); - close(2); - - /* --- Set up stdin and stderr to be empty, and stdout as our pipe --- */ - - if (((fd = open("/dev/null", O_RDONLY)) != 0 && - (fd = dup2(fd, 0)) != 0) || - ((fd = dup2(pfd[1], 1)) != 1) || - ((fd = open("/dev/null", O_WRONLY)) != 2 && - (fd = dup2(fd, 2)) != 2)) - goto child_fail; - - /* --- Close the original pipe file descriptors --- */ - - close(pfd[0]); - close(pfd[1]); - burn(pfd); - - /* --- Now run the child process --- */ - - argv[2] = (char *)cmd; /* POSIX screwed up the prototype */ - execve("/bin/sh", argv, env); - - /* --- Something went horribly wrong --- */ - - child_fail: - _exit(127); - } - - /* --- Now read from the child until it's all done --- */ - - { - char buf[1024]; - ssize_t sz; - - close(pfd[1]); - for (;;) { - sz = read(pfd[0], buf, sizeof(buf)); - if (sz == 0 || (sz < 0 && sz != EINTR)) - break; - rand_add(buf, sz); - } - close(pfd[0]); - rand_add(pfd, sizeof(pfd)); - burn(buf); burn(pfd); - } - - /* --- The child should be dead now, so wait for it --- */ - - { - int st; - wait(&st); - rand_add(&st, sizeof(st)); - rand_add(&pid, sizeof(pid)); - } - - /* --- Restore signals --- */ - -fail_1: -#ifdef HAVE_SIGPROCMASK - sigprocmask(SIG_SETMASK, &ob, 0); -#endif -fail_0:; -} - -/* --- @noise_acquire@ --- * - * - * Arguments: --- - * - * Returns: --- - * - * Use: Attempts to acquire an amount of random noise from the - * environment. A lot of it's not actually much good, but - * it's better than nothing. There's probably a bit or two's - * worth in each item which gets added. - */ - -void noise_acquire(void) -{ - /* --- Try a real random number source --- * - * - * Some operating systems (notably Linux) provide a `/dev/random' which - * contains distilled random numbers from the outside world. - */ - - { - int fd; - int f; - unsigned char buff[64]; - ssize_t sz; - - if ((fd = open("/dev/random", O_RDONLY)) >= 0 && - (f = fcntl(fd, F_GETFL, 0)) >= 0 && - fcntl(fd, F_SETFL, f | O_NONBLOCK) >= 0 && - (sz = read(fd, buff, sizeof(buff))) > 0) { - rand_add(buff, sz); - burn(buff); - } - if (fd >= 0) - close(fd); - } - - /* --- Squeeze some entropy from the current time --- */ - - { - struct timeval tv; - clock_t c; - - gettimeofday(&tv, 0); - c = clock(); - rand_add(&tv, sizeof(tv)); - rand_add(&c, sizeof(c)); - burn(tv); burn(c); - } - - /* --- Try some commands which ask the outside world some questions --- */ - - noise__shell("ps auxww || ps -ef; netstat -an"); - - /* --- Get our resource usage to see if that's at all interesting --- */ - -#if defined(HAVE_GETRUSAGE) - { - struct rusage ru; - getrusage(RUSAGE_SELF, &ru); - rand_add(&ru, sizeof(ru)); - getrusage(RUSAGE_CHILDREN, &ru); - rand_add(&ru, sizeof(ru)); - burn(ru); - } -#elif defined(HAVE_VTIMES) - { - struct vtimes vt, vtc; - vtimes(&vt, &vtc); - rand_add(&vt, sizeof(vt)); - rand_add(&vtc, sizeof(vtc)); - burn(vt); burn(vtc); - } -#endif - - /* --- Squeeze some more entropy from the current time --- */ - - { - struct timeval tv; - clock_t c; - - gettimeofday(&tv, 0); - c = clock(); - rand_add(&tv, sizeof(tv)); - rand_add(&c, sizeof(c)); - burn(tv); burn(c); - } - - /* --- Done -- churn the random pool --- */ - - rand_churn(); -} - -/*----- That's all, folks -------------------------------------------------*/ diff --git a/src/noise.h b/src/noise.h deleted file mode 100644 index 171ab2b..0000000 --- a/src/noise.h +++ /dev/null @@ -1,71 +0,0 @@ -/* -*-c-*- - * - * $Id: noise.h,v 1.2 1998/01/12 16:46:20 mdw Exp $ - * - * Collection of environmental noise - * - * (c) 1998 EBI - */ - -/*----- Licensing notice --------------------------------------------------* - * - * This file is part of `become' - * - * `Become' is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * `Become' is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with `become'; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/*----- Revision history --------------------------------------------------* - * - * $Log: noise.h,v $ - * Revision 1.2 1998/01/12 16:46:20 mdw - * Fix copyright date. - * - * Revision 1.1 1997/08/07 09:45:26 mdw - * New source file added to acquire environmental noise and add it to the - * randomness pool (see `rand.c'). - * - */ - -#ifndef NOISE_H -#define NOISE_H - -#ifdef __cplusplus - extern "C" { -#endif - -/*----- Functions provided ------------------------------------------------*/ - -/* --- @noise_acquire@ --- * - * - * Arguments: --- - * - * Returns: --- - * - * Use: Attempts to acquire an amount of random noise from the - * environment. A lot of it's not actually much good, but - * it's better than nothing. There's probably a bit or two's - * worth in each item which gets added. - */ - -extern void noise_acquire(void); - -/*----- That's all, folks -------------------------------------------------*/ - -#ifdef __cplusplus - } -#endif - -#endif - diff --git a/src/parser.y b/src/parser.y index 495dc4a..cd9c1ce 100644 --- a/src/parser.y +++ b/src/parser.y @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: parser.y,v 1.7 1999/03/26 15:25:22 mdw Exp $ + * $Id: parser.y,v 1.8 2003/10/12 00:14:55 mdw Exp $ * * Parser for `become.conf' files * @@ -29,6 +29,10 @@ /*----- Revision history --------------------------------------------------* * * $Log: parser.y,v $ + * Revision 1.8 2003/10/12 00:14:55 mdw + * Major overhaul. Now uses DSA signatures rather than the bogus symmetric + * encrypt-and-hope thing. Integrated with mLib and Catacomb. + * * Revision 1.7 1999/03/26 15:25:22 mdw * Insert some missing semicolons. Bison didn't seem to care, but other * programs like `yyextract' do, so it's worth fixing. @@ -78,6 +82,11 @@ #include #include +/* --- mLib headers --- */ + +#include +#include + /* --- Local headers --- */ #include "class.h" @@ -85,9 +94,7 @@ #include "lexer.h" #include "name.h" #include "rule.h" -#include "sym.h" #include "userdb.h" -#include "utils.h" %} /*----- Stack type --------------------------------------------------------*/ diff --git a/src/rand.c b/src/rand.c deleted file mode 100644 index 08e6181..0000000 --- a/src/rand.c +++ /dev/null @@ -1,296 +0,0 @@ -/* -*-c-*- - * - * $Id: rand.c,v 1.3 1998/01/12 16:46:23 mdw Exp $ - * - * Random number generation - * - * (c) 1998 EBI - */ - -/*----- Licencing notice --------------------------------------------------* - * - * This file is part of Become. - * - * Become is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * Become is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with `become'; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/*----- Revision history --------------------------------------------------* - * - * $Log: rand.c,v $ - * Revision 1.3 1998/01/12 16:46:23 mdw - * Fix copyright date. - * - * Revision 1.2 1997/08/07 09:47:07 mdw - * Fix address of the FSF. - * - * Revision 1.1 1997/08/07 09:46:05 mdw - * New source file added to maintain a randomness pool. - * - */ - -/*----- Header files ------------------------------------------------------*/ - -/* --- ANSI headers --- */ - -#include -#include -#include -#include -#include -#include - -/* --- Local headers --- */ - -#include "become.h" -#include "config.h" -#include "icrypt.h" -#include "md5.h" -#include "rand.h" -#include "tx.h" -#include "utils.h" - -/*----- Magic numbers -----------------------------------------------------*/ - -#define rand__seedBits 512 /* Number of random seed bits */ - -/*----- Persistant state --------------------------------------------------*/ - -static unsigned char rand__pool[rand__seedBits / 8]; /* Entropy pool */ -static size_t rand__i = 0; /* Index into entropy pool */ -static size_t rand__r = 0; /* Rotation to apply to next byte */ - -/*----- Main code ---------------------------------------------------------*/ - -/* --- @rand_read@ --- * - * - * Arguments: @FILE *fp@ = pointer to file to read from - * - * Returns: --- - * - * Use: Reads a random number seed from the stream. - */ - -void rand_read(FILE *fp) -{ - tx_getBits(rand__pool, rand__seedBits, fp); - rand__i = 0; - rand__r = 0; - T( traceblk(TRACE_RAND, "rand: loaded randomness pool", - rand__pool, sizeof(rand__pool)); ) -} - -/* --- @rand_write@ --- * - * - * Arguments: @FILE *fp@ = pointer to file to write on - * - * Returns: --- - * - * Use: Writes a random number seed back to the stream. - */ - -void rand_write(FILE *fp) -{ - rand_churn(); - tx_putBits(rand__pool, rand__seedBits, fp); -} - -/* --- @rand_clear@ --- * - * - * Arguments: --- - * - * Returns: --- - * - * Use: Clears the random number pool. - */ - -void rand_clear(void) -{ - memset(rand__pool, 0, sizeof(rand__pool)); - T( trace(TRACE_RAND, "rand: cleared randomness pool"); ) - rand__i = 0; - rand__r = 0; -} - -/* --- @rand_encrypt@ --- * - * - * Arguments: @icrypt_job *j@ = pointer to an encryption job to apply - * - * Returns: --- - * - * Use: Encrypts the randomness pool with a given key. This should - * be done before use, in case the pool gets compromised. - */ - -void rand_encrypt(icrypt_job *j) -{ - icrypt_encrypt(j, rand__pool, rand__pool, sizeof(rand__pool)); - rand__i = 0; - rand__r = 0; - T( traceblk(TRACE_RAND, "encrypted randomness pool", - rand__pool, sizeof(rand__pool)); ) -} - -/* --- @rand_add@ --- * - * - * Arguments: @const void *p@ = pointer to some data - * @size_t sz@ = size of the data in bytes - * - * Returns: --- - * - * Use: Adds entropy to the pool. - */ - -void rand_add(const void *p, size_t sz) -{ - /* --- Method --- * - * - * Entropy is inserted byte-by-byte. The method used is derived from - * Linux's `drivers/char/random.c', which is in turn appears to be inspired - * by SHA-1. - * - * Imagine the randomness pool as 8 parallel shift registers. To insert - * a byte into the pool, XOR it with bytes picked according to a primitive - * polynomial mod 2, and rotate one place to the left. (The rotation is - * from SHA-1; it introduces some interaction between the registers.) - */ - - size_t i = rand__i; - const unsigned char *cp = p; - size_t mask = (rand__seedBits / 8) - 1; - size_t r = rand__r; - unsigned int x; - - /* --- Ensure the polynomial is valid --- * - * - * The current polynomal is %$x^{64} + x^4 + x^3 + x + 1$% (picked from - * Schneier's excellent book). If the pool size changes, though, I'll - * need another polynomial. - */ - -#if rand__seedBits / 8 != 64 -# error Change the polynomal in rand_add -#endif - - T( traceblk(TRACE_RAND, "rand: incoming entropy", p, sz); ) - - /* --- Add values to the entropy pool --- */ - - while (sz) { - x = *cp++ & 0xffu; - if (r) - x = ((x << r) | (x >> (8 - r))); - x ^= (rand__pool[i] ^ - rand__pool[(i + 1) & mask] ^ - rand__pool[(i + 3) & mask] ^ - rand__pool[(i + 4) & mask]); - rand__pool[i] = ((x << 1) | (x >> 7)) & 0xffu; - sz--; - i = (i + 1) & mask; - r = (r + 3) & 7; - } - - /* --- Update the global counters --- */ - - rand__r = r; - rand__i = i; - - T( traceblk(TRACE_RAND, "rand: added some entropy", - rand__pool, sizeof(rand__pool)); ) -} - -/* --- @rand_extract@ --- * - * - * Arguments: @unsigned char *b@ = pointer to output buffer - * @size_t sz@ = number of bytes wanted - * - * Returns: --- - * - * Use: Produces a number of random bytes. - */ - -void rand_extract(unsigned char *b, size_t sz) -{ - /* --- Method --- * - * - * Hash the buffer with a secure hash (or, in this case, with MD5 and hope - * for the best...). If this gives us enough bytes, fill the output - * buffer; otherwise copy the whole hash out. The contribute the hash back - * into the randomness pool with @rand_add@ to provide some feedback. - * - * The secure hash gives us good mixing over the whole of the randomness - * pool, and attempts to ensure that an attacker receiving our random - * numbers can't predict any numbers we don't actually give him. - */ - - size_t c; - unsigned char mdbuf[MD5_HASHSIZE]; - md5 md; - - T( trace(TRACE_RAND, "rand: extracting entropy"); ) - - while (sz) { - c = (sz >= sizeof(mdbuf)) ? sizeof(mdbuf) : sz; - md5_init(&md); - md5_buffer(&md, rand__pool, sizeof(rand__pool)); - md5_final(&md, mdbuf); - memcpy(b, mdbuf, c); - rand_add(mdbuf, c); - b += c; sz -= c; - } - burn(mdbuf); burn(md); - - T( trace(TRACE_RAND, "rand: finished extracting entropy"); ) -} - -/* --- @rand_churn@ --- * - * - * Arguments: --- - * - * Returns: --- - * - * Use: Churns the randomness pool completely. The pool is replaced - * by repeated MD5-ings of itself. - */ - -void rand_churn(void) -{ - md5 md; - unsigned char mdbuf[MD5_HASHSIZE]; - size_t sz = sizeof(rand__pool); - size_t c; - - T( trace(TRACE_RAND, "rand: churning pool"); ) - - rand__i = 0; - rand__r = 0; - - while (sz) { - c = (sz >= sizeof(mdbuf)) ? sizeof(mdbuf) : sz; - md5_init(&md); - md5_buffer(&md, rand__pool, sizeof(rand__pool)); - md5_final(&md, mdbuf); - rand_add(mdbuf, c); - sz -= c; - } - - rand__i = 0; - rand__r = 0; - - burn(mdbuf); burn(md); - - T( trace(TRACE_RAND, "rand: finished churning pool"); ) -} - -/*----- That's all, folks -------------------------------------------------*/ diff --git a/src/rand.h b/src/rand.h deleted file mode 100644 index cb3d0f9..0000000 --- a/src/rand.h +++ /dev/null @@ -1,144 +0,0 @@ -/* -*-c-*- - * - * $Id: rand.h,v 1.2 1998/01/12 16:46:24 mdw Exp $ - * - * Random number generation - * - * (c) 1998 EBI - */ - -/*----- Licencing notice --------------------------------------------------* - * - * This file is part of Become. - * - * Become is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * Become is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Become; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/*----- Revision history --------------------------------------------------* - * - * $Log: rand.h,v $ - * Revision 1.2 1998/01/12 16:46:24 mdw - * Fix copyright date. - * - * Revision 1.1 1997/08/07 09:46:05 mdw - * New source file added to maintain a randomness pool. - * - */ - -#ifndef RAND_H -#define RAND_H - -#ifdef __cplusplus - extern "C" { -#endif - -/*----- Required headers --------------------------------------------------*/ - -#include - -#ifndef ICRYPT_H -# include "icrypt.h" -#endif - -/*----- Functions provided ------------------------------------------------*/ - -/* --- @rand_read@ --- * - * - * Arguments: @FILE *fp@ = pointer to file to read from - * - * Returns: --- - * - * Use: Reads a random number seed from the stream. - */ - -extern void rand_read(FILE */*fp*/); - -/* --- @rand_write@ --- * - * - * Arguments: @FILE *fp@ = pointer to file to write on - * - * Returns: --- - * - * Use: Writes a random number seed back to the stream. - */ - -extern void rand_write(FILE */*fp*/); - -/* --- @rand_clear@ --- * - * - * Arguments: --- - * - * Returns: --- - * - * Use: Clears the random number pool. - */ - -extern void rand_clear(void); - -/* --- @rand_encrypt@ --- * - * - * Arguments: @icrypt_job *j@ = pointer to an encryption job to apply - * - * Returns: --- - * - * Use: Encrypts the randomness pool with a given key. This should - * be done before use, in case the pool gets compromised. - */ - -extern void rand_encrypt(icrypt_job */*j*/); - -/* --- @rand_add@ --- * - * - * Arguments: @const void *p@ = pointer to some data - * @size_t sz@ = size of the data in bytes - * - * Returns: --- - * - * Use: Adds entropy to the pool. - */ - -extern void rand_add(const void */*p*/, size_t /*sz*/); - -/* --- @rand_extract@ --- * - * - * Arguments: @unsigned char *b@ = pointer to output buffer - * @size_t sz@ = number of bytes wanted - * - * Returns: --- - * - * Use: Produces a number of random bytes. - */ - -extern void rand_extract(unsigned char */*b*/, size_t /*sz*/); - -/* --- @rand_churn@ --- * - * - * Arguments: --- - * - * Returns: --- - * - * Use: Churns the randomness pool completely. The pool is replaced - * by repeated MD5-ings of itself. - */ - -extern void rand_churn(void); - -/*----- That's all, folks -------------------------------------------------*/ - -#ifdef __cplusplus - } -#endif - -#endif diff --git a/src/rule.c b/src/rule.c index 7f1e9f7..166da54 100644 --- a/src/rule.c +++ b/src/rule.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: rule.c,v 1.6 1998/04/23 13:27:31 mdw Exp $ + * $Id: rule.c,v 1.7 2003/10/12 00:14:55 mdw Exp $ * * Managing rule sets * @@ -29,6 +29,10 @@ /*----- Revision history --------------------------------------------------* * * $Log: rule.c,v $ + * Revision 1.7 2003/10/12 00:14:55 mdw + * Major overhaul. Now uses DSA signatures rather than the bogus symmetric + * encrypt-and-hope thing. Integrated with mLib and Catacomb. + * * Revision 1.6 1998/04/23 13:27:31 mdw * Export structure of the rule list, for `bcquery's benefit. * @@ -67,13 +71,18 @@ #include #include +/* --- mLib headers --- */ + +#include +#include +#include + /* --- Local headers --- */ #include "become.h" #include "class.h" #include "rule.h" #include "userdb.h" -#include "utils.h" /*----- Static variables --------------------------------------------------*/ diff --git a/src/sym.c b/src/sym.c deleted file mode 100644 index 99ec187..0000000 --- a/src/sym.c +++ /dev/null @@ -1,707 +0,0 @@ -/* -*-c-*- - * - * $Id: sym.c,v 1.4 1998/01/12 16:46:28 mdw Exp $ - * - * Symbol table management - * - * (c) 1998 Straylight - */ - -/*----- Licensing notice --------------------------------------------------* - * - * This file is part of `become' - * - * `Become' is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * `Become' is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with `become'; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/*----- Revision history --------------------------------------------------* - * - * $Log: sym.c,v $ - * Revision 1.4 1998/01/12 16:46:28 mdw - * Fix copyright date. - * - * Revision 1.3 1997/08/20 16:22:59 mdw - * Patch memory leak. - * - * Revision 1.2 1997/08/04 10:24:25 mdw - * Sources placed under CVS control. - * - * Revision 1.1 1997/07/21 13:47:44 mdw - * Initial revision - * - */ - -/*----- Header files ------------------------------------------------------*/ - -/* --- ANSI headers --- */ - -#include -#include -#include - -/* --- Local headers --- */ - -#include "sym.h" -#include "utils.h" - -/*----- Tuning parameters -------------------------------------------------*/ - -/* --- Initial hash table size --- * - * - * This is the initial @mask@ value. It must be of the form %$2^n - 1$%, - * so that it can be used to mask of the bottom bits of a hash value. - */ - -#define sym__iSize 255 /* Size of a new hash table */ - -/* --- Maximum load factor --- * - * - * This parameter controls how much the table has to be loaded before the - * table is extended. The number of elements %$n$%, the number of bins %$b$% - * and the limit %$l$% satisfy the relation %$n < bl$%; if a new item is - * added to the table and this relation is found to be false, the table is - * doubled in size. - * - * The parameter @sym__limFactor@ is the value of %$l$% multiplied by 256; - * fixed point arithmetic is used to calculate the allowable load. Note - * that the exact calculation of this criterion isn't important; what's more - * significant is that the parameter allows tuning of the rehashing process. - * - * The current value is %$3 \over 4$%, which appears to be reasonable on the - * face of things. - */ - -#define sym__limFactor 0x0C0 /* Load factor for growing table */ - -/*----- CRC table ---------------------------------------------------------*/ - -/*****************************************************************/ -/* */ -/* CRC LOOKUP TABLE */ -/* ================ */ -/* */ -/* The following CRC lookup table was generated automagically */ -/* by `crcgen', which is based on the Rocksoft^tm Model CRC */ -/* Algorithm Table Generation Program. The model parameters */ -/* supplied to `crcgen' were: */ -/* */ -/* Width : 32 bits */ -/* Poly : 0x04C11DB7 */ -/* Init : 0xFFFFFFFF */ -/* XorOut : 0xFFFFFFFF */ -/* Reverse : Yes */ -/* Check : 0xCBF43926 */ -/* */ -/* For more information on the Rocksoft^tm Model CRC Algorithm, */ -/* see the document titled `A Painless Guide to CRC Error */ -/* Detection Algorithms' by Ross Williams */ -/* (ross@@guest.adelaide.edu.au.). This document is likely to be */ -/* in the FTP archive `ftp.adelaide.edu.au/pub/rocksoft'. */ -/* */ -/*****************************************************************/ - -static unsigned long sym__crcTable[256] = { - 0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL, - 0x076DC419L, 0x706AF48FL, 0xE963A535L, 0x9E6495A3L, - 0x0EDB8832L, 0x79DCB8A4L, 0xE0D5E91EL, 0x97D2D988L, - 0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L, 0x90BF1D91L, - 0x1DB71064L, 0x6AB020F2L, 0xF3B97148L, 0x84BE41DEL, - 0x1ADAD47DL, 0x6DDDE4EBL, 0xF4D4B551L, 0x83D385C7L, - 0x136C9856L, 0x646BA8C0L, 0xFD62F97AL, 0x8A65C9ECL, - 0x14015C4FL, 0x63066CD9L, 0xFA0F3D63L, 0x8D080DF5L, - 0x3B6E20C8L, 0x4C69105EL, 0xD56041E4L, 0xA2677172L, - 0x3C03E4D1L, 0x4B04D447L, 0xD20D85FDL, 0xA50AB56BL, - 0x35B5A8FAL, 0x42B2986CL, 0xDBBBC9D6L, 0xACBCF940L, - 0x32D86CE3L, 0x45DF5C75L, 0xDCD60DCFL, 0xABD13D59L, - 0x26D930ACL, 0x51DE003AL, 0xC8D75180L, 0xBFD06116L, - 0x21B4F4B5L, 0x56B3C423L, 0xCFBA9599L, 0xB8BDA50FL, - 0x2802B89EL, 0x5F058808L, 0xC60CD9B2L, 0xB10BE924L, - 0x2F6F7C87L, 0x58684C11L, 0xC1611DABL, 0xB6662D3DL, - 0x76DC4190L, 0x01DB7106L, 0x98D220BCL, 0xEFD5102AL, - 0x71B18589L, 0x06B6B51FL, 0x9FBFE4A5L, 0xE8B8D433L, - 0x7807C9A2L, 0x0F00F934L, 0x9609A88EL, 0xE10E9818L, - 0x7F6A0DBBL, 0x086D3D2DL, 0x91646C97L, 0xE6635C01L, - 0x6B6B51F4L, 0x1C6C6162L, 0x856530D8L, 0xF262004EL, - 0x6C0695EDL, 0x1B01A57BL, 0x8208F4C1L, 0xF50FC457L, - 0x65B0D9C6L, 0x12B7E950L, 0x8BBEB8EAL, 0xFCB9887CL, - 0x62DD1DDFL, 0x15DA2D49L, 0x8CD37CF3L, 0xFBD44C65L, - 0x4DB26158L, 0x3AB551CEL, 0xA3BC0074L, 0xD4BB30E2L, - 0x4ADFA541L, 0x3DD895D7L, 0xA4D1C46DL, 0xD3D6F4FBL, - 0x4369E96AL, 0x346ED9FCL, 0xAD678846L, 0xDA60B8D0L, - 0x44042D73L, 0x33031DE5L, 0xAA0A4C5FL, 0xDD0D7CC9L, - 0x5005713CL, 0x270241AAL, 0xBE0B1010L, 0xC90C2086L, - 0x5768B525L, 0x206F85B3L, 0xB966D409L, 0xCE61E49FL, - 0x5EDEF90EL, 0x29D9C998L, 0xB0D09822L, 0xC7D7A8B4L, - 0x59B33D17L, 0x2EB40D81L, 0xB7BD5C3BL, 0xC0BA6CADL, - 0xEDB88320L, 0x9ABFB3B6L, 0x03B6E20CL, 0x74B1D29AL, - 0xEAD54739L, 0x9DD277AFL, 0x04DB2615L, 0x73DC1683L, - 0xE3630B12L, 0x94643B84L, 0x0D6D6A3EL, 0x7A6A5AA8L, - 0xE40ECF0BL, 0x9309FF9DL, 0x0A00AE27L, 0x7D079EB1L, - 0xF00F9344L, 0x8708A3D2L, 0x1E01F268L, 0x6906C2FEL, - 0xF762575DL, 0x806567CBL, 0x196C3671L, 0x6E6B06E7L, - 0xFED41B76L, 0x89D32BE0L, 0x10DA7A5AL, 0x67DD4ACCL, - 0xF9B9DF6FL, 0x8EBEEFF9L, 0x17B7BE43L, 0x60B08ED5L, - 0xD6D6A3E8L, 0xA1D1937EL, 0x38D8C2C4L, 0x4FDFF252L, - 0xD1BB67F1L, 0xA6BC5767L, 0x3FB506DDL, 0x48B2364BL, - 0xD80D2BDAL, 0xAF0A1B4CL, 0x36034AF6L, 0x41047A60L, - 0xDF60EFC3L, 0xA867DF55L, 0x316E8EEFL, 0x4669BE79L, - 0xCB61B38CL, 0xBC66831AL, 0x256FD2A0L, 0x5268E236L, - 0xCC0C7795L, 0xBB0B4703L, 0x220216B9L, 0x5505262FL, - 0xC5BA3BBEL, 0xB2BD0B28L, 0x2BB45A92L, 0x5CB36A04L, - 0xC2D7FFA7L, 0xB5D0CF31L, 0x2CD99E8BL, 0x5BDEAE1DL, - 0x9B64C2B0L, 0xEC63F226L, 0x756AA39CL, 0x026D930AL, - 0x9C0906A9L, 0xEB0E363FL, 0x72076785L, 0x05005713L, - 0x95BF4A82L, 0xE2B87A14L, 0x7BB12BAEL, 0x0CB61B38L, - 0x92D28E9BL, 0xE5D5BE0DL, 0x7CDCEFB7L, 0x0BDBDF21L, - 0x86D3D2D4L, 0xF1D4E242L, 0x68DDB3F8L, 0x1FDA836EL, - 0x81BE16CDL, 0xF6B9265BL, 0x6FB077E1L, 0x18B74777L, - 0x88085AE6L, 0xFF0F6A70L, 0x66063BCAL, 0x11010B5CL, - 0x8F659EFFL, 0xF862AE69L, 0x616BFFD3L, 0x166CCF45L, - 0xA00AE278L, 0xD70DD2EEL, 0x4E048354L, 0x3903B3C2L, - 0xA7672661L, 0xD06016F7L, 0x4969474DL, 0x3E6E77DBL, - 0xAED16A4AL, 0xD9D65ADCL, 0x40DF0B66L, 0x37D83BF0L, - 0xA9BCAE53L, 0xDEBB9EC5L, 0x47B2CF7FL, 0x30B5FFE9L, - 0xBDBDF21CL, 0xCABAC28AL, 0x53B39330L, 0x24B4A3A6L, - 0xBAD03605L, 0xCDD70693L, 0x54DE5729L, 0x23D967BFL, - 0xB3667A2EL, 0xC4614AB8L, 0x5D681B02L, 0x2A6F2B94L, - 0xB40BBE37L, 0xC30C8EA1L, 0x5A05DF1BL, 0x2D02EF8DL, -}; - -/*****************************************************************/ -/* End of CRC Lookup Table */ -/*****************************************************************/ - -/* --- Work out the CRC of a bytestring --- */ - -#define sym__crc(s_, l_, hv_) do { \ - unsigned long h_ = 0xFFFFFFFFL; \ - const char *p_ = s_; \ - const char *e_ = (s_) + (l_); \ - \ - while (p_ < e_) \ - h_ = (h_ >> 8) ^ (sym__crcTable[(*p_++ ^ h_) & 0xFF]); \ - hv_ = ~h_ & 0xFFFFFFFFL; \ -} while (0) - -/*----- Main code ---------------------------------------------------------*/ - -#ifndef DEBUG_CRC - -/* --- @sym_createTable@ --- * - * - * Arguments: @sym_table *t@ = symbol table to initialise - * - * Returns: --- - * - * Use: Initialises the given symbol table. - */ - -void sym_createTable(sym_table *t) -{ - size_t i; - - t->mask = sym__iSize; - t->c = (sym__iSize * sym__limFactor) >> 8; - t->a = xmalloc((t->mask + 1) * sizeof(sym_base *)); - - for (i = 0; i < sym__iSize + 1; i++) - t->a[i] = 0; -} - -/* --- @sym_destroyTable@ --- * - * - * Arguments: @sym_table *t@ = pointer to symbol table in question - * - * Returns: --- - * - * Use: Destroys a symbol table, freeing all the memory it used to - * occupy. - */ - -void sym_destroyTable(sym_table *t) -{ - size_t i; - sym_base *p, *q; - - for (i = 0; i <= t->mask; i++) { - p = t->a[i]; - while (p) { - q = p->next; - free(p->name); - free(p); - p = q; - } - } - free(t->a); -} - -/* --- @sym_find@ --- * - * - * Arguments: @sym_table *t@ = pointer to symbol table in question - * @const char *n@ = pointer to symbol table to look up - * @long l@ = length of the name string or negative to measure - * @size_t sz@ = size of desired symbol object, or zero - * @unsigned *f@ = pointer to a flag, or null. - * - * Returns: The address of a @sym_base@ structure, or null if not found - * and @sz@ is zero. - * - * Use: Looks up a symbol in a given symbol table. The name is - * passed by the address of its first character. The length - * may be given, in which case the name may contain arbitrary - * binary data, or it may be given as a negative number, in - * which case the length of the name is calculated as - * @strlen(n)@. - * - * The return value is the address of a pointer to a @sym_base@ - * block (which may have other things on the end, as above). If - * the symbol could be found, the return value points to the - * symbol block. If the symbol wasn't there, then if @sz@ is - * nonzero, a new symbol is created and its address is returned; - * otherwise a null pointer is returned. - * - * The value of @*f@ indicates whether a new symbol entry was - * created: a nonzero value indicates that an old value was - * found. - */ - -void *sym_find(sym_table *t, const char *n, long l, size_t sz, unsigned *f) -{ - unsigned long hash; /* Hash value for user's name */ - size_t len = l < 0 ? strlen(n) + 1 : l; /* Find length of user's name */ - sym_base *bin; /* Bin containing our item */ - sym_base *p, *q; /* Pointer wandering through list */ - - /* --- Find the correct bin --- */ - - sym__crc(n, len, hash); /* Find hash value for this name */ - bin = p = (sym_base *)(t->a + (hash & t->mask)); - - /* --- Search the bin list --- */ - - while (p->next) { - if (hash == p->next->hash && /* Check hash values first */ - len == p->next->len && /* Then compare string lengths */ - !memcmp(n, p->next->name, len)) /* And finally compare the strings */ - { - /* --- Found a match --- * - * - * As a minor, and probably pointless, tweak, move the item to the - * front of its bin list. - */ - - q = p->next; /* Find the actual symbol block */ - p->next = q->next; /* Extract block from bin list */ - q->next = bin->next; /* Set up symbol's next pointer */ - bin->next = q; /* And reinsert the block */ - - /* --- Return the block --- */ - - if (f) *f = 1; /* Didn't fail to find the item */ - return (q); /* And return the block */ - } - - p = p->next; /* Move onto the next item */ - } - - /* --- Couldn't find the item there --- */ - - if (f) *f = 0; /* Failed to find the block */ - if (!sz) return (0); /* Return zero if not creating */ - - /* --- Create a new symbol block and initialise it --- */ - - p = xmalloc(sz); /* Create a new symbol block */ - p->next = bin->next; /* Set up the next pointer */ - p->hash = hash; /* Set up the hash value too */ - p->name = xmalloc(len); /* Allocate a block for the name */ - p->len = len; /* And set up the string length */ - memcpy(p->name, n, len); /* And copy the string over */ - - bin->next = p; /* Put the pointer into the bin */ - - /* --- Consider growing the array --- */ - - if (!--t->c) { - unsigned long m = t->mask + 1; /* Next set bit in has word */ - sym_base *p, *q, *r; /* More useful pointers */ - size_t i, lim; /* Loop counter and limit */ - - /* --- Update values in the anchor block --- */ - - t->c = ((t->mask + 1) * sym__limFactor) >> 8; /* Set load value */ - t->mask = (t->mask + 1) * 2 - 1; /* Set the new mask value */ - t->a = xrealloc(t->a, (t->mask + 1) * sizeof(sym_base *)); - - /* --- Now wander through the table rehashing things --- * - * - * This loop is very careful to avoid problems with aliasing. The items - * are dealt with from the end backwards to avoid overwriting bins before - * they've been processed. - */ - - lim = (t->mask + 1) >> 1; - for (i = 0; i < lim; i++) { - /* --- Some initialisation --- */ - - r = t->a[i]; /* Find the list we're dissecting */ - p = (sym_base *)(t->a + i); /* Find bit-clear list */ - q = (sym_base *)(t->a + i + lim); /* And the bit-set lsit */ - - /* --- Now go through the @r@ list --- */ - - while (r) { - if (r->hash & m) /* Is the next bit set? */ - q = q->next = r; /* Yes, so fit up previous link */ - else - p = p->next = r; /* No, so fit up previous link */ - r = r->next; /* Move onto the next item */ - } - p->next = q->next = 0; /* Null terminate the new lists */ - } - } - - /* --- Finished that, so return the new symbol block --- */ - - return (p); -} - -/* --- @sym_remove@ --- * - * - * Arguments: @sym_table *i@ = pointer to a symbol table object - * @void *b@ = pointer to symbol table entry - * - * Returns: --- - * - * Use: Removes the object from the symbol table. The space occupied - * by the object and its name is freed; anything else attached - * to the entry should already be gone by this point. - */ - -void sym_remove(sym_table *t, void *b) -{ - /* --- A quick comment --- * - * - * Since the @sym_base@ block contains the hash, finding the element in the - * bin list is really quick -- it's not worth bothering with things like - * doubly linked lists. - */ - - sym_base *p = b; - sym_base *bin = (sym_base *)(t->a + (p->hash & t->mask)); - - /* --- Find the item in the bin list --- */ - - while (bin->next) { - if (bin->next == p) - break; - bin = bin->next; - } - if (!bin->next) - return; - - /* --- Now just remove the item from the list and free it --- * - * - * Oh, and bump the load counter. - */ - - bin->next = p->next; - free(p->name); - free(p); - t->c++; -} - -/* --- @sym_createIter@ --- * - * - * Arguments: @sym_iter *i@ = pointer to an iterator object - * @sym_table *t@ = pointer to a symbol table object - * - * Returns: --- - * - * Use: Creates a new symbol table iterator which may be used to - * iterate through a symbol table. - */ - -void sym_createIter(sym_iter *i, sym_table *t) -{ - i->t = t; - i->i = 0; - i->n = 0; -} - -/* --- @sym_next@ --- * - * - * Arguments: @sym_iter *i@ = pointer to iterator object - * - * Returns: Pointer to the next symbol found, or null when finished. - * - * Use: Returns the next symbol from the table. Symbols are not - * returned in any particular order. - */ - -void *sym_next(sym_iter *i) -{ - sym_base *p; - - /* --- Find the next item --- */ - - while (!i->n) { - if (i->i > i->t->mask) - return (0); - i->n = i->t->a[i->i++]; - } - - /* --- Update the iterator block --- */ - - p = i->n; - i->n = p->next; - - /* --- Done --- */ - - return (p); -} - -#endif - -/*----- CRC test code -----------------------------------------------------*/ - -#ifdef DEBUG_CRC - -int main(void) -{ - unsigned long h; - sym__crc("123456789", 9, h); - printf("crc check == %04x\n", h); - return (0); -} - -#endif - -/*----- Symbol table test code --------------------------------------------*/ - -#ifdef TEST_RIG - -#include -#include - -#include "dbutils.h" - -typedef struct sym_word { - sym_base base; - size_t i; -} sym_word; - - -/* --- What it does --- * - * - * Reads the file /usr/dict/words (change to some other file full of - * interesting and appropriate bits of text to taste) into a big buffer and - * picks apart into lines. Then picks lines at random and enters them into - * the symbol table. - */ - -int main(void) -{ - char *buff, *p, *lim; - size_t sz, done; - FILE *fp; - int i; - char **line; - sym_word **flag; - sym_table tbl; - int entries; - - /* --- Initialise for reading the file --- */ - - sz = BUFSIZ; - buff = xmalloc(sz + 1); - done = 0; - - if ((fp = fopen("/usr/dict/words", "r")) == 0) - fprintf(stderr, "buggered ;-( (%s)\n", strerror(errno)); - - /* --- Read buffers of text --- * - * - * Read a buffer. If more to come, double the buffer size and try again. - * This is the method I recommended to comp.lang.c, so I may as well try - * it. - */ - - for (;;) { - i = fread(buff + done, 1, sz - done, fp); - done += i; - if (done != sz) - break; - sz <<= 1; - buff = xrealloc(buff, sz + 1); - } - - /* --- Count the lines --- */ - - lim = buff + done; - - sz = 1; - for (p = buff; p < lim; p++) - if (*p == '\n') sz++; - - /* --- Build a table of line starts --- */ - - line = xmalloc(sz * sizeof(char *)); - i = 0; - line[i++] = buff; - for (p = buff; p < lim; p++) - if (*p == '\n') *p = 0, line[i++] = p + 1; - *lim = 0; - - /* --- Build a table of lines --- * - * - * This reverses the mapping which the symbol table performs, so that its - * accuracy can be tested. - */ - - flag = xmalloc(sz * sizeof(sym_word *)); - for (i = 0; i < sz; i++) - flag[i] = 0; - entries = 0; - - sym_createTable(&tbl); - - for (;;) { - i = (unsigned)rand() % sz; - - switch (rand() % 5) - { - case 0: { - sym_word *w; - - /* printf("find `%s'\n", line[i]); */ - if ((rand() & 1023) == 0) { - putchar('.'); fflush(stdout); - } - - w = sym_find(&tbl, line[i], -1, 0, 0); - if (w != flag[i]) - printf("*** error: find `%s' gave %p not %p\n", - line[i], (void *)w, (void *)flag[i]); - else if (w && w->i != i) - printf("*** error: find sym for `%s' gives index %i not %i\n", - line[i], w->i, i); - } break; - - case 1: { - unsigned f; - sym_word *w; - - /* printf("create `%s'\n", line[i]); */ - if ((rand() & 1023) == 0) { - putchar('+'); fflush(stdout); - } - - w = sym_find(&tbl, line[i], -1, sizeof(sym_word), &f); - if (f) - { - if (w != flag[i]) - printf("*** error: create `%s' gave %p not %p\n", - line[i], (void *)w, (void *)flag[i]); - else if (w && w->i != i) - printf("*** error: create sym for `%s' gives index %i not %i\n", - line[i], w->i, i); - } - else - { - if (flag[i]) - printf("*** error: create `%s' gave new block, should be %p\n", - line[i], (void *)flag[i]); - else { - flag[i] = w; - w->i = i; - entries++; - } - } - } break; - - case 2: { - sym_iter it; - sym_word *w, **ntbl; - int v = (rand() % entries) == 0; - if (!v) - break; - printf("\niterated %i entries\n", entries); - break; - - printf("iterate\n"); - - ntbl = xmalloc(sz * sizeof(sym_word *)); - memcpy(ntbl, flag, sz * sizeof(sym_word *)); - sym_createIter(&it, &tbl); - - while ((w = sym_next(&it)) != 0) { - if (ntbl[w->i] == 0) - printf("*** error: iterate returned duff item %i\n", w->i); - else - ntbl[w->i] = 0; - } - - for (i = 0; i < sz; i++) - if (ntbl[i]) printf("*** error: iterate didn't return item %i\n", - i); - free(ntbl); - } break; - - case 3: { - sym_base *b; - int v = rand() & 255 ? 0 : 1; - break; - - printf("dump\n"); - - for (i = 0; i <= tbl.mask; i++) { - if (!tbl.a[i]) continue; - if (v) printf(" %i: ", i); - b = tbl.a[i]; - while (b) { - if ((b->hash & tbl.mask) != i) - printf("*** error: bad hash value found"); - if (v) printf("`%s'(%08lx:%lu) ", - line[((sym_word *)b)->i], - b->hash, - b->hash & tbl.mask); - b = b->next; - } - if (v) putchar('\n'); - } - } break; - - case 4: { - if (flag[i]) { - /* printf("remove `%s'\n", flag[i]->base.name); */ - if ((rand() & 1023) == 0) { - putchar('-'); fflush(stdout); - } - sym_remove(&tbl, flag[i]); - flag[i] = 0; - entries--; - } - } break; - } - - } - - return (0); -} - -#endif - -/*----- That's all, folks -------------------------------------------------*/ diff --git a/src/sym.h b/src/sym.h deleted file mode 100644 index f8201fd..0000000 --- a/src/sym.h +++ /dev/null @@ -1,196 +0,0 @@ -/* -*-c-*- - * - * $Id: sym.h,v 1.3 1998/01/12 16:46:30 mdw Exp $ - * - * Symbol table management - * - * (c) 1998 Straylight - */ - -/*----- Licensing notice --------------------------------------------------* - * - * This file is part of `become' - * - * `Become' is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * `Become' is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with `become'; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/*----- Revision history --------------------------------------------------* - * - * $Log: sym.h,v $ - * Revision 1.3 1998/01/12 16:46:30 mdw - * Fix copyright date. - * - * Revision 1.2 1997/08/04 10:24:25 mdw - * Sources placed under CVS control. - * - * Revision 1.1 1997/07/21 13:47:43 mdw - * Initial revision - * - */ - -#ifndef SYM_H -#define SYM_H - -#ifdef __cplusplus - extern "C" { -#endif - -/*----- Required headers --------------------------------------------------*/ - -#include - -/*----- Type definitions --------------------------------------------------*/ - -/* --- Symbol table --- * - * - * A @sym_table@ contains the information needed to manage a symbol table. - * Users shouldn't fiddle with this information directly, but it needs to be - * here so that objects of the correct type can be created. - */ - -typedef struct sym_table { - unsigned long mask; /* Bit mask for hashing purposes */ - size_t c; /* Down counter for growing table */ - struct sym_base **a; /* Array of hash bins */ -} sym_table; - -/* --- A symbol table entry --- * - * - * I don't care what actually gets stored in symbol entries because I don't - * create them: that's the responsibility of my client. All I care about - * here is that whatever gets passed to me is a structure whose first member - * is a @sym_base@. The ANSI guarantees about structure layout are - * sufficient to allow me to manipulate such objects. - */ - -typedef struct sym_base { - struct sym_base *next; /* Next symbol in hash bin */ - unsigned long hash; /* Hash value for symbol's name */ - char *name; /* Name of this symbol */ - size_t len; /* Length of the symbol's name */ -} sym_base; - -/* --- An iterator block --- */ - -typedef struct sym_iter { - sym_table *t; /* Symbol table being iterated */ - sym_base *n; /* Address of next item to return */ - size_t i; /* Index of next hash bin to use */ -} sym_iter; - -/*----- External functions ------------------------------------------------*/ - -/* --- @sym_createTable@ --- * - * - * Arguments: @sym_table *t@ = symbol table to initialise - * - * Returns: --- - * - * Use: Initialises the given symbol table. - */ - -extern void sym_createTable(sym_table */*t*/); - -/* --- @sym_destroyTable@ --- * - * - * Arguments: @sym_table *t@ = pointer to symbol table in question - * - * Returns: --- - * - * Use: Destroys a symbol table, freeing all the memory it used to - * occupy. - */ - -extern void sym_destroyTable(sym_table */*t*/); - -/* --- @sym_find@ --- * - * - * Arguments: @sym_table *t@ = pointer to symbol table in question - * @const char *n@ = pointer to symbol table to look up - * @long l@ = length of the name string or negative to measure - * @size_t sz@ = size of desired symbol object, or zero - * @unsigned *f@ = pointer to a flag, or null. - * - * Returns: The address of a @sym_base@ structure, or null if not found - * and @sz@ is zero. - * - * Use: Looks up a symbol in a given symbol table. The name is - * passed by the address of its first character. The length - * may be given, in which case the name may contain arbitrary - * binary data, or it may be given as a negative number, in - * which case the length of the name is calculated as - * @strlen(n)@. - * - * The return value is the address of a pointer to a @sym_base@ - * block (which may have other things on the end, as above). If - * the symbol could be found, the return value points to the - * symbol block. If the symbol wasn't there, then if @sz@ is - * nonzero, a new symbol is created and its address is returned; - * otherwise a null pointer is returned. - * - * The value of @*f@ indicates whether a new symbol entry was - * created: a nonzero value indicates that an old value was - * found. - */ - -extern void *sym_find(sym_table */*t*/, const char */*n*/, long /*l*/, - size_t /*sz*/, unsigned */*f*/); - -/* --- @sym_remove@ --- * - * - * Arguments: @sym_table *i@ = pointer to a symbol table object - * @void *b@ = pointer to symbol table entry - * - * Returns: --- - * - * Use: Removes the object from the symbol table. The space occupied - * by the object and its name is freed; anything else attached - * to the entry should already be gone by this point. - */ - -extern void sym_remove(sym_table */*t*/, void */*b*/); - -/* --- @sym_createIter@ --- * - * - * Arguments: @sym_iter *i@ = pointer to an iterator object - * @sym_table *t@ = pointer to a symbol table object - * - * Returns: --- - * - * Use: Creates a new symbol table iterator which may be used to - * iterate through a symbol table. - */ - -extern void sym_createIter(sym_iter */*i*/, sym_table */*t*/); - -/* --- @sym_next@ --- * - * - * Arguments: @sym_iter *i@ = pointer to iterator object - * - * Returns: Pointer to the next symbol found, or null when finished. - * - * Use: Returns the next symbol from the table. Symbols are not - * returned in any particular order. - */ - -extern void *sym_next(sym_iter */*i*/); - -/*----- That's all, folks -------------------------------------------------*/ - -#ifdef __cplusplus - } -#endif - -#endif diff --git a/src/tx.c b/src/tx.c deleted file mode 100644 index 281902f..0000000 --- a/src/tx.c +++ /dev/null @@ -1,184 +0,0 @@ -/* -*-c-*- - * - * $Id: tx.c,v 1.3 1998/01/12 16:46:31 mdw Exp $ - * - * Transfer for keys and other large integers - * - * (c) 1998 Mark Wooding - */ - -/*----- Licensing notice --------------------------------------------------* - * - * This file is part of `become' - * - * `Become' is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * `Become' is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with `become'; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/*----- Revision history --------------------------------------------------* - * - * $Log: tx.c,v $ - * Revision 1.3 1998/01/12 16:46:31 mdw - * Fix copyright date. - * - * Revision 1.2 1997/08/04 10:24:25 mdw - * Sources placed under CVS control. - * - * Revision 1.1 1997/07/21 13:47:43 mdw - * Initial revision - * - */ - -/*----- Header files ------------------------------------------------------*/ - -/* --- ANSI headers --- */ - -#include -#include -#include -#include - -/* --- Local headers --- */ - -#include "config.h" -#include "tx.h" - -/*----- Main code ---------------------------------------------------------*/ - -/* --- @tx_getBits@ --- * - * - * Arguments: @unsigned char *k@ = pointer to key array to unpack into - * @size_t sz@ = number of bits to read (elements in array) - * @FILE *fp@ = stream to read from - * - * Returns: --- - * - * Use: Reads a number of bits into an array. The least significant - * bits of the final word are cleared to zero. - */ - -void tx_getBits(unsigned char *k, size_t sz, FILE *fp) -{ - int i = 0; - unsigned char a = 0; - unsigned int ch; - size_t wsz = (size_t)((sz + 7ul) & ~7ul); - int t; - - while ((t = getc(fp)) != EOF) { - - /* --- Allow separators for readbility --- */ - - if (t == '-') - continue; - - /* --- Standard converting-from-hex-digit code --- * - * - * Assumes that 'a'--'f' and 'A'--'F' are contiguous and in order, in - * addition to the guarantee that '0'--'9' are like this. The assumption - * is true in ASCII (and character sets based thereon) and EBCDIC. - */ - - ch = (unsigned)t; - ch -= '0'; - if (ch > 9) ch -= 'A' - '0' - 10; - if (ch > 15) ch -= 'a' - 'A'; - if (ch > 15) break; - - /* --- Accumulate and maybe store --- */ - - a = (a << 4) | ch; - i++; - sz -= 4, wsz -= 4; - if ((i & 1) == 0) - *k++ = a, a = 0; - if (!sz) - break; - } - - /* --- Pad the rest out with zeros --- */ - - while (wsz) { - a <<= 4; - i++; - wsz -= 4; - if ((i & 1) == 0) - *k++ = a, a = 0; - } -} - -/* --- @tx_putBits@ --- * - * - * Arguments: @unsigned char *k@ = pointer to key block - * @size_t sz@ = number of bits to write - * @FILE *fp@ = pointer to stream to write on - * - * Returns: --- - * - * Use: Complements @tx_getBits@ above. Writes a number of bits - * to a file in an easy-to-read and transportable format (hex!) - */ - -void tx_putBits(unsigned char *k, size_t sz, FILE *fp) -{ - const static char hex[16] = "0123456789abcdef"; - size_t dash; - size_t d; - unsigned char i; - - /* --- Don't do anything unless we have to --- */ - - if (!sz) - return; - - /* --- Now decide where to `dash' the output --- */ - - if (sz % 32 == 0) - dash = 4; - else if (sz % 40 == 0) - dash = 5; - else - dash = 0; - - /* --- Start writing values out --- */ - - d = dash; - - for (;;) { - - /* --- Write next byte out --- */ - - i = *k++; - putc(hex[(i >> 4) & 0x0fu], fp); - putc(hex[(i >> 0) & 0x0fu], fp); - - /* --- If done, stop now --- */ - - if (sz -= 8, sz == 0) - break; - - /* --- If need a dash, print one --- */ - - if (!--d) { - putc('-', fp); - d = dash; - } - } - - /* --- Print the final newline --- */ - - fputc('\n', fp); -} - -/*----- That's all, folks -------------------------------------------------*/ diff --git a/src/tx.h b/src/tx.h deleted file mode 100644 index 0bfcffc..0000000 --- a/src/tx.h +++ /dev/null @@ -1,90 +0,0 @@ -/* -*-c-*- - * - * $Id: tx.h,v 1.3 1998/01/12 16:46:32 mdw Exp $ - * - * Transfer for keys and other large integers - * - * (c) 1998 Mark Wooding - */ - -/*----- Licensing notice --------------------------------------------------* - * - * This file is part of `become' - * - * `Become' is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * `Become' is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with `become'; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/*----- Revision history --------------------------------------------------* - * - * $Log: tx.h,v $ - * Revision 1.3 1998/01/12 16:46:32 mdw - * Fix copyright date. - * - * Revision 1.2 1997/08/04 10:24:26 mdw - * Sources placed under CVS control. - * - * Revision 1.1 1997/07/21 13:47:43 mdw - * Initial revision - * - */ - -#ifndef TX_H -#define TX_H - -#ifdef __cplusplus - extern "C" { -#endif - -/*----- Required headers --------------------------------------------------*/ - -#include - -/*----- Functions provided ------------------------------------------------*/ - -/* --- @tx_getBits@ --- * - * - * Arguments: @unsigned char *k@ = pointer to key array to unpack into - * @size_t sz@ = number of bits to read (elements in array) - * @FILE *fp@ = stream to read from - * - * Returns: --- - * - * Use: Reads a number of bits into an array. The least significant - * bits of the final word are cleared to zero. - */ - -extern void tx_getBits(unsigned char */*k*/, size_t /*sz*/, FILE */*fp*/); - -/* --- @tx_putBits@ --- * - * - * Arguments: @unsigned char *k@ = pointer to key block - * @size_t sz@ = number of bits to write - * @FILE *fp@ = pointer to stream to write on - * - * Returns: --- - * - * Use: Complements @tx_getBits@ above. Writes a number of bits - * to a file in an easy-to-read and transportable format (hex!) - */ - -extern void tx_putBits(unsigned char */*k*/, size_t /*sz*/, FILE */*fp*/); - -/*----- That's all, folks -------------------------------------------------*/ - -#ifdef __cplusplus - } -#endif - -#endif diff --git a/src/userdb.c b/src/userdb.c index 9151b70..88b1cce 100644 --- a/src/userdb.c +++ b/src/userdb.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: userdb.c,v 1.8 1998/06/08 11:21:22 mdw Exp $ + * $Id: userdb.c,v 1.9 2003/10/12 00:14:55 mdw Exp $ * * User database management * @@ -29,6 +29,10 @@ /*----- Revision history --------------------------------------------------* * * $Log: userdb.c,v $ + * Revision 1.9 2003/10/12 00:14:55 mdw + * Major overhaul. Now uses DSA signatures rather than the bogus symmetric + * encrypt-and-hope thing. Integrated with mLib and Catacomb. + * * Revision 1.8 1998/06/08 11:21:22 mdw * Fixed bug in password and group file reading: strtok doesn't handle * double colons nicely. @@ -79,12 +83,16 @@ #include #include +/* --- mLib headers --- */ + +#include +#include +#include + /* --- Local headers --- */ #include "become.h" -#include "sym.h" #include "userdb.h" -#include "utils.h" #include "ypstuff.h" /*----- Type definitions --------------------------------------------------*/ @@ -131,8 +139,8 @@ static sym_iter userdb__groupi; /* Iterator for groups */ static void userdb__createMap(userdb__map *m) { - sym_createTable(&m->nmap); - sym_createTable(&m->idmap); + sym_create(&m->nmap); + sym_create(&m->idmap); m->list = 0; } @@ -217,8 +225,8 @@ static void userdb__clearMap(userdb__map *m, void (*freerec)(void *rec)) { userdb__node *n, *t; - sym_destroyTable(&m->nmap); - sym_destroyTable(&m->idmap); + sym_destroy(&m->nmap); + sym_destroy(&m->idmap); for (n = m->list; n; n = t) { t = n->next; @@ -238,7 +246,7 @@ static void userdb__clearMap(userdb__map *m, void (*freerec)(void *rec)) * Use: Writes a user's informationt to a stream. */ -#ifdef TRACING +#ifndef NTRACE static void userdb__dumpUser(const struct passwd *pw) { @@ -382,7 +390,7 @@ void userdb_freeUser(void *rec) * Use: Writes a group's information to a stream. */ -#ifdef TRACING +#ifndef NTRACE static void userdb__dumpGroup(const struct group *gr) { @@ -544,7 +552,7 @@ void userdb_iterateUsers(void) { userdb_iterateUsers_r(&userdb__useri); } void userdb_iterateUsers_r(userdb_iter *i) -{ sym_createIter(i, &userdb__users.nmap); } +{ sym_mkiter(i, &userdb__users.nmap); } /* --- @userdb_nextUser@, @userdb_nextUser_r@ --- * * @@ -593,7 +601,7 @@ void userdb_iterateGroups(void) { userdb_iterateGroups_r(&userdb__groupi); } void userdb_iterateGroups_r(userdb_iter *i) -{ sym_createIter(i, &userdb__groups.nmap); } +{ sym_mkiter(i, &userdb__groups.nmap); } /* --- @userdb_nextGroup@, @userdb_nextGroup_r@ --- * * diff --git a/src/userdb.h b/src/userdb.h index d04c13c..1ad0518 100644 --- a/src/userdb.h +++ b/src/userdb.h @@ -29,6 +29,10 @@ /*----- Revision history --------------------------------------------------* * * $Log: userdb.h,v $ + * Revision 1.5 2003/10/12 00:14:55 mdw + * Major overhaul. Now uses DSA signatures rather than the bogus symmetric + * encrypt-and-hope thing. Integrated with mLib and Catacomb. + * * Revision 1.4 1998/01/12 16:46:38 mdw * Fix copyright date. * @@ -55,9 +59,7 @@ #include #include -#ifndef SYM_H -# include "sym.h" -#endif +#include /*----- Type definitions --------------------------------------------------*/ diff --git a/src/utils.c b/src/utils.c deleted file mode 100644 index c6e1313..0000000 --- a/src/utils.c +++ /dev/null @@ -1,513 +0,0 @@ -/* -*-c-*- - * - * $Id: utils.c,v 1.6 1998/01/12 16:46:47 mdw Exp $ - * - * Miscellaneous useful bits of code. - * - * (c) 1998 Mark Wooding - */ - -/*----- Licensing notice --------------------------------------------------* - * - * This file is part of `become' - * - * `Become' is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * `Become' is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with `become'; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/*----- Revision history --------------------------------------------------* - * - * $Log: utils.c,v $ - * Revision 1.6 1998/01/12 16:46:47 mdw - * Fix copyright date. - * - * Revision 1.5 1997/09/17 10:24:47 mdw - * Flush output before and after writing memory tracking information. - * - * Revision 1.4 1997/09/08 13:43:54 mdw - * Flush tracedump file after each `interesting' write. - * - * Revision 1.3 1997/08/20 16:25:37 mdw - * Add some simple `malloc' tracking. - * - * Revision 1.2 1997/08/04 10:24:26 mdw - * Sources placed under CVS control. - * - * Revision 1.1 1997/07/21 13:47:42 mdw - * Initial revision - * - */ - -/*----- Header files ------------------------------------------------------*/ - -/* --- ANSI headers --- */ - -#include -#include -#include -#include -#include - -/* --- Local headers --- */ - -#include "config.h" -#include "utils.h" - -/*----- Program name handling ---------------------------------------------*/ - -/* --- Static data --- */ - -static const char *myname = 0; /* What's my name? */ - -/* --- @quis@ --- * - * - * Arguments: --- - * - * Returns: Pointer to the program name. - * - * Use: Returns the program name. - */ - -const char *quis(void) -{ - return (myname); -} - -/* --- @ego@ --- * - * - * Arguments: @const char *p@ = pointer to program name - * - * Returns: --- - * - * Use: Tells the utils library what the program's name is. - */ - -#ifndef PATHSEP -# if defined(__riscos) -# define PATHSEP '.' -# elif defined(__unix) || defined(unix) -# define PATHSEP '/' -# else -# define PATHSEP '\\' -# endif -#endif - -void ego(const char *p) -{ - const char *q = p; - while (*q) { - if (*q++ == PATHSEP) - p = q; - } - myname = p; -} - -/*----- Error reporting ---------------------------------------------------*/ - -/* --- @moan@ --- * - * - * Arguments: @const char *f@ = a @printf@-style format string - * @...@ = other arguments - * - * Returns: --- - * - * Use: Reports an error. - */ - -void moan(const char *f, ...) -{ - va_list ap; - va_start(ap, f); - fprintf(stderr, "%s: ", myname); - vfprintf(stderr, f, ap); - va_end(ap); - putc('\n', stderr); -} - -/* --- @die@ --- * - * - * Arguments: @const char *f@ = a @printf@-style format string - * @...@ = other arguments - * - * Returns: Never. - * - * Use: Reports an error and hari-kiris. Like @moan@ above, only - * more permanent. - */ - -void die(const char *f, ...) -{ - va_list ap; - va_start(ap, f); - fprintf(stderr, "%s: ", myname); - vfprintf(stderr, f, ap); - va_end(ap); - putc('\n', stderr); - exit(EXIT_FAILURE); -} - -/*----- Trace messages ----------------------------------------------------*/ - -#if defined(TRACING) || !defined(NDEBUG) - -/* --- Static data --- */ - -static FILE *tracefp = 0; /* Where does debugging go? */ -static unsigned int tracelvl = 0; /* How much tracing gets done? */ - -/* --- @trace@ --- * - * - * Arguments: @unsigned int lvl@ = trace level for output - * @const char *f@ = a @printf@-style format string - * @...@ = other arguments - * - * Returns: --- - * - * Use: Reports a message to the trace output. - */ - -void trace(unsigned int lvl, const char *f, ...) -{ - va_list ap; - if ((lvl & tracing()) == 0) - return; - va_start(ap, f); - fprintf(tracefp, "*** %s: ", myname); - vfprintf(tracefp, f, ap); - va_end(ap); - putc('\n', tracefp); - fflush(tracefp); -} - -/* --- @traceblk@ --- * - * - * Arguments: @unsigned int lvl@ = trace level for output - * @const char *hdr@ = some header string to write - * @const void *blk@ = pointer to a block of memory to dump - * @size_t sz@ = size of the block of memory - * - * Returns: --- - * - * Use: Dumps the contents of a block to the trace output. - */ - -void traceblk(unsigned int lvl, const char *hdr, const void *blk, size_t sz) -{ - const unsigned char *p = blk; - size_t i; - unsigned long o = 0; - size_t c; - - /* --- Skip if the trace level is too high --- */ - - if ((lvl & tracing()) == 0) - return; - - /* --- Now start work --- */ - - fprintf(tracefp, "*** %s: %s\n", myname, hdr); - - while (sz) { - fprintf(tracefp, "*** %s: %08lu : ", myname, o); - for (i = 0; i < 8; i++) { - if (i < sz) - fprintf(tracefp, "%02x ", p[i]); - else - fputs("** ", tracefp); - } - fputs(": ", tracefp); - for (i = 0; i < 8; i++) { - if (i < sz) - fputc(isprint(p[i]) ? p[i] : '.', tracefp); - else - fputc('*', tracefp); - } - fputc('\n', tracefp); - c = (sz >= 8) ? 8 : sz; - sz -= c, p += c, o += c; - } - fflush(tracefp); -} - -/* --- @traceon@ --- * - * - * Arguments: @FILE *fp@ = a file to trace on - * @unsigned int lvl@ = trace level to set - * - * Returns: --- - * - * Use: Enables tracing to a file. - */ - -void traceon(FILE *fp, unsigned int lvl) -{ - tracefp = fp; - if (!tracelvl) - tracelvl = lvl; -} - -/* --- @tracesetlvl@ --- * - * - * Arguments: @unsigned int lvl@ = trace level to set - * - * Returns: --- - * - * Use: Sets the tracing level. - */ - -void tracesetlvl(unsigned int lvl) { tracelvl = lvl; } - -/* --- @tracing@ --- * - * - * Arguments: --- - * - * Returns: Zero if not tracing, tracing level if tracing. - * - * Use: Informs the caller whether tracing is enabled. - */ - -unsigned int tracing(void) { return (tracefp ? tracelvl : 0u); } - -#endif - -/*----- Memory management functions ---------------------------------------*/ - -/* --- @xmalloc@ --- * - * - * Arguments: @size_t sz@ = size of block to allocate - * - * Returns: Pointer to allocated block. - * - * Use: Allocates memory. If the memory isn't available, we don't - * hang aroung long enough for a normal function return. - */ - -void *xmalloc(size_t sz) -{ - void *p = malloc(sz); - if (!p) - die("not enough memory"); - return (p); -} - -/* --- @xstrdup@ --- * - * - * Arguments: @const char *s@ = pointer to a string - * - * Returns: Pointer to a copy of the string. - * - * Use: Copies a string (like @strdup@ would, if it existed). - */ - -char *xstrdup(const char *s) -{ - size_t sz = strlen(s) + 1; - char *p = xmalloc(sz); - memcpy(p, s, sz); - return (p); -} - -/* --- @xrealloc@ --- * - * - * Arguments: @void *p@ = pointer to a block of memory - * @size_t sz@ = new size desired for the block - * - * Returns: Pointer to the resized memory block (which is almost - * certainly not in the same place any more). - * - * Use: Resizes a memory block. - */ - -void *xrealloc(void *p, size_t sz) -{ - p = realloc(p, sz); - if (!p) - die("not enough memory"); - return (p); -} - -/*----- Simple memory use tracking ----------------------------------------*/ - -#ifdef TRACK_MALLOC - -/*#define TRACK_VERBOSE*/ - -/* --- A type to record a size and have a nice alignment --- */ - -typedef union szblock { - struct { - union szblock *next; - union szblock *prev; - size_t sz; - } x; - long double _ld; - void *_p; -} szblock; - -/* --- Static data --- */ - -static unsigned int memused = 0; -static szblock *memlist; - -/* --- @track_malloc@ --- * - * - * Arguments: @size_t sz@ = size requested - * - * Returns: Pointer to allocated space, or null - * - * Use: Allocates memory, and tracks how much is allocated. - */ - -void *track_malloc(size_t sz) -{ - szblock *q = (malloc)(sz + sizeof(szblock)); - if (q) { - memused += sz; -#ifdef TRACK_VERBOSE - fflush(0); - printf("[%p] allocated %lu\n", (void *)(q + 1), (unsigned long)sz); - fflush(stdout); -#endif - q->x.sz = sz; - q->x.next = memlist; - q->x.prev = 0; - if (q->x.next) - q->x.next->x.prev = q; - memlist = q; - return (q + 1); - } - return (0); -} - -/* --- @track_free@ --- * - * - * Arguments: @void *p@ = pointer to an allocated block - * - * Returns: --- - * - * Use: Frees memory, and tracks how much is still allocated. - */ - -void track_free(void *p) -{ - szblock *q; - - if (!p) - return; - q = (szblock *)p - 1; -#ifdef TRACK_VERBOSE - fflush(0); - printf("[%p] freed %lu\n", (void *)(q + 1), (unsigned long)q->x.sz); - fflush(stdout); -#endif - if (q->x.next) - q->x.next->x.prev = q->x.prev; - if (q->x.prev) - q->x.prev->x.next = q->x.next; - else - memlist = q->x.next; - memused -= q->x.sz; - (free)(q); -} - -/* --- @track_realloc@ --- * - * - * Arguments: @void *p@ = pointer to an allocated block - * @size_t sz@ = how big it wants to be - * - * Returns: Pointer to the new block. - * - * Use: Reallocates a block, tracking how much memory is still - * available. - */ - -void *track_realloc(void *p, size_t sz) -{ - size_t osz; - szblock *q, *qq; - if (p) { - q = (szblock *)p - 1; - osz = q->x.sz; - if (q->x.next) - q->x.next->x.prev = q->x.prev; - if (q->x.prev) - q->x.prev->x.next = q->x.next; - else - memlist = q->x.next; - } else { - q = 0; - osz = 0; - } - qq = (realloc)(q, sz + sizeof(szblock)); - if (qq) { -#ifdef TRACK_VERBOSE - fflush(0); - printf("[%p->%p] reallocated %lu -> %lu\n", - (void *)(q + 1), (void *)(qq + 1), - (unsigned long)osz, (unsigned long)sz); - fflush(stdout); -#endif - qq->x.sz = sz; - qq->x.next = memlist; - qq->x.prev = 0; - if (qq->x.next) - qq->x.next->x.prev = qq; - memlist = qq; - memused += sz - osz; - qq->x.sz = sz; - return (qq + 1); - } - return (0); -} - -/* --- @track_memused@ --- * - * - * Arguments: --- - * - * Returns: A count of how much memory is used currently. - * - * Use: Returns the amount of memory which the @track_@-functions - * above have counted as being currently allocated. - */ - -unsigned long track_memused(void) -{ - return (memused); -} - -/* --- @track_memlist@ --- * - * - * Arguments: --- - * - * Returns: --- - * - * Use: Dumps a list of allocated blocks to standard output. - */ - -void track_memlist(void) -{ - szblock *q = memlist; - fflush(0); - printf("listing blocks:\n"); - while (q) { - printf("... [%p] %lu\n", (void *)(q + 1), (unsigned long)q->x.sz); - q = q->x.next; - } - printf("done\n"); - fflush(stdout); -} - -#endif - -/*----- That's all, folks -------------------------------------------------*/ diff --git a/src/utils.h b/src/utils.h deleted file mode 100644 index a9752f6..0000000 --- a/src/utils.h +++ /dev/null @@ -1,353 +0,0 @@ -/* -*-c-*- - * - * $Id: utils.h,v 1.4 1998/01/12 16:46:52 mdw Exp $ - * - * Miscellaneous useful bits of code. - * - * (c) 1998 Mark Wooding - */ - -/*----- Licensing notice --------------------------------------------------* - * - * This file is part of `become' - * - * `Become' is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * `Become' is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with `become'; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/*----- Revision history --------------------------------------------------* - * - * $Log: utils.h,v $ - * Revision 1.4 1998/01/12 16:46:52 mdw - * Fix copyright date. - * - * Revision 1.3 1997/08/20 16:25:37 mdw - * Add some simple `malloc' tracking. - * - * Revision 1.2 1997/08/04 10:24:26 mdw - * Sources placed under CVS control. - * - * Revision 1.1 1997/07/21 13:47:42 mdw - * Initial revision - * - */ - -#ifndef UTILS_H -#define UTILS_H - -#ifdef __cplusplus - extern "C" { -#endif - -/*----- Required header files ---------------------------------------------*/ - -#include -#include - -/*----- Storing and retrieving numbers ------------------------------------* - * - * These use big-endian conventions, because they seem more usual in network - * applications. I actually think that little-endian is more sensible... - */ - -#define load32(p) \ - ((((unsigned char)(p)[0] & 0xFF) << 24) | \ - (((unsigned char)(p)[1] & 0xFF) << 16) | \ - (((unsigned char)(p)[2] & 0xFF) << 8) | \ - (((unsigned char)(p)[3] & 0xFF) << 0)) - -#define store32(p, v) \ - ((p)[0] = ((unsigned long)(v) >> 24) & 0xFF, \ - (p)[1] = ((unsigned long)(v) >> 16) & 0xFF, \ - (p)[2] = ((unsigned long)(v) >> 8) & 0xFF, \ - (p)[3] = ((unsigned long)(v) >> 0) & 0xFF) - -/* --- Little-endian versions (for MD5) --- */ - -#define load32_l(p) \ - ((((unsigned char)(p)[0] & 0xFF) << 0) | \ - (((unsigned char)(p)[1] & 0xFF) << 8) | \ - (((unsigned char)(p)[2] & 0xFF) << 16) | \ - (((unsigned char)(p)[3] & 0xFF) << 24)) - -#define store32_l(p, v) \ - ((p)[0] = ((unsigned long)(v) >> 0) & 0xFF, \ - (p)[1] = ((unsigned long)(v) >> 8) & 0xFF, \ - (p)[2] = ((unsigned long)(v) >> 16) & 0xFF, \ - (p)[3] = ((unsigned long)(v) >> 24) & 0xFF) - -/*----- Other macros ------------------------------------------------------*/ - -/* --- @burn@ --- * - * - * Arguments: @obj@ = some object - * - * Use: Writes zero bytes over the object. - */ - -#define burn(obj) ((void)memset(&obj, 0, sizeof(obj))) - -/*----- Program name handling ---------------------------------------------*/ - -/* --- @quis@ --- * - * - * Arguments: --- - * - * Returns: Pointer to the program name. - * - * Use: Returns the program name. - */ - -extern const char *quis(void); - -/* --- @ego@ --- * - * - * Arguments: @const char *p@ = pointer to program name - * - * Returns: --- - * - * Use: Tells the utils library what the program's name is. - */ - -extern void ego(const char */*p*/); - -/*----- Error reporting ---------------------------------------------------*/ - -/* --- @moan@ --- * - * - * Arguments: @const char *f@ = a @printf@-style format string - * @...@ = other arguments - * - * Returns: --- - * - * Use: Reports an error. - */ - -extern void moan(const char */*f*/, ...); - -/* --- @die@ --- * - * - * Arguments: @const char *f@ = a @printf@-style format string - * @...@ = other arguments - * - * Returns: Never. - * - * Use: Reports an error and hari-kiris. Like @moan@ above, only - * more permanent. - */ - -extern void die(const char */*f*/, ...); - -/*----- Trace messages ----------------------------------------------------*/ - -#if !defined(NDEBUG) && !defined(TRACING) -# define TRACING -#endif - -#ifdef TRACING - -/* --- @trace@ --- * - * - * Arguments: @unsigned int lvl@ = trace level for output - * @const char *f@ = a @printf@-style format string - * @...@ = other arguments - * - * Returns: --- - * - * Use: Reports a message to the trace output. - */ - -extern void trace(unsigned int /*lvl*/, const char */*f*/, ...); - -/* --- @traceblk@ --- * - * - * Arguments: @unsigned int lvl@ = trace level for output - * @const char *hdr@ = some header string to write - * @const void *blk@ = pointer to a block of memory to dump - * @size_t sz@ = size of the block of memory - * - * Returns: --- - * - * Use: Dumps the contents of a block to the trace output. - */ - -extern void traceblk(unsigned int /*lvl*/, const char */*hdr*/, - const void */*blk*/, size_t /*sz*/); - -/* --- @traceon@ --- * - * - * Arguments: @FILE *fp@ = a file to trace on - * @unsigned int lvl@ = trace level to set - * - * Returns: --- - * - * Use: Enables tracing to a file. - */ - -extern void traceon(FILE */*fp*/, unsigned int /*lvl*/); - -/* --- @tracesetlvl@ --- * - * - * Arguments: @unsigned int lvl@ = trace level to set - * - * Returns: --- - * - * Use: Sets the tracing level. - */ - -extern void tracesetlvl(unsigned int /*lvl*/); - -/* --- @tracing@ --- * - * - * Arguments: --- - * - * Returns: Zero if not tracing, tracing level if tracing. - * - * Use: Informs the caller whether tracing is enabled. - */ - -extern unsigned int tracing(void); - -#endif - -/* --- Some hacky macros --- */ - -#ifdef TRACING -# define T(x) x -# define IF_TRACING(lvl, x) if ((lvl) & tracing()) x -#else -# define T(x) -# define IF_TRACING(lvl, x) -#endif - -/*----- Memory management functions ---------------------------------------*/ - -/* --- @xmalloc@ --- * - * - * Arguments: @size_t sz@ = size of block to allocate - * - * Returns: Pointer to allocated block. - * - * Use: Allocates memory. If the memory isn't available, we don't - * hang aroung long enough for a normal function return. - */ - -extern void *xmalloc(size_t /*sz*/); - -/* --- @xstrdup@ --- * - * - * Arguments: @const char *s@ = pointer to a string - * - * Returns: Pointer to a copy of the string. - * - * Use: Copies a string (like @strdup@ would, if it existed). - */ - -extern char *xstrdup(const char */*s*/); - -/* --- @xrealloc@ --- * - * - * Arguments: @void *p@ = pointer to a block of memory - * @size_t sz@ = new size desired for the block - * - * Returns: Pointer to the resized memory block (which is almost - * certainly not in the same place any more). - * - * Use: Resizes a memory block. - */ - -extern void *xrealloc(void */*p*/, size_t /*sz*/); - -/*----- Simple memory use tracking ----------------------------------------*/ - -#undef TRACK_MALLOC - -#ifdef TRACK_MALLOC - -/* --- @track_malloc@ --- * - * - * Arguments: @size_t sz@ = size requested - * - * Returns: Pointer to allocated space, or null - * - * Use: Allocates memory, and tracks how much is allocated. - */ - -extern void *track_malloc(size_t /*sz*/); - -/* --- @track_free@ --- * - * - * Arguments: @void *p@ = pointer to an allocated block - * - * Returns: --- - * - * Use: Frees memory, and tracks how much is still allocated. - */ - -extern void track_free(void */*p*/); - -/* --- @track_realloc@ --- * - * - * Arguments: @void *p@ = pointer to an allocated block - * @size_t sz@ = how big it wants to be - * - * Returns: Pointer to the new block. - * - * Use: Reallocates a block, tracking how much memory is still - * available. - */ - -extern void *track_realloc(void */*p*/, size_t /*sz*/); - -/* --- @track_memused@ --- * - * - * Arguments: --- - * - * Returns: A count of how much memory is used currently. - * - * Use: Returns the amount of memory which the @track_@-functions - * above have counted as being currently allocated. - */ - -extern unsigned long track_memused(void); - -/* --- @track_memlist@ --- * - * - * Arguments: --- - * - * Returns: --- - * - * Use: Dumps a list of allocated blocks to standard output. - */ - -extern void track_memlist(void); - -#undef malloc -#define malloc(sz) track_malloc(sz) - -#undef free -#define free(p) track_free(p) - -#undef realloc -#define realloc(p, sz) track_realloc(p, sz) - -#endif - -/*----- That's all, folks -------------------------------------------------*/ - -#ifdef __cplusplus - } -#endif - -#endif