Fixed topic annoucning, server signoff handling, added -D option,
authorPekka Riikonen <priikone@silcnet.org>
Wed, 19 Jun 2002 19:41:52 +0000 (19:41 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Wed, 19 Jun 2002 19:41:52 +0000 (19:41 +0000)
better debugging.  For rest see CHANGES.

14 files changed:
CHANGES
apps/silcd/command.c
apps/silcd/packet_receive.c
apps/silcd/packet_send.c
apps/silcd/packet_send.h
apps/silcd/protocol.c
apps/silcd/server.c
apps/silcd/server_util.c
apps/silcd/silcd.c
lib/silccore/silcargument.c
lib/silccore/silcid.c
lib/silcutil/Makefile.am
lib/silcutil/silclog.c
lib/silcutil/silcmemory.h

diff --git a/CHANGES b/CHANGES
index a6e6ce1aba22c4bf8ca9a564dfa8a7e1d86fb8a1..8d0ca8c7c350f183ca8b73e1c6ec835723fdd17f 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,37 @@
+Wed Jun 19 17:46:31 EEST 2002 Pekka Riikonen <priikone@silcnet.org>
+
+       * Save the channel passphrase when received succesful JOIN
+         command reply from router, on normal server.  Otherwise
+         joinig +a channels from normal server is not possible.
+         Affected file silcd/command.c.
+
+       * Fixed a bug in TOPIC_SET notify handling.  The notifier
+         may be other than client too, like server or channel.
+         It expected it to always be only client and ignored the
+         notify.  Affected file silcd/packet_recieve.c.
+
+       * Removed some (unnecessary) debug printing from 
+         lib/silccore/silcid.c and lib/silccore/silcargument.c.
+
+       * Do not force CMODE_CHANGE when server is announcing new
+         channel.
+
+         Router announces stuff only after server reannounces channel
+         after CHANNEL_CHANGE notify.
+
+         These fixes optimizes the announcing procedure, and perhaps
+         fixes some problems too.  Affected file silcd/packet_receive.c.
+
+       * Fixed SERVER_SIGNOFF sending to local clients.  It was
+         totally broken and sent the notify to all local clients, 
+         instead of only to those that was on same channel as the
+         signing off clients.  Affected file silcd/server_util.c.
+
+       * Added -D option to server.  It can be used to give debug
+         level.  The levels are from 0 - 99, and are predefined for
+         smooth server debugging.  (see silcd.c for the predefined
+         levels).  Affected file silcd/server.c.
+
 Wed Jun 19 16:01:51 EEST 2002 Pekka Riikonen <priikone@silcnet.org>
 
        * Fixed a bug in Irssi SILC client to close the connection
index 50d620a2adda7e60277baea9e5072cd618499543..116de4fd794d18ce7951a64804917502ac396d01 100644 (file)
@@ -3683,6 +3683,18 @@ SILC_SERVER_CMD_FUNC(join)
       SILC_GET32_MSB(created, tmp);
       if (silc_argument_get_arg_type(reply->args, 7, NULL))
        create_key = FALSE;     /* Router returned the key already */
+
+      if (silc_command_get_status(reply->payload, NULL, NULL) &&
+         channel->mode & SILC_CHANNEL_MODE_PASSPHRASE) {
+       /* Save channel passphrase, if user provided it successfully */
+       unsigned char *pa;
+       SilcUInt32 pa_len;
+       pa = silc_argument_get_arg_type(reply->args, 3, &pa_len);
+       if (pa) {
+         silc_free(channel->passphrase);
+         channel->passphrase = silc_memdup(pa, pa_len);
+       }
+      }
     }
 
     if (silc_command_get(reply->payload) == SILC_COMMAND_WHOIS &&
index 1c71e7e65d59893f564abfe404a3394a47f90074..ac06a7d2e4c6c0f0c5d4eb74c503febc4d1c0509 100644 (file)
@@ -368,22 +368,24 @@ void silc_server_notify(SilcServer server,
     tmp = silc_argument_get_arg_type(args, 1, &tmp_len);
     if (!tmp)
       goto out;
-    client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
+    client_id = silc_id_payload_parse_id(tmp, tmp_len, &id_type);
     if (!client_id)
       goto out;
 
     /* Get client entry */
-    client = silc_idlist_find_client_by_id(server->global_list, 
-                                          client_id, TRUE, &cache);
-    if (!client) {
-      client = silc_idlist_find_client_by_id(server->local_list, 
+    if (id_type == SILC_ID_CLIENT) {
+      client = silc_idlist_find_client_by_id(server->global_list, 
                                             client_id, TRUE, &cache);
       if (!client) {
-       silc_free(client_id);
-       goto out;
+       client = silc_idlist_find_client_by_id(server->local_list, 
+                                              client_id, TRUE, &cache);
+       if (!client) {
+         silc_free(client_id);
+         goto out;
+       }
       }
+      silc_free(client_id);
     }
-    silc_free(client_id);
 
     /* Get the topic */
     tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
@@ -414,14 +416,16 @@ void silc_server_notify(SilcServer server,
     if (channel->topic && !strcmp(channel->topic, tmp))
       goto out;
 
-    /* Get user's channel entry and check that topic set is allowed. */
-    if (!silc_server_client_on_channel(client, channel, &chl))
-      goto out;
-    if (channel->mode & SILC_CHANNEL_MODE_TOPIC &&
-       !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
-       !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
-      SILC_LOG_DEBUG(("Topic change is not allowed"));
-      goto out;
+    if (client) {
+      /* Get user's channel entry and check that topic set is allowed. */
+      if (!silc_server_client_on_channel(client, channel, &chl))
+       goto out;
+      if (channel->mode & SILC_CHANNEL_MODE_TOPIC &&
+         !(chl->mode & SILC_CHANNEL_UMODE_CHANOP) &&
+         !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
+       SILC_LOG_DEBUG(("Topic change is not allowed"));
+       goto out;
+      }
     }
 
     /* Change the topic */
@@ -1098,7 +1102,7 @@ void silc_server_notify(SilcServer server,
        silc_server_send_notify_topic_set(server, sock,
                                          server->server_type == SILC_ROUTER ?
                                          TRUE : FALSE, channel, 
-                                         channel->id, SILC_ID_CHANNEL,
+                                         server->id, SILC_ID_SERVER,
                                          channel->topic);
       }
     }
@@ -2806,8 +2810,14 @@ void silc_server_new_channel(SilcServer server,
        SILC_LOG_DEBUG(("Forcing the server to change Channel ID"));
        silc_server_send_notify_channel_change(server, sock, FALSE, 
                                               channel_id, channel->id);
+
+       /* Wait that server re-announces this channel */
+       return;
       }
 
+#if 0 /* Lets expect that server send CMODE_CHANGE notify anyway to
+        (attempt) force mode change, and may very well get it. */
+
       /* If the mode is different from what we have then enforce the
         mode change. */
       mode = silc_channel_get_mode(payload);
@@ -2820,6 +2830,7 @@ void silc_server_new_channel(SilcServer server,
                                      channel->passphrase,
                                      channel->founder_key);
       }
+#endif
 
       /* Create new key for the channel and send it to the server and
         everybody else possibly on the channel. */
@@ -2881,6 +2892,13 @@ void silc_server_new_channel(SilcServer server,
                                     users_modes->len, FALSE);
        silc_buffer_free(users_modes);
       }
+      if (channel->topic) {
+       silc_server_send_notify_topic_set(server, sock,
+                                         server->server_type == SILC_ROUTER ?
+                                         TRUE : FALSE, channel, 
+                                         server->id, SILC_ID_SERVER,
+                                         channel->topic);
+      }
     }
   }
 
index 737da431691b217c016fe740ef10760ee4212286..2d41ebcc658eb81f5a048c2ce7058cb654746db9 100644 (file)
@@ -387,8 +387,7 @@ void silc_server_packet_route(SilcServer server,
    clients (for server locally connected, and for router local cell). */
 
 void silc_server_packet_send_clients(SilcServer server,
-                                    SilcClientEntry *clients,
-                                    SilcUInt32 clients_count,
+                                    SilcHashTable clients,
                                     SilcPacketType type, 
                                     SilcPacketFlags flags,
                                     bool route,
@@ -397,18 +396,18 @@ void silc_server_packet_send_clients(SilcServer server,
                                     bool force_send)
 {
   SilcSocketConnection sock = NULL;
+  SilcHashTableList htl;
   SilcClientEntry client = NULL;
   SilcServerEntry *routed = NULL;
   SilcUInt32 routed_count = 0;
   bool gone = FALSE;
-  int i, k;
+  int k;
 
   SILC_LOG_DEBUG(("Sending packet to list of clients"));
 
   /* Send to all clients in table */
-  for (i = 0; i < clients_count; i++) {
-    client = clients[i];
-
+  silc_hash_table_list(clients, &htl);
+  while (silc_hash_table_get(&htl, NULL, (void **)&client)) {
     /* If client has router set it is not locally connected client and
        we will route the message to the router set in the client. Though,
        send locally connected server in all cases. */
@@ -453,7 +452,7 @@ void silc_server_packet_send_clients(SilcServer server,
                                 client->id, SILC_ID_CLIENT,
                                 data, data_len, force_send);
   }
-
+  silc_hash_table_list_reset(&htl);
   silc_free(routed);
 }
 
@@ -590,7 +589,7 @@ void silc_server_packet_send_to_channel(SilcServer server,
 
   /* Send the message to clients on the channel's client list. */
   silc_hash_table_list(channel->user_list, &htl);
-  while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
+  while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
     client = chl->client;
     if (!client)
       continue;
@@ -788,7 +787,7 @@ void silc_server_packet_relay_to_channel(SilcServer server,
 
   /* Send the message to clients on the channel's client list. */
   silc_hash_table_list(channel->user_list, &htl);
-  while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
+  while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
     client = chl->client;
     if (!client || client == sender_entry)
       continue;
@@ -940,7 +939,7 @@ void silc_server_packet_send_local_channel(SilcServer server,
 
   /* Send the message to clients on the channel's client list. */
   silc_hash_table_list(channel->user_list, &htl);
-  while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
+  while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
     if (chl->client && !chl->client->router) {
       sock = (SilcSocketConnection)chl->client->connection;
 
@@ -1532,12 +1531,12 @@ void silc_server_send_notify_on_channels(SilcServer server,
   packetdata.src_id_type = SILC_ID_SERVER;
 
   silc_hash_table_list(client->channels, &htl);
-  while (silc_hash_table_get(&htl, NULL, (void *)&chl)) {
+  while (silc_hash_table_get(&htl, NULL, (void **)&chl)) {
     channel = chl->channel;
 
     /* Send the message to all clients on the channel's client list. */
     silc_hash_table_list(channel->user_list, &htl2);
-    while (silc_hash_table_get(&htl2, NULL, (void *)&chl2)) {
+    while (silc_hash_table_get(&htl2, NULL, (void **)&chl2)) {
       c = chl2->client;
       
       if (sender && c == sender)
index 8e8ca9c92aeaba00eafc1469288cf87d3abfd0b5..ca0779e922741ec7144f700ad753010ccac90c6a 100644 (file)
@@ -60,8 +60,7 @@ void silc_server_packet_route(SilcServer server,
                              SilcSocketConnection sock,
                              SilcPacketContext *packet);
 void silc_server_packet_send_clients(SilcServer server,
-                                    SilcClientEntry *clients,
-                                    SilcUInt32 clients_count,
+                                    SilcHashTable clients,
                                     SilcPacketType type, 
                                     SilcPacketFlags flags,
                                     bool route,
index 75eb86ed70906707402d6143279145f87e9b5082..06922c364641772e407a40a789f9266e8789e940 100644 (file)
@@ -170,15 +170,16 @@ silc_server_protocol_ke_verify_key(SilcSKE ske,
     (SilcServerKEInternalContext *)protocol->context;
   SilcServer server = (SilcServer)ctx->server;
 
-  SILC_LOG_DEBUG(("Start"));
-
-  if (silc_verify_public_key_internal(server, ctx->sock, 
-                                     (ctx->responder == FALSE ?
-                                      SILC_SOCKET_TYPE_ROUTER:
-                                      ctx->sconfig.ref_ptr ? SILC_SOCKET_TYPE_SERVER :
-                                      ctx->rconfig.ref_ptr ? SILC_SOCKET_TYPE_ROUTER :
-                                      SILC_SOCKET_TYPE_CLIENT),
-                                     pk_data, pk_len, pk_type))
+  SILC_LOG_DEBUG(("Verifying received public key"));
+
+  if (silc_verify_public_key_internal(
+                 server, ctx->sock, 
+                 (ctx->responder == FALSE ?
+                  SILC_SOCKET_TYPE_ROUTER:
+                  ctx->sconfig.ref_ptr ? SILC_SOCKET_TYPE_SERVER :
+                  ctx->rconfig.ref_ptr ? SILC_SOCKET_TYPE_ROUTER :
+                  SILC_SOCKET_TYPE_CLIENT),
+                 pk_data, pk_len, pk_type))
     completion(ske, SILC_SKE_STATUS_OK, completion_context);
   else
     completion(ske, SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY, 
@@ -219,7 +220,7 @@ int silc_server_protocol_ke_set_keys(SilcServer server,
   SilcUnknownEntry conn_data;
   SilcIDListData idata;
 
-  SILC_LOG_DEBUG(("Setting new key into use"));
+  SILC_LOG_DEBUG(("Setting new keys into use"));
 
   conn_data = silc_calloc(1, sizeof(*conn_data));
   idata = (SilcIDListData)conn_data;
@@ -373,8 +374,6 @@ static void silc_server_protocol_ke_continue(SilcSKE ske, void *context)
     (SilcServerKEInternalContext *)protocol->context;
   SilcServer server = (SilcServer)ctx->server;
 
-  SILC_LOG_DEBUG(("Start"));
-
   if (ske->status != SILC_SKE_STATUS_OK) {
     SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol",
                    silc_ske_map_status(ske->status)));
@@ -387,6 +386,7 @@ static void silc_server_protocol_ke_continue(SilcSKE ske, void *context)
   /* Send Ok to the other end. We will end the protocol as responder
      sends Ok to us when we will take the new keys into use. */
   if (ctx->responder == FALSE) {
+    SILC_LOG_DEBUG(("Ending key exchange protocol"));
     silc_ske_end(ctx->ske);
 
     /* End the protocol on the next round */
@@ -414,12 +414,10 @@ SILC_TASK_CALLBACK(silc_server_protocol_key_exchange)
   SilcServer server = (SilcServer)ctx->server;
   SilcSKEStatus status = SILC_SKE_STATUS_OK;
 
-  SILC_LOG_DEBUG(("Start"));
-
   if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
     protocol->state = SILC_PROTOCOL_STATE_START;
 
-  SILC_LOG_DEBUG(("State=%d", protocol->state));
+  SILC_LOG_DEBUG(("Current protocol state %d", protocol->state));
 
   switch(protocol->state) {
   case SILC_PROTOCOL_STATE_START:
@@ -440,12 +438,15 @@ SILC_TASK_CALLBACK(silc_server_protocol_key_exchange)
       if (ctx->responder == TRUE) {
        /* Start the key exchange by processing the received security
           properties packet from initiator. */
+       SILC_LOG_DEBUG(("Process security property list (KE)"));
        status = silc_ske_responder_start(ske, ctx->rng, ctx->sock,
                                          silc_version_string,
                                          ctx->packet->buffer, ctx->flags);
       } else {
        SilcSKEStartPayload *start_payload;
 
+       SILC_LOG_DEBUG(("Send security property list (KE)"));
+
        /* Assemble security properties. */
        silc_ske_assemble_security_properties(ske, ctx->flags, 
                                              silc_version_string,
@@ -483,12 +484,14 @@ SILC_TASK_CALLBACK(silc_server_protocol_key_exchange)
        */
       if (ctx->responder == TRUE) {
        /* Sends the selected security properties to the initiator. */
+       SILC_LOG_DEBUG(("Send security property list reply (KE)"));
        status = silc_ske_responder_phase_1(ctx->ske);
       } else {
        /* Call Phase-1 function. This processes the Key Exchange Start
           paylaod reply we just got from the responder. The callback
           function will receive the processed payload where we will
           save it. */
+       SILC_LOG_DEBUG(("Process security property list reply (KE)"));
        status = silc_ske_initiator_phase_1(ctx->ske, ctx->packet->buffer);
       }
 
@@ -521,11 +524,13 @@ SILC_TASK_CALLBACK(silc_server_protocol_key_exchange)
           the initiator. This also creates our parts of the Diffie
           Hellman algorithm. The silc_server_protocol_ke_continue
           will be called after the public key has been verified. */
+       SILC_LOG_DEBUG(("Process KE1 packet"));
        status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer);
       } else {
        /* Call the Phase-2 function. This creates Diffie Hellman
           key exchange parameters and sends our public part inside
           Key Exhange 1 Payload to the responder. */
+       SILC_LOG_DEBUG(("Send KE1 packet"));
        status = silc_ske_initiator_phase_2(ctx->ske,
                                            server->public_key,
                                            server->private_key,
@@ -555,6 +560,7 @@ SILC_TASK_CALLBACK(silc_server_protocol_key_exchange)
       if (ctx->responder == TRUE) {
        /* This creates the key exchange material and sends our
           public parts to the initiator inside Key Exchange 2 Payload. */
+       SILC_LOG_DEBUG(("Process KE2 packet"));
        status = silc_ske_responder_finish(ctx->ske, 
                                           server->public_key, 
                                           server->private_key,
@@ -566,6 +572,7 @@ SILC_TASK_CALLBACK(silc_server_protocol_key_exchange)
        /* Finish the protocol. This verifies the Key Exchange 2 payload
           sent by responder. The silc_server_protocol_ke_continue will
           be called after the public key has been verified. */
+       SILC_LOG_DEBUG(("Send KE2 packet"));
        status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer);
       }
 
@@ -593,6 +600,8 @@ SILC_TASK_CALLBACK(silc_server_protocol_key_exchange)
       int key_len = silc_cipher_get_key_len(ctx->ske->prop->cipher);
       int hash_len = silc_hash_len(ctx->ske->prop->hash);
 
+      SILC_LOG_DEBUG(("Process computed key material"));
+
       /* Process the key material */
       keymat = silc_calloc(1, sizeof(*keymat));
       status = silc_ske_process_key_material(ctx->ske, 16, key_len, hash_len,
@@ -610,8 +619,10 @@ SILC_TASK_CALLBACK(silc_server_protocol_key_exchange)
 
       /* Send Ok to the other end if we are responder. If we are initiator
         we have sent this already. */
-      if (ctx->responder == TRUE)
+      if (ctx->responder == TRUE) {
+       SILC_LOG_DEBUG(("Ending key exchange protocol"));
        silc_ske_end(ctx->ske);
+      }
 
       /* Unregister the timeout task since the protocol has ended. 
         This was the timeout task to be executed if the protocol is
@@ -777,6 +788,8 @@ silc_server_get_public_key_auth(SilcServer server,
     return TRUE;
   }
 
+  SILC_LOG_ERROR(("Error computing signature"));
+
   silc_free(*auth_data);
   silc_buffer_free(auth);
   return FALSE;
@@ -834,6 +847,8 @@ silc_server_get_authentication(SilcServerConnAuthInternalContext *ctx,
                                                   remote_auth_len, ske);
   }
 
+  SILC_LOG_DEBUG(("Authentication %s", result ? "successful" : "failed"));
+
   return result;
 }
 
@@ -848,12 +863,10 @@ SILC_TASK_CALLBACK(silc_server_protocol_connection_auth)
     (SilcServerConnAuthInternalContext *)protocol->context;
   SilcServer server = (SilcServer)ctx->server;
 
-  SILC_LOG_DEBUG(("Start"));
-
   if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
     protocol->state = SILC_PROTOCOL_STATE_START;
 
-  SILC_LOG_DEBUG(("State=%d", protocol->state));
+  SILC_LOG_DEBUG(("Current protocol state %d", protocol->state));
 
   switch(protocol->state) {
   case SILC_PROTOCOL_STATE_START:
@@ -1319,12 +1332,10 @@ SILC_TASK_CALLBACK(silc_server_protocol_rekey)
   SilcIDListData idata = (SilcIDListData)ctx->sock->user_data;
   SilcSKEStatus status;
 
-  SILC_LOG_DEBUG(("Start"));
-
   if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
     protocol->state = SILC_PROTOCOL_STATE_START;
 
-  SILC_LOG_DEBUG(("State=%d", protocol->state));
+  SILC_LOG_DEBUG(("Current protocol state %d", protocol->state));
 
   switch(protocol->state) {
   case SILC_PROTOCOL_STATE_START:
index 9631e5f01718ba9db3b83740e82c8c6236622c81..4ec15a821a010c254b90c098f626b57aaee0a1af 100644 (file)
@@ -1217,8 +1217,6 @@ silc_server_accept_new_connection_lookup(SilcSocketConnection sock,
 
   context = (void *)server;
 
-  SILC_LOG_DEBUG(("Start"));
-
   /* Check whether we could resolve both IP and FQDN. */
   if (!sock->ip || (!strcmp(sock->ip, sock->hostname) &&
                    server->config->require_reverse_lookup)) {
@@ -1319,6 +1317,7 @@ silc_server_accept_new_connection_lookup(SilcSocketConnection sock,
      initiator of the protocol thus we will wait for initiation from
      there before we start the protocol. */
   server->stat.auth_attempts++;
+  SILC_LOG_DEBUG(("Starting key exchange protocol"));
   silc_protocol_alloc(SILC_PROTOCOL_SERVER_KEY_EXCHANGE,
                      &sock->protocol, proto_ctx,
                      silc_server_accept_new_connection_second);
@@ -1404,6 +1403,7 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_second)
   if ((protocol->state == SILC_PROTOCOL_STATE_ERROR) ||
       (protocol->state == SILC_PROTOCOL_STATE_FAILURE)) {
     /* Error occured during protocol */
+    SILC_LOG_DEBUG(("Error key exchange protocol"));
     silc_protocol_free(protocol);
     sock->protocol = NULL;
     silc_ske_free_key_material(ctx->keymat);
@@ -1436,6 +1436,7 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_second)
                                        ctx->ske->prop->hmac,
                                        ctx->ske->prop->group,
                                        ctx->responder)) {
+    SILC_LOG_ERROR(("Error setting key material in use"));
     silc_protocol_free(protocol);
     sock->protocol = NULL;
     silc_ske_free_key_material(ctx->keymat);
@@ -1481,6 +1482,7 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_second)
      but we won't start it yet. We will be receiving party of this
      protocol thus we will wait that connecting party will make
      their first move. */
+  SILC_LOG_DEBUG(("Starting connection authentication protocol"));
   silc_protocol_alloc(SILC_PROTOCOL_SERVER_CONNECTION_AUTH,
                      &sock->protocol, proto_ctx,
                      silc_server_accept_new_connection_final);
@@ -1512,11 +1514,10 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final)
   void *id_entry;
   SilcUInt32 hearbeat_timeout = server->config->param.keepalive_secs;
 
-  SILC_LOG_DEBUG(("Start"));
-
   if (protocol->state == SILC_PROTOCOL_STATE_ERROR ||
       protocol->state == SILC_PROTOCOL_STATE_FAILURE) {
     /* Error occured during protocol */
+    SILC_LOG_DEBUG(("Error during authentication protocol"));
     silc_protocol_free(protocol);
     sock->protocol = NULL;
     if (ctx->packet)
@@ -1548,6 +1549,11 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final)
       if (!silc_server_connection_allowed(server, sock, ctx->conn_type,
                                          &server->config->param,
                                          conn->param, ctx->ske)) {
+       SILC_LOG_INFO(("Connection %s (%s) is not allowed", sock->hostname,
+                      sock->ip));
+       silc_server_disconnect_remote(server, sock,
+                                     SILC_STATUS_ERR_BANNED_FROM_SERVER,
+                                     NULL);
        server->stat.auth_failures++;
        goto out;
       }
@@ -1602,6 +1608,11 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final)
                                            &server->config->param,
                                            rconn ? rconn->param : NULL,
                                            ctx->ske)) {
+         SILC_LOG_INFO(("Connection %s (%s) is not allowed", sock->hostname,
+                        sock->ip));
+         silc_server_disconnect_remote(server, sock,
+                                       SILC_STATUS_ERR_BANNED_FROM_SERVER,
+                                       NULL);
          server->stat.auth_failures++;
          goto out;
        }
@@ -1626,6 +1637,11 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final)
                                            &server->config->param,
                                            sconn ? sconn->param : NULL,
                                            ctx->ske)) {
+         SILC_LOG_INFO(("Connection %s (%s) is not allowed", sock->hostname,
+                        sock->ip));
+         silc_server_disconnect_remote(server, sock,
+                                       SILC_STATUS_ERR_BANNED_FROM_SERVER,
+                                       NULL);
          server->stat.auth_failures++;
          goto out;
        }
@@ -1769,17 +1785,19 @@ SILC_TASK_CALLBACK(silc_server_packet_process)
   SilcUInt32 sequence = 0;
   int ret;
 
-  if (!sock)
+  if (!sock) {
+    SILC_LOG_DEBUG(("Unknown socket connection"));
     return;
-
-  SILC_LOG_DEBUG(("Processing packet"));
+  }
 
   /* Packet sending */
 
   if (type == SILC_TASK_WRITE) {
     /* Do not send data to disconnected connection */
-    if (SILC_IS_DISCONNECTED(sock))
+    if (SILC_IS_DISCONNECTED(sock)) {
+      SILC_LOG_DEBUG(("Disconnected socket connection, cannot send"));
       return;
+    }
 
     server->stat.packets_sent++;
 
@@ -1911,7 +1929,7 @@ SILC_TASK_CALLBACK(silc_server_packet_parse_real)
   SilcIDListData idata = (SilcIDListData)sock->user_data;
   int ret;
 
-  SILC_LOG_DEBUG(("Start"));
+  SILC_LOG_DEBUG(("Parsing packet"));
 
   /* Parse the packet */
   if (parse_ctx->normal)
@@ -2061,8 +2079,6 @@ void silc_server_packet_parse_type(SilcServer server,
   SilcPacketType type = packet->type;
   SilcIDListData idata = (SilcIDListData)sock->user_data;
 
-  SILC_LOG_DEBUG(("Parsing packet type %d", type));
-
   /* Parse the packet type */
   switch (type) {
   case SILC_PACKET_DISCONNECT:
@@ -2510,7 +2526,6 @@ void silc_server_packet_parse_type(SilcServer server,
     SILC_LOG_ERROR(("Incorrect packet type %d, packet dropped", type));
     break;
   }
-
 }
 
 /* Creates connection to a remote router. */
index e7bff22110e2b36b0d18a94f4b26379bc2bafd2e..c041ffb0caa822e980c4f69fc326021b19b7b5b6 100644 (file)
@@ -28,14 +28,16 @@ extern char *server_version;
    keys are regnerated. This is called only by the function
    silc_server_remove_clients_by_server. */
 
-static void silc_server_remove_clients_channels(SilcServer server, 
-                                               SilcSocketConnection sock,
-                                               SilcClientEntry client,
-                                               SilcHashTable channels)
+static void
+silc_server_remove_clients_channels(SilcServer server,
+                                   SilcServerEntry server_entry,
+                                   SilcHashTable clients,
+                                   SilcClientEntry client,
+                                   SilcHashTable channels)
 {
   SilcChannelEntry channel;
-  SilcChannelClientEntry chl;
-  SilcHashTableList htl;
+  SilcChannelClientEntry chl, chl2;
+  SilcHashTableList htl, htl2;
   SilcBuffer clidp;
 
   SILC_LOG_DEBUG(("Start"));
@@ -43,6 +45,9 @@ static void silc_server_remove_clients_channels(SilcServer server,
   if (!client || !client->id)
     return;
 
+  if (silc_hash_table_find(clients, client, NULL, NULL))
+    silc_hash_table_del(clients, client);
+
   clidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
 
   /* Remove the client from all channels. The client is removed from
@@ -94,6 +99,21 @@ static void silc_server_remove_clients_channels(SilcServer server,
       continue;
     }
 
+    /* Mark other local clients to the table of clients whom will receive
+       the SERVER_SIGNOFF notify. */
+    silc_hash_table_list(channel->user_list, &htl2);
+    while (silc_hash_table_get(&htl2, NULL, (void **)&chl2)) {
+      SilcClientEntry c = chl2->client;
+      if (!c)
+       continue;
+
+      /* Add client to table, if it's not from the signoff server */
+      if (c->router != server_entry &&
+         !silc_hash_table_find(clients, c, NULL, NULL))
+       silc_hash_table_add(clients, c, c);
+    }
+    silc_hash_table_list_reset(&htl2);
+
     /* Add the channel to the the channels list to regenerate the 
        channel key */
     if (!silc_hash_table_find(channels, channel, NULL, NULL))
@@ -117,13 +137,11 @@ bool silc_server_remove_clients_by_server(SilcServer server,
   SilcIDCacheEntry id_cache = NULL;
   SilcClientEntry client = NULL;
   SilcBuffer idp;
-  SilcClientEntry *clients = NULL;
-  SilcUInt32 clients_c = 0;
   unsigned char **argv = NULL;
   SilcUInt32 *argv_lens = NULL, *argv_types = NULL, argc = 0;
   SilcHashTableList htl;
   SilcChannelEntry channel;
-  SilcHashTable channels;
+  SilcHashTable channels, clients;
   int i;
 
   SILC_LOG_DEBUG(("Start"));
@@ -133,6 +151,8 @@ bool silc_server_remove_clients_by_server(SilcServer server,
      from the channels. */
   channels = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL, NULL,
                                   NULL, NULL, TRUE);
+  clients = silc_hash_table_alloc(0, silc_hash_ptr, NULL, NULL, NULL,
+                                 NULL, NULL, TRUE);
 
   if (server_signoff) {
     idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER);
@@ -160,13 +180,6 @@ bool silc_server_remove_clients_by_server(SilcServer server,
        }
 
        if (client->router != entry) {
-         if (server_signoff) {
-           clients = silc_realloc(clients, 
-                                  sizeof(*clients) * (clients_c + 1));
-           clients[clients_c] = client;
-           clients_c++;
-         }
-
          if (!silc_idcache_list_next(list, &id_cache))
            break;
          else
@@ -196,7 +209,8 @@ bool silc_server_remove_clients_by_server(SilcServer server,
        SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
 
        /* Remove the client entry */
-       silc_server_remove_clients_channels(server, NULL, client, channels);
+       silc_server_remove_clients_channels(server, entry, clients,
+                                           client, channels);
        if (!server_signoff) {
          client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
          id_cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
@@ -226,13 +240,6 @@ bool silc_server_remove_clients_by_server(SilcServer server,
        }
        
        if (client->router != entry) {
-         if (server_signoff && client->connection) {
-           clients = silc_realloc(clients, 
-                                  sizeof(*clients) * (clients_c + 1));
-           clients[clients_c] = client;
-           clients_c++;
-         }
-
          if (!silc_idcache_list_next(list, &id_cache))
            break;
          else
@@ -262,7 +269,8 @@ bool silc_server_remove_clients_by_server(SilcServer server,
        SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
 
        /* Remove the client entry */
-       silc_server_remove_clients_channels(server, NULL, client, channels);
+       silc_server_remove_clients_channels(server, entry, clients,
+                                           client, channels);
        if (!server_signoff) {
          client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED;
          id_cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
@@ -295,17 +303,18 @@ bool silc_server_remove_clients_by_server(SilcServer server,
       silc_buffer_free(args);
     }
 
+    
+
     /* Send to local clients. We also send the list of client ID's that
        is to be removed for those servers that would like to use that list. */
     args = silc_argument_payload_encode(argc, argv, argv_lens,
                                        argv_types);
     not = silc_notify_payload_encode_args(SILC_NOTIFY_TYPE_SERVER_SIGNOFF, 
                                          argc, args);
-    silc_server_packet_send_clients(server, clients, clients_c,
+    silc_server_packet_send_clients(server, clients,
                                    SILC_PACKET_NOTIFY, 0, FALSE,
                                    not->data, not->len, FALSE);
 
-    silc_free(clients);
     silc_buffer_free(args);
     silc_buffer_free(not);
     for (i = 0; i < argc; i++)
@@ -313,6 +322,7 @@ bool silc_server_remove_clients_by_server(SilcServer server,
     silc_free(argv);
     silc_free(argv_lens);
     silc_free(argv_types);
+    silc_hash_table_free(clients);
   }
 
   /* We must now re-generate the channel key for all channels that had
index c1a5277e570ee2d36fe1c8e4d2edbc705e85ead2..4b49cafa044ced7bd455a90c2c17a6950f5648d8 100644 (file)
@@ -45,6 +45,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 +76,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"
@@ -310,6 +312,80 @@ SILC_TASK_CALLBACK(dump_stats)
   fclose(fdd);
 }
 
+typedef struct {
+  int level;
+  const char *string;
+} DebugLevel;
+
+static DebugLevel debug_levels[] = {
+  /* Basic stuff from silcd/ */
+  { 5, "silc_server_*" },
+
+  /* All from silcd/ */
+  { 10, "*silcd*,*serverid*,silc_server_*,*idlist*" },
+
+  /* All from silcd/ and basic stuff from libs */
+  { 15, "*silcd*,*serverid*,silc_server_*,*idlist*,*silcauth*,*silcske*" },
+
+  /* All from silcd/ and more stuff from libs */
+  { 20, "*silcd*,*serverid*,silc_server_*,*idlist*,*silcauth*,"
+    "*silcpacket*,*ske*,*silcrng*" },
+
+  /* All from silcd/ and even more stuff from libs */
+  { 25, "*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 */
+  { 30, "*silcd*,*serverid*,silc_server_*,*idlist*,*silcauth*,"
+    "*silcpacket*,*ske*,*silcrng*,*command*,*channel*,*private*,*notify*"
+    "*silcid*,*argument*" },
+
+  /* All from silcd/, all from silccore, silccrypt and silcmath */
+  { 35, "*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 */
+  { 40, "*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 */
+  { 45, "*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 */
+  { 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*,*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;
+    }
+}
+
 /* This function should not be called directly but throught the wrapper
    macro SILC_SERVER_LOG_STDERR() */
 
@@ -333,7 +409,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 +428,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"
index dd470a37dbc4ef704a7d6f55e9cc5a2d17250799..2b69f80b3ad5b295a9189b64d9b9c45bf3965b51 100644 (file)
@@ -50,8 +50,6 @@ SilcArgumentPayload silc_argument_payload_parse(const unsigned char *payload,
   SilcUInt32 pull_len = 0;
   int i = 0, ret;
 
-  SILC_LOG_DEBUG(("Parsing argument payload"));
-
   silc_buffer_set(&buffer, (unsigned char *)payload, payload_len);
   newp = silc_calloc(1, sizeof(*newp));
   if (!newp)
@@ -95,8 +93,10 @@ SilcArgumentPayload silc_argument_payload_parse(const unsigned char *payload,
     pull_len += 3 + p_len;
   }
 
-  if (buffer.len != 0)
+  if (buffer.len != 0) {
+    SILC_LOG_DEBUG(("Malformed argument payload"));
     goto err;
+  }
 
   newp->argc = argc;
   newp->pos = 0;
@@ -106,6 +106,7 @@ SilcArgumentPayload silc_argument_payload_parse(const unsigned char *payload,
   return newp;
 
  err:
+  SILC_LOG_DEBUG(("Error parsing argument payload"));
   if (i)
     for (ret = 0; ret < i; ret++)
       silc_free(newp->argv[ret]);
@@ -129,8 +130,6 @@ SilcBuffer silc_argument_payload_encode(SilcUInt32 argc,
   SilcUInt32 len;
   int i;
 
-  SILC_LOG_DEBUG(("Encoding Argument payload"));
-
   len = 0;
   for (i = 0; i < argc; i++)
     len += 3 + argv_lens[i];
@@ -163,8 +162,6 @@ SilcBuffer silc_argument_payload_encode_payload(SilcArgumentPayload payload)
   SilcUInt32 len;
   int i;
 
-  SILC_LOG_DEBUG(("Encoding Argument payload"));
-
   len = 0;
   for (i = 0; i < payload->argc; i++)
     len += 3 + payload->argv_lens[i];
index 6e892c087b2a8dedb675bbf4206408873fe48637..ee2b1edb9b68e942f41d0632dadc17bb3677d7a7 100644 (file)
@@ -48,8 +48,6 @@ SilcIDPayload silc_id_payload_parse(const unsigned char *payload,
   SilcIDPayload newp;
   int ret;
 
-  SILC_LOG_DEBUG(("Parsing ID payload"));
-
   silc_buffer_set(&buffer, (unsigned char *)payload, payload_len);
   newp = silc_calloc(1, sizeof(*newp));
   if (!newp)
@@ -81,6 +79,7 @@ SilcIDPayload silc_id_payload_parse(const unsigned char *payload,
   return newp;
 
  err:
+  SILC_LOG_DEBUG(("Error parsing ID payload"));
   silc_free(newp);
   return NULL;
 }
@@ -103,21 +102,21 @@ void *silc_id_payload_parse_id(const unsigned char *data, SilcUInt32 len,
                             SILC_STR_UI_SHORT(&idlen),
                             SILC_STR_END);
   if (ret == -1)
-    return NULL;
+    goto err;
 
   if (type > SILC_ID_CHANNEL)
-    return NULL;
+    goto err;
 
   silc_buffer_pull(&buffer, 4);
 
   if (idlen > buffer.len || idlen > SILC_PACKET_MAX_ID_LEN)
-    return NULL;
+    goto err;
 
   ret = silc_buffer_unformat(&buffer,
                             SILC_STR_UI_XNSTRING(&id_data, idlen),
                             SILC_STR_END);
   if (ret == -1)
-    return NULL;
+    goto err;
 
   id = silc_id_str2id(id_data, idlen, type);
 
@@ -125,6 +124,10 @@ void *silc_id_payload_parse_id(const unsigned char *data, SilcUInt32 len,
     *ret_type = type;
 
   return id;
+
+ err:
+  SILC_LOG_DEBUG(("Error parsing ID payload"));
+  return NULL;
 }
 
 /* Encodes ID Payload */
@@ -148,10 +151,6 @@ SilcBuffer silc_id_payload_encode_data(const unsigned char *id,
 {
   SilcBuffer buffer;
 
-  SILC_LOG_DEBUG(("Encoding %s ID payload",
-                 type == SILC_ID_CLIENT ? "Client" :
-                 type == SILC_ID_SERVER ? "Server" : "Channel"));
-
   buffer = silc_buffer_alloc_size(4 + id_len);
   if (!buffer)
     return NULL;
index b91e5c5d1b60515344246704c65e6f22caf95376..eeea6a0951757df18367a3fa255797faeaa72cd2 100644 (file)
@@ -35,9 +35,18 @@ endif
 endif
 endif
 
+if SILC_DIST_TOOLKIT
+SILC_DIST_SOURCE = stacktrace.c
+SILC_DIST_HEADERS = stacktrace.h
+else
+SILC_DIST_SOURCE =
+SILC_DIST_HEADERS =
+endif
+
 noinst_LIBRARIES = libsilcutil.a
 
 libsilcutil_a_SOURCES = \
+       $(SILC_DIST_SOURCE) \
        silcbuffmt.c \
        silcconfig.c \
        silclog.c \
@@ -49,11 +58,11 @@ libsilcutil_a_SOURCES = \
        silcutil.c \
        silchashtable.c \
        silcsockconn.c  \
-       silcprotocol.c  \
-       stacktrace.c
+       silcprotocol.c
 
 if SILC_DIST_TOOLKIT
 include_HEADERS =      \
+       $(SILC_DIST_SOURCE) \
        silcbuffer.h    \
        silcbuffmt.h    \
        silcconfig.h    \
index 176c3eb73092be7156a56bf154af73a9e9868885..4a70cbc5a7d47d0ba6a665f5dafd104d7efb3b5f 100644 (file)
@@ -497,6 +497,7 @@ void silc_log_set_debug_string(const char *debug_string)
   len = strlen(string);
   if (len >= sizeof(silc_log_debug_string))
     len = sizeof(silc_log_debug_string) - 1;
+  memset(silc_log_debug_string, 0, sizeof(silc_log_debug_string));
   strncpy(silc_log_debug_string, string, len);
   silc_free(string);
 }
index 233f38943618080124475725052af96dad449dbe..6c213f7a4b1ce73836b8605457e56dfb383afec3 100644 (file)
@@ -120,6 +120,10 @@ void silc_free(void *ptr);
 void *silc_memdup(const void *ptr, size_t size);
 
 #else
+#ifndef SILC_DIST_TOOLKIT
+#error "The stack trace is not supported in this distribution"
+#endif
+
 #include "stacktrace.h"
 #endif /* SILC_STACKTRACE */