+Fri Dec 28 12:43:22 EET 2001 Pekka Riikonen <priikone@silcnet.org>
+
+ * Cancel protocol and NULL sock->protocol if timeout
+ occurred during protocol. Affected file silcd/server.c.
+
+ * Cancel protocol timeouts always before calling the final
+ callback, to assure that after final callback is called
+ no other state will be called for the protocol anymore.
+ Affected file silcd/protocol.c.
+
+ * Print error log if incoming connection configuration could
+ not be found. Affected file silcd/server.c.
+
+ * Fixed JOIN command to correctly save the founder mode
+ to the client on normal SILC server, when the channel
+ was created by the router. Affected file silcd/command.c.
+
+ * Fixed LIST command (hopefully) to send correct reply
+ packets. Affected file silcd/command.c.
+
Thu Dec 20 16:14:52 CET 2001 Pekka Riikonen <priikone@silcnet.org>
* The silc_packet_receive_process now returns FALSE if the
printed only once and not everytime it fails (produces
too much useless log). Affected file lib/silcutil/silclog.c.
+Wed Dec 19 18:21:51 CET 2001 Johnny Mnemonic <johnny@themnemonic.org>
+
+ * Made the silc_server_daemonise() function more readable.
+ Affected file silcd/server.c.
+
+ * Pid file is now optional, the user may comment it out from
+ the config file. Removed define SILC_SERVER_PID_FILE, we
+ don't need a default any longer. Affected file
+ configure.in.pre, lib/Makefile.am.pre.
+
+ * Make some use of the pid file. The server now dies at startup
+ if it detects a valid pid file on his path. The server would
+ die anyway in this circumstance, because of the bind() failure.
+ Affected file silcd/silcd.c.
+
+ * No longer compiling lib/dotconf.
+
Mon Dec 17 18:24:27 EET 2001 Pekka Riikonen <priikone@silcnet.org>
* Fixed JOIN command parsing not to crash. Affected file
behaviour and maybe should be removed. The changer should always
get the one it wants and not have the formatted nickname.
- o strerror messages from premature EOF's to signoff messages.
-
o Additions to do after protocol version 1.1:
o Fix the NICK_CHANGE notify handling not to create new entry
TODO/bugs In SILC Server
========================
- o User modes did not show correctly on normal server but looked ok
- on router. Join channel from normal server, join same from router
- and see the user modes. The founder of the channel (on normal server)
- appears correctly on router but incorrectly (no modes) on normal
- server.
-
- o LIST command reply sending is broken. It is possible it does not
- end the list with LIST_END, but sends LIST_ENTRY as last entry.
+ o strerror messages from premature EOF's to signoff messages.
o Backup router related issues
/* Default configuration file */
#undef SILC_SERVER_CONFIG_FILE
-/* Default pid file */
-#undef SILC_SERVER_PID_FILE
-
/* Multi-thread support */
#undef SILC_THREADS
#undef SILC_HAVE_PTHREAD
SilcChannelEntry *gch,
uint32 gch_count)
{
- int i;
+ int i, k;
SilcBuffer packet, idp;
SilcChannelEntry entry;
SilcCommandStatus status;
char *topic;
unsigned char usercount[4];
uint32 users;
+ int valid_lcount = 0, valid_rcount = 0;
- for (i = 0; i < lch_count; i++)
+ for (i = 0; i < lch_count; i++) {
if (lch[i]->mode & SILC_CHANNEL_MODE_SECRET)
lch[i] = NULL;
- for (i = 0; i < gch_count; i++)
+ else
+ valid_lcount++;
+ }
+ for (i = 0; i < gch_count; i++) {
if (gch[i]->mode & SILC_CHANNEL_MODE_SECRET)
gch[i] = NULL;
+ else
+ valid_rcount++;
+ }
status = SILC_STATUS_OK;
if ((lch_count + gch_count) > 1)
status = SILC_STATUS_LIST_START;
/* Local list */
- for (i = 0; i < lch_count; i++) {
+ for (i = 0, k = 0; i < lch_count; i++) {
entry = lch[i];
if (!entry)
continue;
- if (i >= 1)
+ if (k >= 1)
status = SILC_STATUS_LIST_ITEM;
- if (i >= 1 && i == lch_count - 1 && !gch_count)
+ if (valid_lcount > 1 && k == valid_lcount - 1 && !valid_rcount)
status = SILC_STATUS_LIST_END;
idp = silc_id_payload_encode(entry->id, SILC_ID_CHANNEL);
packet->len, FALSE);
silc_buffer_free(packet);
silc_buffer_free(idp);
+ k++;
}
/* Global list */
- for (i = 0; i < gch_count; i++) {
+ for (i = 0, k = 0; i < gch_count; i++) {
entry = gch[i];
if (!entry)
continue;
- if (i >= 1)
+ if (k >= 1)
status = SILC_STATUS_LIST_ITEM;
- if (i >= 1 && i == gch_count - 1)
+ if (valid_rcount > 1 && k == valid_rcount - 1)
status = SILC_STATUS_LIST_END;
idp = silc_id_payload_encode(entry->id, SILC_ID_CHANNEL);
packet->len, FALSE);
silc_buffer_free(packet);
silc_buffer_free(idp);
+ k++;
}
}
if (cmd->pending && context2) {
SilcServerCommandReplyContext reply =
(SilcServerCommandReplyContext)context2;
+
if (silc_command_get(reply->payload) == SILC_COMMAND_JOIN) {
tmp = silc_argument_get_arg_type(reply->args, 6, NULL);
SILC_GET32_MSB(created, tmp);
create_key = FALSE; /* Router returned the key already */
}
+
+ if (silc_command_get(reply->payload) == SILC_COMMAND_WHOIS)
+ created = TRUE;
}
/* If the channel does not have global users and is also empty the client
if (ctx->timeout_task)
silc_schedule_task_del(server->schedule, ctx->timeout_task);
+ /* Assure that after calling final callback there cannot be pending
+ executions for this protocol anymore. This just unregisters any
+ timeout callbacks for this protocol. */
+ silc_protocol_cancel(protocol, server->schedule);
+
/* Call the final callback */
if (protocol->final_callback)
silc_protocol_execute_final(protocol, server->schedule);
if (ctx->timeout_task)
silc_schedule_task_del(server->schedule, ctx->timeout_task);
+ /* Assure that after calling final callback there cannot be pending
+ executions for this protocol anymore. This just unregisters any
+ timeout callbacks for this protocol. */
+ silc_protocol_cancel(protocol, server->schedule);
+
/* On error the final callback is always called. */
if (protocol->final_callback)
silc_protocol_execute_final(protocol, server->schedule);
if (ctx->timeout_task)
silc_schedule_task_del(server->schedule, ctx->timeout_task);
+ /* Assure that after calling final callback there cannot be pending
+ executions for this protocol anymore. This just unregisters any
+ timeout callbacks for this protocol. */
+ silc_protocol_cancel(protocol, server->schedule);
+
/* On error the final callback is always called. */
if (protocol->final_callback)
silc_protocol_execute_final(protocol, server->schedule);
if (ctx->timeout_task)
silc_schedule_task_del(server->schedule, ctx->timeout_task);
+ /* Assure that after calling final callback there cannot be pending
+ executions for this protocol anymore. This just unregisters any
+ timeout callbacks for this protocol. */
+ silc_protocol_cancel(protocol, server->schedule);
+
/* Protocol has ended, call the final callback */
if (protocol->final_callback)
silc_protocol_execute_final(protocol, server->schedule);
if (ctx->timeout_task)
silc_schedule_task_del(server->schedule, ctx->timeout_task);
+ /* Assure that after calling final callback there cannot be pending
+ executions for this protocol anymore. This just unregisters any
+ timeout callbacks for this protocol. */
+ silc_protocol_cancel(protocol, server->schedule);
+
/* On error the final callback is always called. */
if (protocol->final_callback)
silc_protocol_execute_final(protocol, server->schedule);
if (ctx->timeout_task)
silc_schedule_task_del(server->schedule, ctx->timeout_task);
+ /* Assure that after calling final callback there cannot be pending
+ executions for this protocol anymore. This just unregisters any
+ timeout callbacks for this protocol. */
+ silc_protocol_cancel(protocol, server->schedule);
+
/* On error the final callback is always called. */
if (protocol->final_callback)
silc_protocol_execute_final(protocol, server->schedule);
encrypted with the new key so set the decryption key to the new key */
silc_server_protocol_rekey_generate(server, ctx, FALSE);
+ /* Assure that after calling final callback there cannot be pending
+ executions for this protocol anymore. This just unregisters any
+ timeout callbacks for this protocol. */
+ silc_protocol_cancel(protocol, server->schedule);
+
/* Protocol has ended, call the final callback */
if (protocol->final_callback)
silc_protocol_execute_final(protocol, server->schedule);
silc_ske_abort(ctx->ske, ctx->ske->status);
}
+ /* Assure that after calling final callback there cannot be pending
+ executions for this protocol anymore. This just unregisters any
+ timeout callbacks for this protocol. */
+ silc_protocol_cancel(protocol, server->schedule);
+
/* On error the final callback is always called. */
if (protocol->final_callback)
silc_protocol_execute_final(protocol, server->schedule);
* We have received failure from remote
*/
+ /* Assure that after calling final callback there cannot be pending
+ executions for this protocol anymore. This just unregisters any
+ timeout callbacks for this protocol. */
+ silc_protocol_cancel(protocol, server->schedule);
+
/* On error the final callback is always called. */
if (protocol->final_callback)
silc_protocol_execute_final(protocol, server->schedule);
return FALSE;
}
-/* Fork server to background and set gid+uid to non-root */
+/* Fork server to background */
void silc_server_daemonise(SilcServer server)
{
int i;
- i = fork ();
+ SILC_LOG_DEBUG(("Forking SILC server to background"));
- if (i) {
- if (i > 0) {
- if (geteuid())
- SILC_LOG_DEBUG(("Server started as user"));
- else
- SILC_LOG_DEBUG(("Server started as root. Dropping privileges."));
+ i = fork();
- SILC_LOG_DEBUG(("Forking SILC server to background"));
- exit(0);
- } else {
- SILC_LOG_DEBUG(("fork() failed, cannot proceed"));
- exit(1);
- }
+ if (i < 0) {
+ SILC_LOG_DEBUG(("fork() failed, cannot proceed"));
+ exit(1);
+ }
+ else if (i) {
+ if (geteuid())
+ SILC_LOG_DEBUG(("Server started as user"));
+ else
+ SILC_LOG_DEBUG(("Server started as root. Dropping privileges."));
+ exit(0);
}
setsid();
}
{
/* Are we executing silcd as root or a regular user? */
if (!geteuid()) {
-
struct passwd *pw;
struct group *gr;
char *user, *group;
sock->hostname,
port);
if (!cconfig && !sconfig && !rconfig) {
+ SILC_LOG_INFO(("Connection %s (%s) is not allowed",
+ sock->hostname, sock->ip));
silc_server_disconnect_remote(server, sock,
"Server closed connection: "
"Connection refused");
exit(0);
}
+/* Dies if a *valid* pid file exists already */
+
+static void silc_checkpid(SilcServer silcd)
+{
+ if (silcd->config->pidfile && silcd->config->pidfile->pid_file) {
+ int oldpid;
+ char *buf;
+ uint32 buf_len;
+
+ SILC_LOG_DEBUG(("Checking for another silcd running"));
+ buf = silc_file_readfile(silcd->config->pidfile->pid_file, &buf_len);
+ if (!buf)
+ return;
+ oldpid = atoi(buf);
+ silc_free(buf);
+ if (oldpid <= 0)
+ return;
+ kill(oldpid, SIGCHLD); /* this signal does nothing, check if alive */
+ if (errno != ESRCH) {
+ fprintf(stderr, "\nI detected another daemon running with the same pid file.\n");
+ fprintf(stderr, "Please change the config file, or erase the %s\n",
+ silcd->config->pidfile->pid_file);
+ exit(1);
+ }
+ }
+}
+
int main(int argc, char **argv)
{
int ret;
char *config_file = NULL;
SilcServer silcd;
struct sigaction sa;
- char pid[10];
silc_debug = FALSE;
silc_debug = TRUE;
silc_debug_hexdump = TRUE;
silc_log_set_debug_string(optarg);
+ foreground = TRUE;
#ifndef SILC_DEBUG
fprintf(stdout,
"Run-time debugging is not enabled. To enable it recompile\n"
if (silcd->config == NULL)
goto fail;
+ /* Check for another silcd running */
+ silc_checkpid(silcd);
+
/* Initialize the server */
ret = silc_server_init(silcd);
if (ret == FALSE)
sigemptyset(&sa.sa_mask);
sigaction(SIGPIPE, &sa, NULL);
- if ((silc_debug == FALSE) && (foreground == FALSE))
- /* Before running the server, fork to background. */
+ /* Before running the server, fork to background. */
+ if (!foreground)
silc_server_daemonise(silcd);
- /* Set /var/run/silcd.pid */
- unlink(SILC_SERVER_PID_FILE);
- memset(pid, 0, sizeof(pid));
- snprintf(pid, sizeof(pid) - 1, "%d\n", getpid());
+ /* If set, write pid to file */
if (silcd->config->pidfile && silcd->config->pidfile->pid_file) {
- silc_file_writefile(silcd->config->pidfile->pid_file, pid, strlen(pid));
- } else {
- silc_file_writefile(SILC_SERVER_PID_FILE, pid, strlen(pid));
+ char buf[10];
+ unlink(silcd->config->pidfile->pid_file);
+ snprintf(buf, sizeof(buf) - 1, "%d\n", getpid());
+ silc_file_writefile(silcd->config->pidfile->pid_file, buf, strlen(buf));
}
-
+
/* Drop root. */
silc_server_drop(silcd);
#define SILC_SERVER_CONFIG_FILE "/etc/silc/silcd.conf"
#endif
-#ifndef SILC_SERVER_PID_FILE
-#define SILC_SERVER_PID_FILE "/var/run/silcd.pid"
-#endif
-
#define SILC_SERVER_PUBLIC_KEY_NAME "/silcd.pub"
#define SILC_SERVER_PRIVATE_KEY_NAME "/silcd.prv"
esac ],
)
AC_SUBST(PIDFILE)
-AC_DEFINE_UNQUOTED(SILC_SERVER_PID_FILE, "$PIDFILE")
#
# Native WIN32 compilation under cygwin
#
# Other configure scripts
#
-AC_CONFIG_SUBDIRS(lib/dotconf)
+#AC_CONFIG_SUBDIRS(lib/dotconf)
AC_CONFIG_SUBDIRS(lib/trq)
AC_CONFIG_SUBDIRS(irssi)
AC_CONFIG_SUBDIRS(lib/silcmath/mpi)
# SILC Server distribution
server_SUBDIRS=lib silcd doc includes
-server_SUBDIRS_lib=contrib silccore silccrypt silcsim silcmath silcske silcutil trq dotconf silcsftp
+server_SUBDIRS_lib=contrib silccore silccrypt silcsim silcmath silcske silcutil trq silcsftp
server_SUBDIRS_doc=$(COMMONDIRS)
server_DISTLABEL=SILC_DIST_SERVER
server_EXTRA_DIST=#
<font face="Helvetica">
<font size="6"><b>SILC Protocol White Paper</b></font><br>
-<font size="2">Version 1.0 / 03 Aug 2001</font>
+<font size="2">Version 1.1 / 01 Jan 2002</font>
<p>
<h1>Introduction</h1>
<p>
<p>
-(c) Copyright 2001 Pekka Riikonen
+(c) Copyright 2001 - 2002 Pekka Riikonen
(<a href="mailto:priikone at silcnet.org">priikone at silcnet.org</a>)
<p>
This document is free document; you can redistribute it and/or modify
method of private message delivery is very simple and recommended.
+<p><br>
+<h1>Secure File Transfers</h1>
+
+
<p><br>
<h1>Conclusion</h1>
silcutil \
silcclient \
silcsftp \
- dotconf \
trq
-# zlib
+# dotconf
+# zlib
SUBDIRS = SILC_DISTRIBUTION_SUBDIRS
DIST_SUBDIRS = SILC_DISTRIBUTION_SUBDIRS
silcske \
silcutil \
silcsftp \
- trq \
- dotconf
+ trq
+# dotconf
# SILC Client Library dirs
SILCCLIENTLIB_DIRS = \