/* -*-c-*-
*
- * $Id: daemon.c,v 1.12 2003/10/12 00:14:55 mdw Exp $
+ * $Id: daemon.c,v 1.17 2004/04/08 01:36:20 mdw Exp $
*
* Running a `become' daemon
*
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
-/*----- 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.
- *
- * Revision 1.10 1998/04/23 13:23:09 mdw
- * Support new interface to configuration file parser.
- *
- * Revision 1.9 1998/01/12 16:45:59 mdw
- * Fix copyright date.
- *
- * Revision 1.8 1997/09/26 09:14:58 mdw
- * Merged blowfish branch into trunk.
- *
- * Revision 1.7.2.1 1997/09/26 09:08:05 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.7 1997/09/17 10:23:23 mdw
- * Fix a typo. Port numbers are in network order now, so don't change them.
- *
- * Revision 1.6 1997/09/09 18:17:06 mdw
- * Allow default port to be given as a service name or port number.
- *
- * Revision 1.5 1997/08/20 16:17:10 mdw
- * More sensible restart routine: `_reinit' functions replaced by `_end' and
- * `_init' functions.
- *
- * Revision 1.4 1997/08/07 10:00:37 mdw
- * (Log entry for previous version is bogus.) Read netgroups database.
- * Give up privileges permanently on startup.
- *
- * Revision 1.2 1997/08/04 10:24:21 mdw
- * Sources placed under CVS control.
- *
- * Revision 1.1 1997/07/21 13:47:50 mdw
- * Initial revision
- *
- */
-
/*----- Header files ------------------------------------------------------*/
/* --- ANSI headers --- */
/*----- Arbitrary constants -----------------------------------------------*/
-#define daemon__awakeEvery (5 * 60) /* Awaken this often to rescan */
+#define daemon__awakeEvery (10) /* Awaken this often to rescan */
/*----- Static variables --------------------------------------------------*/
static int daemon__port = -1; /* No particular port yet */
-static int daemon__readKey = 0; /* Have I read a key? */
-static fwatch daemon__watch;
+static fwatch daemon__cwatch, daemon__kwatch; /* Watching key/config files */
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 const char *daemon__keyfile; /* Keyring file for daemon */
static dsa_priv daemon__key; /* The key data */
/*----- Main code ---------------------------------------------------------*/
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);
+ T( trace(TRACE_DAEMON, "daemon: key file error: %s: %d: %s",
+ f, line, msg); )
}
/* --- @daemon_readKey@ --- *
key *k;
int err;
- if (daemon__readKey)
+ if (daemon__keyfile)
return;
+ T( trace(TRACE_DAEMON, "daemon: reading key from `%s'", kf); )
if (key_open(&f, kf, KOPEN_READ, daemon__moan, 0))
return;
kp = key_fetchinit(dsa_privfetch, kps, &daemon__key);
mp_copy(daemon__key.dp.g);
mp_copy(daemon__key.x);
mp_copy(daemon__key.y);
+ daemon__keyfile = kf;
}
key_fetchdone(kp);
key_close(&f);
{
FILE *fp;
- daemon__readKey = 0;
+ daemon__keyfile = 0;
if ((fp = fopen(cf, "r")) == 0)
return (-1);
lexer_scan(fp);
parse();
fclose(fp);
- if (!daemon__readKey)
+ if (!daemon__keyfile)
daemon_readKey(file_KEY);
T( trace(TRACE_DAEMON, "daemon: read config file"); )
return (0);
syslog(LOG_DEBUG, "packet received from %s", sender);
T( trace(TRACE_DAEMON, "daemon: received request from %s", sender); )
+ /* --- Sanity check --- */
+
+ if (!daemon__keyfile) {
+ syslog(LOG_NOTICE, "no key file: ignoring request");
+ T( trace(TRACE_DAEMON, "daemon: no key file: ignoring request"); )
+ return;
+ }
+
/* --- Unpack the block --- */
rq.host = sin.sin_addr;
syslog(LOG_ERR, "error reading configuration file");
sel_rmtimer(&daemon__timer);
daemon__setTimer();
- fwatch_update(&daemon__watch, daemon__config);
+ fwatch_update(&daemon__cwatch, daemon__config);
+ fwatch_update(&daemon__kwatch, daemon__keyfile);
}
/* --- @daemon__wakeUp@ --- *
static void daemon__wakeUp(struct timeval *tv, void *p)
{
+ T( trace(TRACE_DAEMON, "daemon: interval timer"); )
rand_seed(RAND_GLOBAL, 160);
- if (fwatch_update(&daemon__watch, daemon__config))
+ daemon__setTimer();
+ if (fwatch_update(&daemon__cwatch, daemon__config))
daemon__rescan(0, 0);
+ else if (fwatch_update(&daemon__kwatch, daemon__keyfile)) {
+ const char *kf = daemon__keyfile;
+ daemon__keyfile = 0;
+ daemon_readKey(kf);
+ }
}
/* --- @daemon_init@ --- *
*
* Arguments: @const char *cf@ = pointer to name of configuration file
* @int port@ = port to listen to, or %$-1$% for default
+ * @unsigned f@ = various flags
*
* Returns: Never.
*
* Use: Starts `become' up in daemon mode.
*/
-void daemon_init(const char *cf, int port)
+void daemon_init(const char *cf, int port, unsigned f)
{
int s;
int i;
if (daemon__readConfig(daemon__config))
die(1, "couldn't read configuration file");
- fwatch_init(&daemon__watch, daemon__config);
+ fwatch_init(&daemon__cwatch, daemon__config);
+ fwatch_init(&daemon__kwatch, daemon__keyfile);
/* --- Decide on a port to use --- *
*
if (daemon__port == 0) {
struct servent *se = getservbyname(quis(), "udp");
- if (!se)
- die(1, "no idea which port to listen to");
- daemon__port = se->s_port;
+ if (se)
+ daemon__port = se->s_port;
+ else
+ daemon__port = htons(SERVER_PORT);
}
/* --- Now set up a socket --- */
/* --- Fork off into the sunset --- */
-#ifdef NDEBUG
- {
+ if (!(f & df_nofork)) {
int pid = fork();
FILE *fp;
}
T( trace(TRACE_DAEMON, "daemon: forked to pid %li", (long)getpid()); )
}
-#endif
/* --- Set signal handlers --- */