+Fri Mar 29 03:26:12 CET 2002 Johnny Mnemonic <johnny@themnemonic.org>
+
+ * Added preliminary checking during config parsing for a valid
+ public/private key and removed further checks in the code.
+ Affected files are silcd/serverconfig.[ch], server.c.
+
+ * Moved functions silc_server_drop() and silc_server_daemonise()
+ from server.c to silcd.c since they are stricly related to
+ the application activity.
+
+ * Reverted a small part of the automatic ref/unref since
+ it caused a double unref in some situations. Affected
+ files are silcd/silcd.[ch], server.c, serverconfig.c.
+
+ * Added some .cvsignore files in the lib directory.
+
Thu Mar 28 22:51:15 EET 2002 Pekka Riikonen <priikone@silcnet.org>
* Fixed silc_net_gethostbyaddr to correctly resolve by
SilcSocketConnection newsocket = NULL;
SILC_LOG_DEBUG(("Initializing server"));
- assert(server);
- assert(server->config);
-
- silc_server_config_ref(&server->config_ref, server->config,
- server->config);
-
- /* Set public and private keys */
- if (!server->config->server_info ||
- !server->config->server_info->public_key ||
- !server->config->server_info->private_key) {
- SILC_LOG_ERROR(("Server public key and/or private key does not exist"));
- return FALSE;
- }
/* Steal public and private key from the config object */
server->public_key = server->config->server_info->public_key;
goto err;
}
id_entry->data.status |= SILC_IDLIST_STATUS_REGISTERED;
-
+
/* Put the allocated socket pointer also to the entry allocated above
for fast back-referencing to the socket list. */
newsocket->user_data = (void *)id_entry;
{
SilcServerConfig newconfig;
- /* Our old config is gone now. We'll unreference our reference made in
- silc_server_init and then destroy it since we are destroying it
- underneath the application (layer which called silc_server_init). */
- silc_server_config_unref(&server->config_ref);
- silc_server_config_destroy(server->config);
+ SILC_LOG_INFO(("Rehashing server"));
/* Reset the logging system */
silc_log_quick = TRUE;
silc_log_flush_all();
/* Start the main rehash phase (read again the config file) */
- SILC_LOG_INFO(("Rehashing server"));
newconfig = silc_server_config_alloc(server->config_file);
if (!newconfig) {
SILC_LOG_ERROR(("Rehash FAILED."));
return FALSE;
}
- /* Take new config context */
+ /* Config file parsing went fine, so our old config is gone now. We
+ unreference the basic pointer and it should be destroyed as soon
+ as all other references are released. */
+ silc_server_config_unref(&server->config_ref);
server->config = newconfig;
silc_server_config_ref(&server->config_ref, server->config, server->config);
- /* Set public and private keys */
- if (!server->config->server_info ||
- !server->config->server_info->public_key ||
- !server->config->server_info->private_key) {
- SILC_LOG_ERROR(("Server public key and/or private key does not exist"));
- return FALSE;
- }
-
/* Fix the server_name field */
if (!strcmp(server->server_name, newconfig->server_info->server_name)) {
/* We don't need any update */
silc_free(server->id_entry->server_name);
server->id_entry->server_name = strdup(server->server_name);
silc_idcache_del_by_context(server->local_list->servers, server->id_entry);
- silc_idcache_add(server->local_list->servers,
+ silc_idcache_add(server->local_list->servers,
server->id_entry->server_name,
server->id_entry->id, server->id_entry, 0, NULL);
}
silc_server_config_setlogfiles(server);
/* Change new key pair if necessary */
- if (server->config->server_info->public_key &&
+ if (newconfig->server_info->public_key &&
!silc_pkcs_public_key_compare(server->public_key,
- server->config->server_info->public_key)) {
+ newconfig->server_info->public_key)) {
silc_pkcs_public_key_free(server->public_key);
silc_pkcs_private_key_free(server->private_key);
server->public_key = server->config->server_info->public_key;
return TRUE;
}
-/* Drop root privileges. If some system call fails, die. */
-
-void silc_server_drop(SilcServer server)
-{
- /* Are we executing silcd as root or a regular user? */
- if (geteuid()) {
- SILC_LOG_DEBUG(("Server started as user"));
- }
- else {
- struct passwd *pw;
- struct group *gr;
- char *user, *group;
-
- SILC_LOG_DEBUG(("Server started as root. Dropping privileges."));
-
- /* Get the values given for user and group in configuration file */
- user = server->config->server_info->user;
- group = server->config->server_info->group;
-
- if (!user || !group) {
- fprintf(stderr, "Error:"
- "\tSILC server must not be run as root. For the security of your\n"
- "\tsystem it is strongly suggested that you run SILC under dedicated\n"
- "\tuser account. Modify the ServerInfo configuration section to run\n"
- "\tthe server as non-root user.\n");
- exit(1);
- }
-
- /* Check whether the user/group does not begin with a number */
- if (isdigit(user[0]) || isdigit(group[0])) {
- SILC_LOG_DEBUG(("User and/or group starts with a number"));
- fprintf(stderr, "Invalid user and/or group information\n");
- fprintf(stderr, "Please assign them as names, not numbers\n");
- exit(1);
- }
-
- if (!(pw = getpwnam(user))) {
- fprintf(stderr, "Error: No such user %s found.\n", user);
- exit(1);
- }
- if (!(gr = getgrnam(group))) {
- fprintf(stderr, "Error: No such group %s found.\n", group);
- exit(1);
- }
-
- /* Check whether user and/or group is set to root. If yes, exit
- immediately. Otherwise, setgid and setuid server to user.group */
- if ((gr->gr_gid == 0) || (pw->pw_uid == 0)) {
- fprintf(stderr, "Error:"
- "\tSILC server must not be run as root. For the security of your\n"
- "\tsystem it is strongly suggested that you run SILC under dedicated\n"
- "\tuser account. Modify the ServerInfo configuration section to run\n"
- "\tthe server as non-root user.\n");
- exit(1);
- }
-
- SILC_LOG_DEBUG(("Changing to group %s (gid=%u)", group, gr->gr_gid));
- if (setgid(gr->gr_gid) != 0) {
- fprintf(stderr, "Error: Failed setgid() to %s (gid=%u). Exiting.\n",
- group, gr->gr_gid);
- exit(1);
- }
-#if defined HAVE_SETGROUPS && defined HAVE_INITGROUPS
- SILC_LOG_DEBUG(("Removing supplementary groups"));
- if (setgroups(0, NULL) != 0) {
- fprintf(stderr, "Error: Failed setgroups() to NULL. Exiting.\n");
- exit(1);
- }
- SILC_LOG_DEBUG(("Setting supplementary groups for user %s", user));
- if (initgroups(user, gr->gr_gid) != 0) {
- fprintf(stderr, "Error: Failed initgroups() for user %s (gid=%u). "
- "Exiting.\n", user, gr->gr_gid);
- exit(1);
- }
-#endif
- SILC_LOG_DEBUG(("Changing to user %s (uid=%u)", user, pw->pw_uid));
- if (setuid(pw->pw_uid) != 0) {
- fprintf(stderr, "Error: Failed to setuid() to %s (gid=%u). Exiting.\n",
- user, pw->pw_uid);
- exit(1);
- }
- }
-}
-
-/* Fork server to background */
-
-void silc_server_daemonise(SilcServer server)
-{
- int i;
-
- SILC_LOG_DEBUG(("Forking SILC server to background"));
-
- if ((i = fork()) < 0) {
- fprintf(stderr, "Error: fork() failed: %s\n", strerror(errno));
- exit(1);
- }
-
- if (i) /* Kill the parent */
- exit(0);
-
- server->background = TRUE;
- setsid();
-
- /* XXX close stdin, stdout, stderr -- before this, check that all writes
- to stderr are changed to SILC_SERVER_LOG_ERROR() */
-}
-
/* The heart of the server. This runs the scheduler thus runs the server.
When this returns the server has been stopped and the program will
be terminated. */
void silc_server_free(SilcServer server);
bool silc_server_init(SilcServer server);
bool silc_server_rehash(SilcServer server);
-void silc_server_drop(SilcServer server);
-void silc_server_daemonise(SilcServer server);
void silc_server_run(SilcServer server);
void silc_server_stop(SilcServer server);
void silc_server_start_key_exchange(SilcServer server,
if (type == SILC_CONFIG_ARG_BLOCK) {
/* check for mandatory inputs */
+ if (!server_info->public_key || !server_info->private_key) {
+ got_errno = SILC_CONFIG_EMISSFIELDS;
+ goto got_err;
+ }
return SILC_CONFIG_OK;
}
if (!strcmp(name, "hostname")) {
/* obtain a config file object */
file = silc_config_open(filename);
if (!file) {
- SILC_SERVER_LOG_ERROR(("\nError: can't open config file `%s'\n",
+ SILC_SERVER_LOG_ERROR(("\nError: can't open config file `%s'\n",
filename));
return NULL;
}
SILC_SERVER_LOG_ERROR(("Error while parsing config file: %s.\n",
silc_config_strerror(ret)));
linebuf = silc_config_read_line(file, line);
- SILC_SERVER_LOG_ERROR((" file %s line %lu: %s\n", filename,
+ SILC_SERVER_LOG_ERROR((" file %s line %lu: %s\n", filename,
line, linebuf));
silc_free(linebuf);
}
/* Set default to configuration parameters */
silc_server_config_set_defaults(config_new);
- config_new->refcount = 1;
return config_new;
}
void silc_server_config_unref(SilcServerConfigRef *ref)
{
- if (ref->ref_ptr)
- silc_server_config_destroy(ref->config);
+ SilcServerConfig config = ref->config;
+
+ if (ref->ref_ptr) {
+ config->refcount--;
+ SILC_LOG_DEBUG(("Unreferencing config [%p] refcnt %hu->%hu", config,
+ config->refcount + 1, config->refcount));
+ if (!config->refcount)
+ silc_server_config_destroy(config);
+ ref->ref_ptr = NULL;
+ }
}
/* Destroy a config object with all his children lists */
{
void *tmp;
- config->refcount--;
- SILC_LOG_DEBUG(("Unreferencing config [%p] refcnt %hu->%hu", config,
- config->refcount + 1, config->refcount));
- if (config->refcount > 0)
- return;
-
SILC_LOG_DEBUG(("Freeing config context"));
silc_free(config->module_path);
silc_free(si->group);
silc_free(si->motd_file);
silc_free(si->pid_file);
+ silc_pkcs_public_key_free(si->public_key);
+ silc_pkcs_private_key_free(si->private_key);
}
/* Now let's destroy the lists */
};
/* Command line option variables */
-static bool opt_create_keypair = FALSE;
static char *opt_keypath = NULL;
static char *opt_pkcs = "rsa";
static char *opt_identifier = NULL;
exit(0);
}
-/* Dies if a *valid* pid file exists already */
+/* Die if a *valid* pid file exists already */
static void silc_server_checkpid(SilcServer silcd)
{
}
}
+/* Drop root privileges. If some system call fails, die. */
+
+static void silc_server_drop(SilcServer server)
+{
+ /* Are we executing silcd as root or a regular user? */
+ if (geteuid()) {
+ SILC_LOG_DEBUG(("Server started as user"));
+ }
+ else {
+ struct passwd *pw;
+ struct group *gr;
+ char *user, *group;
+
+ SILC_LOG_DEBUG(("Server started as root. Dropping privileges."));
+
+ /* Get the values given for user and group in configuration file */
+ user = server->config->server_info->user;
+ group = server->config->server_info->group;
+
+ if (!user || !group) {
+ fprintf(stderr, "Error:"
+ "\tSILC server must not be run as root. For the security of your\n"
+ "\tsystem it is strongly suggested that you run SILC under dedicated\n"
+ "\tuser account. Modify the ServerInfo configuration section to run\n"
+ "\tthe server as non-root user.\n");
+ exit(1);
+ }
+
+ /* Check whether the user/group does not begin with a number */
+ if (isdigit(user[0]) || isdigit(group[0])) {
+ SILC_LOG_DEBUG(("User and/or group starts with a number"));
+ fprintf(stderr, "Invalid user and/or group information\n");
+ fprintf(stderr, "Please assign them as names, not numbers\n");
+ exit(1);
+ }
+
+ if (!(pw = getpwnam(user))) {
+ fprintf(stderr, "Error: No such user %s found.\n", user);
+ exit(1);
+ }
+ if (!(gr = getgrnam(group))) {
+ fprintf(stderr, "Error: No such group %s found.\n", group);
+ exit(1);
+ }
+
+ /* Check whether user and/or group is set to root. If yes, exit
+ immediately. Otherwise, setgid and setuid server to user.group */
+ if ((gr->gr_gid == 0) || (pw->pw_uid == 0)) {
+ fprintf(stderr, "Error:"
+ "\tSILC server must not be run as root. For the security of your\n"
+ "\tsystem it is strongly suggested that you run SILC under dedicated\n"
+ "\tuser account. Modify the ServerInfo configuration section to run\n"
+ "\tthe server as non-root user.\n");
+ exit(1);
+ }
+
+ SILC_LOG_DEBUG(("Changing to group %s (gid=%u)", group, gr->gr_gid));
+ if (setgid(gr->gr_gid) != 0) {
+ fprintf(stderr, "Error: Failed setgid() to %s (gid=%u). Exiting.\n",
+ group, gr->gr_gid);
+ exit(1);
+ }
+#if defined HAVE_SETGROUPS && defined HAVE_INITGROUPS
+ SILC_LOG_DEBUG(("Removing supplementary groups"));
+ if (setgroups(0, NULL) != 0) {
+ fprintf(stderr, "Error: Failed setgroups() to NULL. Exiting.\n");
+ exit(1);
+ }
+ SILC_LOG_DEBUG(("Setting supplementary groups for user %s", user));
+ if (initgroups(user, gr->gr_gid) != 0) {
+ fprintf(stderr, "Error: Failed initgroups() for user %s (gid=%u). "
+ "Exiting.\n", user, gr->gr_gid);
+ exit(1);
+ }
+#endif
+ SILC_LOG_DEBUG(("Changing to user %s (uid=%u)", user, pw->pw_uid));
+ if (setuid(pw->pw_uid) != 0) {
+ fprintf(stderr, "Error: Failed to setuid() to %s (gid=%u). Exiting.\n",
+ user, pw->pw_uid);
+ exit(1);
+ }
+ }
+}
+
+/* Fork server to background */
+
+static void silc_server_daemonise(SilcServer server)
+{
+ int i;
+
+ SILC_LOG_DEBUG(("Forking SILC server to background"));
+
+ if ((i = fork()) < 0) {
+ fprintf(stderr, "Error: fork() failed: %s\n", strerror(errno));
+ exit(1);
+ }
+
+ if (i) /* Kill the parent */
+ exit(0);
+
+ server->background = TRUE;
+ setsid();
+
+ /* XXX close stdin, stdout, stderr -- before this, check that all writes
+ to stderr are changed to SILC_SERVER_LOG_ERROR() */
+}
+
static void signal_handler(int sig)
{
/* Mark the signal to be caller after this signal is over. */
silc_schedule_stop(silcd->schedule);
}
+/* This function should not be called directly but throught the wrapper
+ macro SILC_SERVER_LOG_STDERR() */
+
void silc_server_stderr(char *message)
{
if (silcd->background)
{
int ret, opt, option_index;
bool foreground = FALSE;
+ bool opt_create_keypair = FALSE;
char *silcd_config_file = NULL;
struct sigaction sa;
if (argc > 1) {
while ((opt = getopt_long(argc, argv, "f:p:d::xhFVC:",
long_opts, &option_index)) != EOF) {
- switch(opt)
- {
+ switch(opt) {
case 'h':
silc_usage();
break;
case 'V':
printf("SILCd Secure Internet Live Conferencing daemon, "
"version %s (base: SILC Toolkit %s)\n",
- silc_dist_version, silc_version);
+ silc_dist_version, silc_version);
printf("(c) 1997 - 2002 Pekka Riikonen "
"<priikone@silcnet.org>\n");
exit(0);
default:
silc_usage();
break;
- }
+ }
}
}
if (silcd->config == NULL)
goto fail;
silcd->config_file = silcd_config_file;
+ /* Since silc_server_config_alloc returns an unreferenced config object
+ we must immediately increment it. */
+ silc_server_config_ref(&silcd->config_ref, silcd->config, silcd->config);
/* Check for another silcd running */
silc_server_checkpid(silcd);
/* Stop the server and free it. */
silc_server_stop(silcd);
silc_server_free(silcd);
- silc_server_config_destroy(silcd->config);
/* Flush the logging system */
silc_log_flush_all();
--- /dev/null
+Makefile
+Makefile.in
--- /dev/null
+Makefile
+Makefile.in
--- /dev/null
+Makefile
+Makefile.in
--- /dev/null
+Makefile
+Makefile.in
--- /dev/null
+Makefile
+Makefile.in
--- /dev/null
+Makefile
+Makefile.in