encrypt-and-hope thing. Integrated with mLib and Catacomb.
manual/texinice.tex
missing
mkinstalldirs
-src/mdwopt.c
-src/mdwopt.h
/* -*-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
*
/*----- 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.
*
/* 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
#undef NONETWORK
/* Debugging options. */
-#undef TRACING
+#undef NTRACE
#ifndef TEST_RIG
#undef NDEBUG
@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
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
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
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 ---
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])])
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, '/')
become_*.html
html
stamp-html.in
+become.html
\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
@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,
* Administering Become:: How to maintain Become
* Invoking Become:: Reference to Become's command line options
+@detailmenu
--- The Detailed Node Listing ---
Becoming someone else
* 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 --------------------------------------------------------------------------
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
@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
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 --------------------------------------------------------------------------
## 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'
##
##----- 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.
##
## --- What to make ---
-bin_PROGRAMS = become keygen bcquery
+bin_PROGRAMS = become bcquery
noinst_LIBRARIES = libbecome.a
##----- Building the main code ----------------------------------------------
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
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 ------------------------------------------
/* -*-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
*
/*----- 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.
#include <syslog.h>
#include <unistd.h>
+/* --- mLib headers --- */
+
+#include <mLib/alloc.h>
+#include <mLib/mdwopt.h>
+#include <mLib/quis.h>
+#include <mLib/report.h>
+#include <mLib/sym.h>
+
/* --- Local headers --- */
#include "become.h"
#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 --------------------------------------------------*/
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) {
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++;
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 ')':
break;
}
if (!opt)
- die("unexpected text `%s' found", optarg);
+ die(1, "unexpected text `%s' found", optarg);
break;
}
nextopt();
q = qparse_expr();
if (opt != ')')
- die("syntax error: expected `)', found `%s'", optname());
+ die(1, "syntax error: expected `)', found `%s'", optname());
nextopt();
return (q);
}
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();
}
pw = userdb_userByName(optarg);
if (!pw)
- die("unknown user `%s'", optarg);
+ die(1, "unknown user `%s'", optarg);
q->q_uid = pw->pw_uid;
}
nextopt();
return (q);
}
default:
- die("unexpected token: `%s'", optname());
+ die(1, "unexpected token: `%s'", optname());
}
return (0);
}
return (0);
q = qparse_expr();
if (opt != EOF)
- die("syntax error: `%s' unexpected", optname());
+ die(1, "syntax error: `%s' unexpected", optname());
return (q);
}
/* --- 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);
}
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, "");
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);
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)
/* --- Done --- */
if (!(flags & f_match))
- die("no match");
+ die(1, "no match");
return (0);
}
/* -*-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'
*
/*----- 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 `.'.
*
extern char **environ;
+/* --- mLib --- */
+
+#include <mLib/alloc.h>
+#include <mLib/mdwopt.h>
+#include <mLib/quis.h>
+#include <mLib/report.h>
+#include <mLib/sym.h>
+#include <mLib/trace.h>
+
/* --- Local headers --- */
#include "become.h"
#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 --------------------------------------------------*/
"-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,
{
char **p;
- sym_createTable(&bc__env);
+ sym_create(&bc__env);
for (p = environ; *p; p++)
bc__putenv(0, *p, 0, 0);
}
/* --- Tracing options --- */
-#ifdef TRACING
+#ifndef NTRACE
{ "impersonate", gFlag_argReq, 0, 'I' },
{ "trace", gFlag_argOpt, 0, 'T' },
{ "trace-level", gFlag_argOpt, 0, 'L' },
#ifndef NONETWORK
"dp:f:" /* Server options */
#endif
-#ifdef TRACING
+#ifndef NTRACE
"I:T::L::" /* Tracing options */
#endif
,
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;
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;
* allow it if we're running setuid. Disable the actual login anyway.
*/
-#ifdef TRACING
+#ifndef NTRACE
case 'I':
if (flags & f_setuid)
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;
* to!
*/
-#ifdef TRACING
+#ifndef TRACE
case 'T': {
FILE *fp;
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));
}
#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;
/* --- 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" },
{ '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
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;
}
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);
}
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));
}
/* --- 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
if (group == to_gr[i])
goto group_ok;
}
- die("invalid default group");
+ die(1, "invalid default group");
group_ok:;
}
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 --- */
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;
}
}
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);
}
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++ = '/';
}
*/
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 --- */
rq.cmd);
if (!a)
- die("permission denied");
+ die(1, "permission denied");
}
/* --- Now do the job --- */
#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 --- */
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);
}
+++ /dev/null
-/* -*-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 -------------------------------------------------*/
+++ /dev/null
-/* -*-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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-/* --- 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 -------------------------------------------------*/
+++ /dev/null
-/* -*-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
/* -*-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
*
/*----- 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.
#include <netdb.h>
#include <unistd.h>
+/* --- mLib headers --- */
+
+#include <mLib/alloc.h>
+#include <mLib/quis.h>
+#include <mLib/report.h>
+#include <mLib/sym.h>
+#include <mLib/trace.h>
+
+/* --- Catacomb headers --- */
+
+#include <catacomb/buf.h>
+#include <catacomb/dsa.h>
+#include <catacomb/key.h>
+#include <catacomb/mp.h>
+#include <catacomb/noise.h>
+#include <catacomb/rand.h>
+#include <catacomb/sha.h>
+
/* --- 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 ----------------------------------------*/
/* --- @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
* 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;
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)); )
}
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@ --- *
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);
}
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);
*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;
}
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);
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;
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;
/* --- 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;
}
}
/* --- 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;
/* --- 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));
}
/* -*-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
*
/*----- 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.
#include <netdb.h>
+/* --- mLib headers --- */
+
+#include <mLib/alloc.h>
+#include <mLib/report.h>
+#include <mLib/sym.h>
+
/* --- Local headers --- */
#include "become.h"
#include "class.h"
-#include "sym.h"
-#include "utils.h"
/*----- Global variables --------------------------------------------------*/
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:
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:
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;
/* --- 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 --- */
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);
}
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;
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);
}
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);
}
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);
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;
}
}
}
- die("internal error: can't get here in class_matchUser");
+ die(1, "internal: can't get here in class_matchUser");
return (0);
}
}
}
- die("internal error: can't get here in class_matchCommand");
+ die(1, "internal: can't get here in class_matchCommand");
return (0);
}
}
}
- die("internal error: can't get here in class_matchUser");
+ die(1, "internal: can't get here in class_matchUser");
return (0);
}
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);
/* -*-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
*
/*----- 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.
*
#include <netinet/in.h>
#include <arpa/inet.h>
-#ifndef SYM_H
-# include "sym.h"
-#endif
+#include <mLib/sym.h>
/*----- Data structures ---------------------------------------------------*/
+++ /dev/null
-/* -*-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 <ctype.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-/* --- Unix headers --- */
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <unistd.h>
-#include <syslog.h>
-#include <fcntl.h>
-
-/* --- 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 -------------------------------------------------*/
+++ /dev/null
-/* -*-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 <string.h>
-
-#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
/* -*-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
*
/*----- 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.
#include <errno.h>
#include <signal.h>
-#include <setjmp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <unistd.h>
+/* --- mLib headers --- */
+
+#include <mLib/fwatch.h>
+#include <mLib/quis.h>
+#include <mLib/report.h>
+#include <mLib/sel.h>
+#include <mLib/sig.h>
+#include <mLib/sym.h>
+#include <mLib/trace.h>
+
+/* --- Catacomb headers --- */
+
+#include <catacomb/buf.h>
+#include <catacomb/dsa.h>
+#include <catacomb/key.h>
+#include <catacomb/mp.h>
+#include <catacomb/noise.h>
+#include <catacomb/paranoia.h>
+#include <catacomb/rand.h>
+#include <catacomb/sha.h>
+
/* --- 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 ---------------------------------------------------------*/
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@ --- *
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@ --- *
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 --- *
*
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();
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 --- *
*
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;
}
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));
}
}
/* --- 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;
}
#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);
}
}
}
+++ /dev/null
-/* -*-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 <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-/* --- 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 <errno.h>
-#include <pwd.h>
-#include <unistd.h>
-#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 -------------------------------------------------*/
+++ /dev/null
-/* -*-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 <stddef.h>
-
-#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
+++ /dev/null
-/* -*-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 <ctype.h>
-#include <errno.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-/* --- Unix headers --- */
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <fcntl.h>
-
-#include <termios.h>
-#include <unistd.h>
-
-/* --- 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 -------------------------------------------------*/
+++ /dev/null
-/* -*-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 <stdio.h>
-#include <string.h>
-
-#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 -------------------------------------------------*/
+++ /dev/null
-/* -*-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 <stddef.h>
-
-#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
/* -*-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
*
/*----- 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.
*
#include <grp.h>
#include <pwd.h>
+/* --- mLib headers --- */
+
+#include <mLib/alloc.h>
+#include <mLib/sym.h>
+
/* --- Local headers --- */
#include "config.h"
#include "class.h"
#include "name.h"
#include "netg.h"
-#include "sym.h"
#include "userdb.h"
-#include "utils.h"
/*----- Static variables --------------------------------------------------*/
{
/* --- Initialise the name table --- */
- sym_createTable(&name__table);
+ sym_create(&name__table);
/* --- Add everyone into the table --- */
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);
}
/* --- Destroy and recreate the table --- */
- sym_destroyTable(&name__table);
+ sym_destroy(&name__table);
}
/* --- @name_find@ --- *
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: <empty>");
/* -*-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
*
/*----- 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.
*
/*----- Required headers --------------------------------------------------*/
+#include <mLib/sym.h>
+
#ifndef CLASS_H
# include "class.h"
#endif
-#ifndef SYM_H
-# include "sym.h"
-#endif
-
/*----- Data structures ---------------------------------------------------*/
typedef struct name {
/* -*-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
*
/*----- 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.
*
#include <netdb.h>
#include <unistd.h>
+/* --- mLib headers --- */
+
+#include <mLib/alloc.h>
+#include <mLib/report.h>
+#include <mLib/sym.h>
+#include <mLib/trace.h>
+
/* --- 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 --------------------------------------------------*/
* Use: Dumps the netgroup given.
*/
-#ifdef TRACING
+#ifndef NTRACE
static void netg__dumpGroup(netg__cons *c, int lev)
{
* Use: Dumps the netgroups table.
*/
-#ifdef TRACING
+#ifndef NTRACE
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);
*/
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@ --- *
*
{
/* --- Initialise my symbol table --- */
- sym_createTable(&netg__table);
+ sym_create(&netg__table);
/* --- Bind myself unto a YP server --- */
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;
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);
}
/* --- 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;
sym_remove(&netg__table, sng);
}
- sym_destroyTable(&netg__table);
+ sym_destroy(&netg__table);
}
/*----- Test driver -------------------------------------------------------*/
/* -*-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
*
/*----- 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.
*
/*----- Required headers --------------------------------------------------*/
-#ifndef SYM_H
-# include "sym.h"
-#endif
+#include <mLib/sym.h>
/*----- Type definitions --------------------------------------------------*/
+++ /dev/null
-/* -*-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 <ctype.h>
-#include <errno.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-/* --- Unix headers --- */
-
-#include <sys/types.h>
-#include <sys/time.h>
-
-#include "config.h"
-#if defined(HAVE_GETRUSAGE)
-# include <sys/resource.h>
-#elif defined(HAVE_VTIMES)
-# include <sys/vtimes.h>
-#endif
-
-#include <sys/wait.h>
-
-#include <fcntl.h>
-#include <unistd.h>
-
-/* --- 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 -------------------------------------------------*/
+++ /dev/null
-/* -*-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
-
/* -*-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
*
/*----- 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.
#include <pwd.h>
#include <unistd.h>
+/* --- mLib headers --- */
+
+#include <mLib/report.h>
+#include <mLib/sym.h>
+
/* --- Local headers --- */
#include "class.h"
#include "lexer.h"
#include "name.h"
#include "rule.h"
-#include "sym.h"
#include "userdb.h"
-#include "utils.h"
%}
/*----- Stack type --------------------------------------------------------*/
+++ /dev/null
-/* -*-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 <ctype.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-/* --- 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 -------------------------------------------------*/
+++ /dev/null
-/* -*-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 <stdio.h>
-
-#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
/* -*-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
*
/*----- 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.
*
#include <netdb.h>
#include <unistd.h>
+/* --- mLib headers --- */
+
+#include <mLib/alloc.h>
+#include <mLib/report.h>
+#include <mLib/trace.h>
+
/* --- Local headers --- */
#include "become.h"
#include "class.h"
#include "rule.h"
#include "userdb.h"
-#include "utils.h"
/*----- Static variables --------------------------------------------------*/
+++ /dev/null
-/* -*-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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-/* --- 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 <errno.h>
-#include <time.h>
-
-#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 -------------------------------------------------*/
+++ /dev/null
-/* -*-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 <stddef.h>
-
-/*----- 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
+++ /dev/null
-/* -*-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 <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-/* --- 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 -------------------------------------------------*/
+++ /dev/null
-/* -*-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 <stddef.h>
-
-/*----- 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
/* -*-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
*
/*----- 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.
#include <pwd.h>
#include <unistd.h>
+/* --- mLib headers --- */
+
+#include <mLib/alloc.h>
+#include <mLib/sym.h>
+#include <mLib/trace.h>
+
/* --- Local headers --- */
#include "become.h"
-#include "sym.h"
#include "userdb.h"
-#include "utils.h"
#include "ypstuff.h"
/*----- Type definitions --------------------------------------------------*/
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;
}
{
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;
* Use: Writes a user's informationt to a stream.
*/
-#ifdef TRACING
+#ifndef NTRACE
static void userdb__dumpUser(const struct passwd *pw)
{
* Use: Writes a group's information to a stream.
*/
-#ifdef TRACING
+#ifndef NTRACE
static void userdb__dumpGroup(const struct group *gr)
{
{ 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@ --- *
*
{ 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@ --- *
*
/*----- 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.
*
#include <grp.h>
#include <pwd.h>
-#ifndef SYM_H
-# include "sym.h"
-#endif
+#include <mLib/sym.h>
/*----- Type definitions --------------------------------------------------*/
+++ /dev/null
-/* -*-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 <ctype.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-/* --- 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 -------------------------------------------------*/
+++ /dev/null
-/* -*-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 <stddef.h>
-#include <stdlib.h>
-
-/*----- 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