X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=blobdiff_plain;f=apps%2Fsilcd%2Fsilcd.c;h=33a5043cc7ca12475dc117c538a5930024e62773;hp=c1a5277e570ee2d36fe1c8e4d2edbc705e85ead2;hb=382d15d447b7a95390decfa783836ae4fe255b3d;hpb=e2c551b9693b6d42e5997b9df416a17fb94c1ccb diff --git a/apps/silcd/silcd.c b/apps/silcd/silcd.c index c1a5277e..33a5043c 100644 --- a/apps/silcd/silcd.c +++ b/apps/silcd/silcd.c @@ -33,11 +33,6 @@ static SilcServer silcd; static void silc_usage(void); -static char *silc_server_create_identifier(void); -static int silc_server_create_key_pair(char *pkcs_name, int bits, char *path, - char *identifier, - SilcPublicKey *ret_pub_key, - SilcPrivateKey *ret_prv_key); /* Long command line options */ static struct option long_opts[] = @@ -45,6 +40,7 @@ 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' }, @@ -75,6 +71,7 @@ static void silc_usage(void) " 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" @@ -306,19 +303,236 @@ SILC_TASK_CALLBACK(dump_stats) STAT_OUTPUT(" Packets sent : %d", silcd->stat.packets_sent); STAT_OUTPUT(" Packets received : %d", silcd->stat.packets_received); +#undef STAT_OUTPUT + +#ifdef SILC_DEBUG + /* Dump lists */ + { + SilcIDCacheList list = NULL; + 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)) { + if (silc_idcache_list_first(list, &id_cache)) { + fprintf(fdd, "\nServers in local-list:\n"); + c = 1; + while (id_cache) { + 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); + if (!silc_idcache_list_next(list, &id_cache)) + break; + c++; + } + } + silc_idcache_list_free(list); + } + if (silc_idcache_get_all(silcd->global_list->servers, &list)) { + if (silc_idcache_list_first(list, &id_cache)) { + fprintf(fdd, "\nServers in global-list:\n"); + c = 1; + while (id_cache) { + 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); + if (!silc_idcache_list_next(list, &id_cache)) + break; + c++; + } + } + silc_idcache_list_free(list); + } + if (silc_idcache_get_all(silcd->local_list->clients, &list)) { + if (silc_idcache_list_first(list, &id_cache)) { + fprintf(fdd, "\nClients in local-list:\n"); + c = 1; + while (id_cache) { + client_entry = (SilcClientEntry)id_cache->context; + fprintf(fdd, " %d: name %s id %s status 0x%x\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); + if (!silc_idcache_list_next(list, &id_cache)) + break; + c++; + } + } + silc_idcache_list_free(list); + } + if (silc_idcache_get_all(silcd->global_list->clients, &list)) { + if (silc_idcache_list_first(list, &id_cache)) { + fprintf(fdd, "\nClients in global-list:\n"); + c = 1; + while (id_cache) { + client_entry = (SilcClientEntry)id_cache->context; + fprintf(fdd, " %d: name %s id %s status 0x%x\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); + if (!silc_idcache_list_next(list, &id_cache)) + break; + c++; + } + } + silc_idcache_list_free(list); + } + if (silc_idcache_get_all(silcd->local_list->channels, &list)) { + if (silc_idcache_list_first(list, &id_cache)) { + fprintf(fdd, "\nChannels in local-list:\n"); + c = 1; + while (id_cache) { + 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"); + if (!silc_idcache_list_next(list, &id_cache)) + break; + c++; + } + } + silc_idcache_list_free(list); + } + if (silc_idcache_get_all(silcd->global_list->channels, &list)) { + if (silc_idcache_list_first(list, &id_cache)) { + fprintf(fdd, "\nChannels in global-list:\n"); + c = 1; + while (id_cache) { + 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"); + if (!silc_idcache_list_next(list, &id_cache)) + break; + c++; + } + } + silc_idcache_list_free(list); + } + } +#endif + fflush(fdd); fclose(fdd); } -/* This function should not be called directly but throught the wrapper - macro SILC_SERVER_LOG_STDERR() */ +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*,*silcauth*,*silcske*" }, + + /* All from silcd/ and more stuff from libs */ + { 25, "*silcd*,*serverid*,silc_server_*,*idlist*,*silcauth*," + "*silcpacket*,*ske*,*silcrng*" }, + + /* All from silcd/ and even more stuff from libs */ + { 30, "*silcd*,*serverid*,silc_server_*,*idlist*,*silcauth*," + "*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*,*silcauth*," + "*silcpacket*,*ske*,*silcrng*,*command*,*channel*,*private*,*notify*" + "*silcid*,*argument*" }, + + /* All from silcd/, all from silccore, silccrypt and silcmath */ + { 40, "*silcd*,*serverid*,silc_server_*,*idlist*,*silcauth*," + "*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*,*silcauth*," + "*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*,*silcauth*," + "*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*,*silcauth*," + "*silcpacket*,*ske*,*silcrng*,*command*,*channel*,*private*,*notify*" + "*silcid*,*argument*,*pkcs*,*hmac*,*hash*,*cipher*,silc_math*,*sim*" + "*sockconn*,*net*,*log*,*config*" }, + + /* All */ + { 90, "*" }, + + { -1, NULL }, +}; -void silc_server_stderr(char *message) +static void silc_get_debug_level(int level) { - if (silcd->background) - silc_log_output(SILC_LOG_ERROR, message); + 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; + } +} + +/* 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", message); + fprintf(stderr, "%s\n", message); silc_free(message); } } @@ -333,7 +547,7 @@ int main(int argc, char **argv) /* Parse command line arguments */ if (argc > 1) { - while ((opt = getopt_long(argc, argv, "f:p:d:xhFVC:", + while ((opt = getopt_long(argc, argv, "f:p:d:D:xhFVC:", long_opts, &option_index)) != EOF) { switch(opt) { case 'h': @@ -352,8 +566,21 @@ int main(int argc, char **argv) silc_debug = TRUE; if (optarg) silc_log_set_debug_string(optarg); - foreground = TRUE; /* implied */ - silc_log_quick = TRUE; /* implied */ + foreground = TRUE; /* implied */ + silc_log_quick = 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_debug = TRUE; + if (optarg) + silc_get_debug_level(atoi(optarg)); + foreground = TRUE; /* implied */ + silc_log_quick = TRUE; /* implied */ #else fprintf(stderr, "Run-time debugging is not enabled. To enable it recompile\n" @@ -409,12 +636,19 @@ int main(int argc, char **argv) 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(); - silc_server_create_key_pair(opt_pkcs, opt_bits, opt_keypath, - opt_identifier, NULL, NULL); + silc_create_key_pair(opt_pkcs, opt_bits, pubfile, prvfile, + opt_identifier, "", NULL, NULL, NULL, FALSE); exit(0); } @@ -427,12 +661,25 @@ int main(int argc, char **argv) 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); 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(); + silc_hash_unregister_all(); + silc_hmac_unregister_all(); + /* Check for another silcd running */ silc_server_checkpid(silcd); @@ -496,108 +743,3 @@ int main(int argc, char **argv) silc_free(opt_keypath); exit(1); } - -/* Returns identifier string for public key generation. */ - -static char *silc_server_create_identifier(void) -{ - char *username = NULL, *realname = NULL; - char hostname[256], email[256]; - - /* Get realname */ - realname = silc_get_real_name(); - - /* Get hostname */ - memset(hostname, 0, sizeof(hostname)); - gethostname(hostname, sizeof(hostname)); - - /* Get username (mandatory) */ - username = silc_get_username(); - if (!username) - return NULL; - - /* Create default email address, whether it is right or not */ - snprintf(email, sizeof(email), "%s@%s", username, hostname); - - return silc_pkcs_encode_identifier(username, hostname, realname, email, - NULL, NULL); -} - -/* Creates new public key and private key pair. This is used only - when user wants to create new key pair from command line. */ - -static int -silc_server_create_key_pair(char *pkcs_name, int bits, char *path, - char *identifier, - SilcPublicKey *ret_pub_key, - SilcPrivateKey *ret_prv_key) -{ - SilcPKCS pkcs; - SilcPublicKey pub_key; - SilcPrivateKey prv_key; - SilcRng rng; - unsigned char *key; - SilcUInt32 key_len; - char pkfile[256], prvfile[256]; - - if (!pkcs_name || !path) - return FALSE; - - if (!silc_pkcs_is_supported(pkcs_name)) { - fprintf(stderr, "Unsupported PKCS `%s'", pkcs_name); - return FALSE; - } - - if (!bits) - bits = 2048; - - if (!identifier) - identifier = silc_server_create_identifier(); - - rng = silc_rng_alloc(); - silc_rng_init(rng); - silc_rng_global_init(rng); - - snprintf(pkfile, sizeof(pkfile) - 1, "%s%s", path, - SILC_SERVER_PUBLIC_KEY_NAME); - snprintf(prvfile, sizeof(prvfile) - 1, "%s%s", path, - SILC_SERVER_PRIVATE_KEY_NAME); - - /* Generate keys */ - silc_pkcs_alloc(pkcs_name, &pkcs); - silc_pkcs_generate_key(pkcs, bits, rng); - - /* Save public key into file */ - key = silc_pkcs_get_public_key(pkcs, &key_len); - pub_key = silc_pkcs_public_key_alloc(silc_pkcs_get_name(pkcs), identifier, - key, key_len); - silc_pkcs_save_public_key(pkfile, pub_key, SILC_PKCS_FILE_PEM); - if (ret_pub_key) - *ret_pub_key = pub_key; - else - silc_pkcs_public_key_free(pub_key); - - memset(key, 0, sizeof(key_len)); - silc_free(key); - - /* Save private key into file */ - key = silc_pkcs_get_private_key(pkcs, &key_len); - prv_key = silc_pkcs_private_key_alloc(silc_pkcs_get_name(pkcs), - key, key_len); - silc_pkcs_save_private_key(prvfile, prv_key, NULL, SILC_PKCS_FILE_BIN); - if (ret_prv_key) - *ret_prv_key = prv_key; - else - silc_pkcs_private_key_free(prv_key); - - printf("Public key has been saved into `%s'\n", pkfile); - printf("Private key has been saved into `%s'\n", prvfile); - - memset(key, 0, sizeof(key_len)); - silc_free(key); - - silc_rng_free(rng); - silc_pkcs_free(pkcs); - - return TRUE; -}