X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=apps%2Fsilcd%2Fsilcd.c;fp=apps%2Fsilcd%2Fsilcd.c;h=0000000000000000000000000000000000000000;hb=72c2de619079457f7a68100eb13385275a424a23;hp=14e3657f968d6fd64e6fdbb4b09caf8f00ea215a;hpb=e7b6c157b80152bf9fb9266e6bdd93f9fb0db776;p=runtime.git diff --git a/apps/silcd/silcd.c b/apps/silcd/silcd.c deleted file mode 100644 index 14e3657f..00000000 --- a/apps/silcd/silcd.c +++ /dev/null @@ -1,775 +0,0 @@ -/* - - silcd.c - - Author: Pekka Riikonen - - Copyright (C) 1997 - 2007 Pekka Riikonen - - This program 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; version 2 of the License. - - This program 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. - -*/ -/* - * Created: Wed Mar 19 00:17:12 1997 - * - * This is the main program for the SILC daemon. This parses command - * line arguments and creates the server object. - */ -/* $Id$ */ - -#include "serverincludes.h" -#include "server_internal.h" -#include "silcversion.h" - -/* For now, we'll have this one server context global for this module. */ -static SilcServer silcd; - -static void silc_usage(void); - -#ifdef HAVE_GETOPT_LONG -/* Long command line options */ -static struct option long_opts[] = -{ - { "config-file", 1, NULL, 'f' }, - { "passphrase", 1, NULL, 'p' }, - { "debug", 2, NULL, 'd' }, - { "debug-level", 1, NULL, 'D' }, - { "hexdump", 0, NULL, 'x' }, - { "help", 0, NULL, 'h' }, - { "foreground", 0, NULL, 'F' }, - { "version", 0, NULL,'V' }, - - /* Key management options */ - { "create-key-pair", 1, NULL, 'C' }, - { "pkcs", 1, NULL, 10 }, - { "bits", 1, NULL, 11 }, - { "identifier", 1, NULL, 12 }, - - { NULL, 0, NULL, 0 } -}; -#endif /* HAVE_GETOPT_LONG */ - -/* Command line option variables */ -static char *opt_keypath = NULL; -static char *opt_pkcs = "rsa"; -static char *opt_identifier = NULL; -static int opt_bits = 2048; - -/* Prints out the usage of silc client */ - -static void silc_usage(void) -{ - printf("" -"Usage: silcd [options]\n" -"\n" -" Generic Options:\n" -" -f --config-file=FILE Alternate configuration file\n" -" -d --debug=string Enable debugging (Implies --foreground)\n" -" -D --debug-level=level Enable debugging (Implies --foreground)\n" -" -x --hexdump Enable hexdumps (Implies --debug)\n" -" -h --help Display this message\n" -" -F --foreground Dont fork\n" -" -V --version Display version\n" -"\n" -" Key Management Options:\n" -" -C, --create-key-pair=PATH Create new public key pair\n" -" --pkcs=PKCS Set the PKCS of the public key pair\n" -" --bits=VALUE Set length of the public key pair\n" -" --identifier=IDENTIFIER Public key identifier\n" -"\n" -" The public key identifier may be of the following format:\n" -"\n" -" UN=, HN=, RN=, E=,\n" -" O=, C=\n" -"\n" -" The UN and HN must be provided, the others are optional. If the\n" -" --identifier option is not used an identifier will be created for\n" -" the public key automatically.\n" -"\n" -" Example identifier: \"UN=foobar, HN=foo.bar.com, RN=Foo T. Bar, \n" -" E=foo@bar.com, C=FI\"\n" -"\n"); - exit(0); -} - -/* Die if a *valid* pid file exists already */ - -static void silc_server_checkpid(SilcServer silcd) -{ - if (silcd->config->server_info->pid_file) { - int oldpid; - char *buf; - SilcUInt32 buf_len; - - SILC_LOG_DEBUG(("Checking for another silcd running")); - buf = silc_file_readfile(silcd->config->server_info->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->server_info->pid_file); - exit(1); - } - } -} - -/* Drop root privileges. If some system call fails, die. */ - -static void silc_server_drop_privs(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() */ -} - -SILC_TASK_CALLBACK(got_hup) -{ - /* First, reset all log files (they might have been deleted) */ - silc_log_reset_all(); - - /* Rehash the configuration file */ - silc_server_rehash(silcd); -} - -SILC_TASK_CALLBACK(stop_server) -{ - /* Stop scheduler, the program will stop eventually after noticing - that the scheduler is down. */ - silc_schedule_stop(silcd->schedule); -} - -/* Dump server statistics into a file into /tmp directory */ - -SILC_TASK_CALLBACK(dump_stats) -{ - FILE *fdd; - int fild; - char filename[256]; - - memset(filename, 0, sizeof(filename)); - snprintf(filename, sizeof(filename) - 1, "/tmp/silcd.%d.stats-XXXXXX", getpid()); - fild = mkstemp(filename); - if (fild == -1) - return; - - fdd = fdopen(fild, "w"); - if (fdd == NULL) { - close(fild); - unlink(filename); - return; - } - -#define STAT_OUTPUT(fmt, stat) fprintf(fdd, fmt "\n", (int)stat); - - fprintf(fdd, "SILC Server %s Statistics\n\n", silcd->server_name); - fprintf(fdd, "Local Stats:\n"); - STAT_OUTPUT(" My clients : %d", silcd->stat.my_clients); - STAT_OUTPUT(" My servers : %d", silcd->stat.my_servers); - STAT_OUTPUT(" My routers : %d", silcd->stat.my_routers); - STAT_OUTPUT(" My channels : %d", silcd->stat.my_channels); - STAT_OUTPUT(" My joined users : %d", silcd->stat.my_chanclients); - STAT_OUTPUT(" My aways : %d", silcd->stat.my_aways); - STAT_OUTPUT(" My detached clients : %d", silcd->stat.my_detached); - STAT_OUTPUT(" My server operators : %d", silcd->stat.my_server_ops); - STAT_OUTPUT(" My router operators : %d", silcd->stat.my_router_ops); - fprintf(fdd, "\nGlobal Stats:\n"); - STAT_OUTPUT(" Cell clients : %d", silcd->stat.cell_clients); - STAT_OUTPUT(" Cell servers : %d", silcd->stat.cell_servers); - STAT_OUTPUT(" Cell channels : %d", silcd->stat.cell_channels); - STAT_OUTPUT(" Cell joined users : %d", silcd->stat.cell_chanclients); - STAT_OUTPUT(" All clients : %d", silcd->stat.clients); - STAT_OUTPUT(" All servers : %d", silcd->stat.servers); - STAT_OUTPUT(" All routers : %d", silcd->stat.routers); - STAT_OUTPUT(" All channels : %d", silcd->stat.channels); - STAT_OUTPUT(" All joined users : %d", silcd->stat.chanclients); - STAT_OUTPUT(" All aways : %d", silcd->stat.aways); - STAT_OUTPUT(" All detached clients : %d", silcd->stat.detached); - STAT_OUTPUT(" All server operators : %d", silcd->stat.server_ops); - STAT_OUTPUT(" All router operators : %d", silcd->stat.router_ops); - fprintf(fdd, "\nGeneral Stats:\n"); - STAT_OUTPUT(" Connection attempts : %d", silcd->stat.conn_attempts); - STAT_OUTPUT(" Connection failures : %d", silcd->stat.conn_failures); - STAT_OUTPUT(" Authentication attempts : %d", silcd->stat.auth_attempts); - STAT_OUTPUT(" Authentication failures : %d", silcd->stat.auth_failures); - STAT_OUTPUT(" Packets sent : %d", silcd->stat.packets_sent); - STAT_OUTPUT(" Packets received : %d", silcd->stat.packets_received); - STAT_OUTPUT(" Commands sent : %d", silcd->stat.commands_sent); - STAT_OUTPUT(" Commands received : %d", silcd->stat.commands_received); - STAT_OUTPUT(" Connections : %d", silcd->stat.conn_num); - -#undef STAT_OUTPUT - -#ifdef SILC_DEBUG - /* Dump internal flags */ - fprintf(fdd, "\nDumping internal flags\n"); - fprintf(fdd, " server_type : %d\n", silcd->server_type); - fprintf(fdd, " standalone : %d\n", silcd->standalone); - fprintf(fdd, " listenning : %d\n", silcd->listenning); - fprintf(fdd, " background : %d\n", silcd->background); - fprintf(fdd, " backup_router : %d\n", silcd->backup_router); - fprintf(fdd, " backup_primary : %d\n", silcd->backup_primary); - fprintf(fdd, " backup_noswitch : %d\n", silcd->backup_noswitch); - fprintf(fdd, " backup_closed : %d\n", silcd->backup_closed); - fprintf(fdd, " wait_backup : %d\n", silcd->wait_backup); - if (silcd->router) - fprintf(fdd, " primary router : %s\n", - silcd->router->server_name ? silcd->router->server_name : ""); - - /* Dump connections */ - { - SilcPacketStream s; - SilcDList conns = silc_packet_engine_get_streams(silcd->packet_engine); - - fprintf(fdd, "\nDumping connections\n"); - silc_dlist_start(conns); - while ((s = silc_dlist_get(conns))) { - const char *hostname, *ip; - SilcUInt16 port; - SilcSocket sock; - SilcIDListData idata = silc_packet_get_context(s); - if (!silc_socket_stream_get_info(silc_packet_stream_get_stream(s), - &sock, &hostname, &ip, &port)) - continue; - fprintf(fdd, " %d: host %s ip %s port %d type %d\n", - sock, hostname ? hostname : "N/A", - ip ? ip : "N/A", port, idata ? idata->conn_type : 0); - } - silc_dlist_uninit(conns); - } - - /* Dump lists */ - { - SilcList list; - SilcIDCacheEntry id_cache = NULL; - SilcServerEntry server_entry; - SilcClientEntry client_entry; - SilcChannelEntry channel_entry; - int c; - - fprintf(fdd, "\nDumping databases\n"); - - if (silc_idcache_get_all(silcd->local_list->servers, &list)) { - c = 1; - fprintf(fdd, "\nServers in local-list:\n"); - while ((id_cache = silc_list_get(list))) { - server_entry = (SilcServerEntry)id_cache->context; - fprintf(fdd, " %d: name %s id %s status 0x%x\n", c, - server_entry->server_name ? server_entry->server_name : - "N/A", server_entry->id ? - silc_id_render(server_entry->id, SILC_ID_SERVER) : "N/A", - server_entry->data.status); - c++; - } - } - if (silc_idcache_get_all(silcd->global_list->servers, &list)) { - fprintf(fdd, "\nServers in global-list:\n"); - c = 1; - while ((id_cache = silc_list_get(list))) { - server_entry = (SilcServerEntry)id_cache->context; - fprintf(fdd, " %d: name %s id %s status 0x%x\n", c, - server_entry->server_name ? server_entry->server_name : - "N/A", server_entry->id ? - silc_id_render(server_entry->id, SILC_ID_SERVER) : "N/A", - server_entry->data.status); - c++; - } - } - if (silc_idcache_get_all(silcd->local_list->clients, &list)) { - fprintf(fdd, "\nClients in local-list:\n"); - c = 1; - while ((id_cache = silc_list_get(list))) { - client_entry = (SilcClientEntry)id_cache->context; - server_entry = client_entry->router; - fprintf(fdd, " %d: name %s id %s status 0x%x from %s\n", c, - client_entry->nickname ? client_entry->nickname : - (unsigned char *)"N/A", client_entry->id ? - silc_id_render(client_entry->id, SILC_ID_CLIENT) : "N/A", - client_entry->data.status, server_entry ? - server_entry->server_name ? server_entry->server_name : - "N/A" : "local"); - c++; - } - } - if (silc_idcache_get_all(silcd->global_list->clients, &list)) { - fprintf(fdd, "\nClients in global-list:\n"); - c = 1; - while ((id_cache = silc_list_get(list))) { - client_entry = (SilcClientEntry)id_cache->context; - server_entry = client_entry->router; - fprintf(fdd, " %d: name %s id %s status 0x%x from %s\n", c, - client_entry->nickname ? client_entry->nickname : - (unsigned char *)"N/A", client_entry->id ? - silc_id_render(client_entry->id, SILC_ID_CLIENT) : "N/A", - client_entry->data.status, server_entry ? - server_entry->server_name ? server_entry->server_name : - "N/A" : "local"); - c++; - } - } - if (silc_idcache_get_all(silcd->local_list->channels, &list)) { - fprintf(fdd, "\nChannels in local-list:\n"); - c = 1; - while ((id_cache = silc_list_get(list))) { - channel_entry = (SilcChannelEntry)id_cache->context; - fprintf(fdd, " %d: name %s id %s\n", c, - channel_entry->channel_name ? channel_entry->channel_name : - "N/A", channel_entry->id ? - silc_id_render(channel_entry->id, SILC_ID_CHANNEL) : "N/A"); - c++; - } - } - if (silc_idcache_get_all(silcd->global_list->channels, &list)) { - fprintf(fdd, "\nChannels in global-list:\n"); - c = 1; - while ((id_cache = silc_list_get(list))) { - channel_entry = (SilcChannelEntry)id_cache->context; - fprintf(fdd, " %d: name %s id %s\n", c, - channel_entry->channel_name ? channel_entry->channel_name : - "N/A", channel_entry->id ? - silc_id_render(channel_entry->id, SILC_ID_CHANNEL) : "N/A"); - c++; - } - } - } -#endif - - fflush(fdd); - fclose(fdd); -} - -#ifdef SILC_DEBUG - -typedef struct { - int level; - const char *string; -} DebugLevel; - -static DebugLevel debug_levels[] = { - /* Very basic stuff from silcd/ */ - { 3, "silcd\\.c,server\\.c" }, - - /* More stuff from silcd/ */ - { 7, "silcd\\.c,server\\.c,command\\.c,server_backup\\.c,packet_send\\.c" }, - - /* All basic stuff from silcd/ */ - { 10, "silc_server_*" }, - - /* All from silcd/ */ - { 15, "*silcd*,*serverid*,silc_server_*,*idlist*" }, - - /* All from silcd/ and basic stuff from libs */ - { 20, "*silcd*,*serverid*,silc_server_*,*idlist*,*silcconauth*,*silcske*" }, - - /* All from silcd/ and more stuff from libs */ - { 25, "*silcd*,*serverid*,silc_server_*,*idlist*,*silcconauth*," - "*silcpacket*,*ske*,*silcrng*" }, - - /* All from silcd/ and even more stuff from libs */ - { 30, "*silcd*,*serverid*,silc_server_*,*idlist*,*silcconauth*," - "*silcpacket*,*ske*,*silcrng*,*command*,*channel*,*private*,*notify*" }, - - /* All from silcd/ and even more stuff from libs + all from silccore */ - { 35, "*silcd*,*serverid*,silc_server_*,*idlist*,*silcconauth*," - "*silcpacket*,*ske*,*silcrng*,*command*,*channel*,*private*,*notify*" - "*silcid*,*argument*" }, - - /* All from silcd/, all from silccore, silccrypt and silcmath */ - { 40, "*silcd*,*serverid*,silc_server_*,*idlist*,*silcconauth*," - "*silcpacket*,*ske*,*silcrng*,*command*,*channel*,*private*,*notify*" - "*silcid*,*argument*,*pkcs*,*hmac*,*hash*,*cipher*,silc_math*" }, - - /* All from silcd/, all from silccore, silccrypt and silcmath + stuff - from silcutil */ - { 45, "*silcd*,*serverid*,silc_server_*,*idlist*,*silcconauth*," - "*silcpacket*,*ske*,*silcrng*,*command*,*channel*,*private*,*notify*" - "*silcid*,*argument*,*pkcs*,*hmac*,*hash*,*cipher*,silc_math*,*sim*" - "*sockconn*" }, - - /* All from silcd/, all from silccore, silccrypt and silcmath + more stuff - from silcutil */ - { 50, "*silcd*,*serverid*,silc_server_*,*idlist*,*silcconauth*," - "*silcpacket*,*ske*,*silcrng*,*command*,*channel*,*private*,*notify*" - "*silcid*,*argument*,*pkcs*,*hmac*,*hash*,*cipher*,silc_math*,*sim*" - "*sockconn*,*net*" }, - - /* All from silcd/, all from silccore, silccrypt and silcmath + more stuff - from silcutil */ - { 55, "*silcd*,*serverid*,silc_server_*,*idlist*,*silcconauth*," - "*silcpacket*,*ske*,*silcrng*,*command*,*channel*,*private*,*notify*" - "*silcid*,*argument*,*pkcs*,*hmac*,*hash*,*cipher*,silc_math*,*sim*" - "*sockconn*,*net*,*log*,*config*" }, - - /* All */ - { 90, "*" }, - - { -1, NULL }, -}; - -static void silc_get_debug_level(int level) -{ - int i; - - if (level < 0) - return; - - for (i = 0; debug_levels[i].string; i++) - if (level <= debug_levels[i].level) { - silc_log_set_debug_string(debug_levels[i].string); - break; - } -} -#endif /* SILC_DEBUG */ - -/* This function should not be called directly but through the appropriate - wrapper macro defined in server.h */ - -void silc_server_stderr(SilcLogType type, char *message) -{ - if (silcd->background) { - char *p, *n = message; - - /* remove newlines if we are going to output it to a log file */ - for (p = n; *p; p++) { - if (*p != '\n') { - if (p != n) - *n = *p; - n++; - } - } - *n = 0; - - /* the message is freed inside the logging function */ - silc_log_output(type, message); - } - else { - fprintf(stderr, "%s\n", message); - silc_free(message); - } -} - -int main(int argc, char **argv) -{ - int ret, opt, option_index; - SilcBool foreground = FALSE; - SilcBool opt_create_keypair = FALSE; - char *silcd_config_file = NULL; - struct sigaction sa; - - /* Parse command line arguments */ - if (argc > 1) { -#ifdef HAVE_GETOPT_LONG - while ((opt = getopt_long(argc, argv, "f:p:d:D:xhFVC:", - long_opts, &option_index)) != EOF) { -#else - while ((opt = getopt(argc, argv, "f:p:d:D:xhFVC:")) != EOF) { -#endif /* HAVE_GETOPT_LONG */ - 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); - printf("(c) 1997 - 2007 Pekka Riikonen " - "\n"); - exit(0); - break; - case 'd': -#ifdef SILC_DEBUG - silc_log_debug(TRUE); - silc_log_quick(TRUE); - if (optarg) - silc_log_set_debug_string(optarg); - foreground = TRUE; /* implied */ -#else - fprintf(stderr, - "Run-time debugging is not enabled. To enable it recompile\n" - "the server with --enable-debug configuration option.\n"); -#endif - break; - case 'D': -#ifdef SILC_DEBUG - silc_log_debug(TRUE); - silc_log_quick(TRUE); - if (optarg) - silc_get_debug_level(atoi(optarg)); - foreground = TRUE; /* implied */ -#else - fprintf(stderr, - "Run-time debugging is not enabled. To enable it recompile\n" - "the server with --enable-debug configuration option.\n"); -#endif - break; - case 'x': -#ifdef SILC_DEBUG - silc_log_debug(TRUE); - silc_log_debug_hexdump(TRUE); - silc_log_quick(TRUE); - foreground = TRUE; /* implied */ -#else - fprintf(stderr, - "Run-time debugging is not enabled. To enable it recompile\n" - "the server with --enable-debug configuration option.\n"); -#endif - break; - case 'f': - silcd_config_file = strdup(optarg); - break; - case 'F': - foreground = TRUE; - break; - - /* - * Key management options - */ - case 'C': - opt_create_keypair = TRUE; - if (optarg) - opt_keypath = strdup(optarg); - break; - case 10: - if (optarg) - opt_pkcs = strdup(optarg); - break; - case 11: - if (optarg) - opt_bits = atoi(optarg); - break; - case 12: - if (optarg) - opt_identifier = strdup(optarg); - break; - - default: - silc_usage(); - break; - } - } - } - - if (opt_create_keypair == TRUE) { - /* Create new key pair and exit */ - char pubfile[256], prvfile[256]; - - memset(pubfile, 0, sizeof(pubfile)); - memset(prvfile, 0, sizeof(prvfile)); - snprintf(pubfile, sizeof(pubfile) - 1, "%s/silcd.pub", opt_keypath); - snprintf(prvfile, sizeof(prvfile) - 1, "%s/silcd.prv", opt_keypath); - - silc_cipher_register_default(); - silc_pkcs_register_default(); - silc_hash_register_default(); - silc_hmac_register_default(); - if (!silc_create_key_pair(opt_pkcs, opt_bits, pubfile, prvfile, - opt_identifier, "", NULL, NULL, FALSE)) - exit(1); - exit(0); - } - - /* Default configuration file */ - if (!silcd_config_file) - silcd_config_file = strdup(SILC_SERVER_CONFIG_FILE); - - /* Create SILC Server object */ - ret = silc_server_alloc(&silcd); - if (ret == FALSE) - goto fail; - - /* Register default crypto stuff since we are going to need them - in the configuration file parsing phase */ - silc_cipher_register_default(); - silc_pkcs_register_default(); - silc_hash_register_default(); - silc_hmac_register_default(); - - /* Read configuration files */ - silcd->config = silc_server_config_alloc(silcd_config_file, silcd); - if (silcd->config == NULL) - goto fail; - silcd->config_file = silcd_config_file; - - /* Unregister the default crypto stuff so that configuration takes effect */ - silc_cipher_unregister_all(); - /* silc_pkcs_unregister_all(); MUST NOT do this anymore; SilcPublicKey - parsed from config file references pointers so we cannot unregister */ - silc_hash_unregister_all(); - silc_hmac_unregister_all(); - - /* Check for another silcd running */ - silc_server_checkpid(silcd); - - /* Initialize the server */ - if (silc_server_init(silcd) == FALSE) - goto fail; - - /* Ignore some signals */ - sa.sa_handler = SIG_IGN; - sa.sa_flags = 0; - sigemptyset(&sa.sa_mask); -#if defined(SIGPIPE) - sigaction(SIGPIPE, &sa, NULL); /* Ignore broken pipes */ -#endif /* SIGPIPE*/ -#if defined(SIGXFSZ) - sigaction(SIGXFSZ, &sa, NULL); /* Ignore file limit exceeds */ -#endif /* SIGXFSZ */ -#if defined(SIGXCPU) - sigaction(SIGXCPU, &sa, NULL); /* Ignore CPU time limit exceeds */ -#endif /* SIGXCPU */ - - /* Handle specificly some other signals. */ - silc_schedule_task_add_signal(silcd->schedule, SIGHUP, got_hup, NULL); - silc_schedule_task_add_signal(silcd->schedule, SIGTERM, stop_server, NULL); - silc_schedule_task_add_signal(silcd->schedule, SIGINT, stop_server, NULL); - silc_schedule_task_add_signal(silcd->schedule, SIGUSR1, dump_stats, NULL); - - if (!foreground) { - /* Before running the server, fork to background. */ - silc_server_daemonise(silcd); - - /* If set, write pid to file */ - if (silcd->config->server_info->pid_file) { - char buf[10], *pidfile = silcd->config->server_info->pid_file; - unlink(pidfile); - snprintf(buf, sizeof(buf) - 1, "%d\n", getpid()); - silc_file_writefile(pidfile, buf, strlen(buf)); - } - - silc_server_drop_privs(silcd); - } - - /* Run the server. When this returns the server has been stopped - and we will exit. */ - silc_server_run(silcd); - - /* Stop the server and free it. */ - silc_server_stop(silcd); - silc_server_config_destroy(silcd->config); - silc_server_free(silcd); - - /* Flush the logging system */ - silc_log_flush_all(); - - silc_free(silcd_config_file); - silc_free(opt_identifier); - silc_free(opt_keypath); - exit(0); - - fail: - silc_free(silcd_config_file); - silc_free(opt_identifier); - silc_free(opt_keypath); - exit(1); -}