updates.
authorPekka Riikonen <priikone@silcnet.org>
Fri, 23 Feb 2001 10:48:00 +0000 (10:48 +0000)
committerPekka Riikonen <priikone@silcnet.org>
Fri, 23 Feb 2001 10:48:00 +0000 (10:48 +0000)
CHANGES
apps/silc/client_ops.c
apps/silcd/command.c
apps/silcd/packet_receive.c
apps/silcd/server.c
apps/silcd/server.h
doc/draft-riikonen-silc-pp-01.nroff
lib/silcclient/client.c
lib/silcclient/command.c
lib/silcske/silcske.c

diff --git a/CHANGES b/CHANGES
index 544168d684d2292437e5b2bbd6cdfdb41cd35706..bf360649f8e1ab3f836545db8531559d589eda4a 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,12 @@
+Fri Feb 23 11:22:57 EET 2001  Pekka Riikonen <priikone@poseidon.pspt.fi>
+
+       * Added support for quit message that client can "leave" on the
+         channel when it quits the SILC.  It is ditributed inside the
+         SILC_NOTIFY_TYPE_SIGNOFF notify type.
+
+         Added silc_server_free_client_data that will take the
+         signoff message as argument.
+
 Thu Feb 22 23:05:36 EET 2001  Pekka Riikonen <priikone@poseidon.pspt.fi>
 
        * Updated parts of the protocol specification to keep it up
index 0aeea8fed1c3b1da98d1018493a2541e469f5528..830c6e9004d1be1f233998c12761ddc6f9d5261d 100644 (file)
@@ -85,7 +85,7 @@ void silc_notify(SilcClient client, SilcClientConnection conn,
   char message[4096];
   SilcClientEntry client_entry, client_entry2;
   SilcChannelEntry channel_entry;
-  char *tmp;
+  char *tmp = NULL;
   unsigned int tmp_int;
 
   va_start(vp, type);
@@ -130,12 +130,15 @@ void silc_notify(SilcClient client, SilcClientConnection conn,
 
   case SILC_NOTIFY_TYPE_SIGNOFF:
     client_entry = va_arg(vp, SilcClientEntry);
+    tmp = va_arg(vp, char *);
     if (client_entry->server)
-      snprintf(message, sizeof(message), "Signoff: %s@%s", 
-              client_entry->nickname, client_entry->server);
+      snprintf(message, sizeof(message), "Signoff: %s@%s %s%s%s", 
+              client_entry->nickname, client_entry->server,
+              tmp ? "(" : "", tmp ? tmp : "", tmp ? ")" : "");
     else
-      snprintf(message, sizeof(message), "Signoff: %s", 
-              client_entry->nickname);
+      snprintf(message, sizeof(message), "Signoff: %s %s%s%s", 
+              client_entry->nickname,
+              tmp ? "(" : "", tmp ? tmp : "", tmp ? ")" : "");
     break;
 
   case SILC_NOTIFY_TYPE_TOPIC_SET:
index e0477ee45f0ddaf6ca6b26ca6a6f73f2153154ab..188c04cac8c0421383229208c4436e3085dd7706 100644 (file)
@@ -1573,20 +1573,30 @@ SILC_SERVER_CMD_FUNC(invite)
   silc_server_command_free(cmd);
 }
 
+typedef struct {
+  SilcServer server;
+  SilcSocketConnection sock;
+  char *signoff;
+} *QuitInternal;
+
 /* Quits connection to client. This gets called if client won't
    close the connection even when it has issued QUIT command. */
 
 SILC_TASK_CALLBACK(silc_server_command_quit_cb)
 {
-  SilcServer server = (SilcServer)context;
-  SilcSocketConnection sock = server->sockets[fd];
+  QuitInternal q = (QuitInternal)context;
 
   /* Free all client specific data, such as client entry and entires
      on channels this client may be on. */
-  silc_server_free_sock_user_data(server, sock);
+  silc_server_free_client_data(q->server, q->sock, q->sock->user_data,
+                              q->signoff);
+  q->sock->user_data = NULL;
 
   /* Close the connection on our side */
-  silc_server_close_connection(server, sock);
+  silc_server_close_connection(q->server, q->sock);
+
+  silc_free(q->signoff);
+  silc_free(q);
 }
 
 /* Quits SILC session. This is the normal way to disconnect client. */
@@ -1596,13 +1606,26 @@ SILC_SERVER_CMD_FUNC(quit)
   SilcServerCommandContext cmd = (SilcServerCommandContext)context;
   SilcServer server = cmd->server;
   SilcSocketConnection sock = cmd->sock;
+  QuitInternal q;
+  unsigned char *tmp = NULL;
+  unsigned int len = 0;
 
-  SILC_LOG_DEBUG(("Start"));
+  SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_QUIT, cmd, 0, 1);
+
+  /* Get destination ID */
+  tmp = silc_argument_get_arg_type(cmd->args, 1, &len);
+  if (len > 128)
+    tmp = NULL;
+
+  q = silc_calloc(1, sizeof(*q));
+  q->server = server;
+  q->sock = sock;
+  q->signoff = tmp ? strdup(tmp) : NULL;
 
   /* We quit the connection with little timeout */
   silc_task_register(server->timeout_queue, sock->sock,
-                    silc_server_command_quit_cb, server,
-                    0, 300000, SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
+                    silc_server_command_quit_cb, (void *)q,
+                    0, 200000, SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW);
 
   silc_server_command_free(cmd);
 }
index b6c58ed1e5d66c174a3a66ffeec7eb36c74130eb..3c66a9125cf57c8ca1743fcd02e2912613011e59 100644 (file)
@@ -240,8 +240,13 @@ void silc_server_notify(SilcServer server,
     }
     silc_free(client_id);
 
+    /* Get signoff message */
+    tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
+    if (tmp_len > 128)
+      tmp = NULL;
+
     /* Remove the client from all channels */
-    silc_server_remove_from_channels(server, NULL, client);
+    silc_server_remove_from_channels(server, NULL, client, tmp);
 
     /* Remove the client entry */
     if (!silc_idlist_del_client(server->global_list, client))
index e12dfb04a54418d698abf1764f4ee93e74a0f75c..e68fa380a627ed33a14380ced728046f71e62ca7 100644 (file)
@@ -1809,7 +1809,34 @@ void silc_server_disconnect_remote(SilcServer server,
   silc_server_close_connection(server, sock);
 }
 
-/* Free's user_data pointer from socket connection object. This also sends
+/* Frees client data and notifies about client's signoff. */
+
+void silc_server_free_client_data(SilcServer server, 
+                                 SilcSocketConnection sock,
+                                 SilcClientEntry user_data, char *signoff)
+{
+  /* Send REMOVE_ID packet to routers. */
+  if (!server->standalone && server->router)
+    silc_server_send_notify_signoff(server, server->router->connection,
+                                   server->server_type == SILC_SERVER ?
+                                   FALSE : TRUE, user_data->id, 
+                                   SILC_ID_CLIENT_LEN, signoff);
+
+  /* Remove client from all channels */
+  silc_server_remove_from_channels(server, sock, user_data, signoff);
+
+  /* XXX must take some info to history before freeing */
+
+  /* Free the client entry and everything in it */
+  silc_idlist_del_data(user_data);
+  silc_idlist_del_client(server->local_list, user_data);
+  server->stat.my_clients--;
+  server->stat.clients--;
+  if (server->server_type == SILC_ROUTER)
+    server->stat.cell_clients--;
+}
+
+/* Frees user_data pointer from socket connection object. This also sends
    appropriate notify packets to the network to inform about leaving
    entities. */
 
@@ -1822,26 +1849,7 @@ void silc_server_free_sock_user_data(SilcServer server,
   case SILC_SOCKET_TYPE_CLIENT:
     {
       SilcClientEntry user_data = (SilcClientEntry)sock->user_data;
-
-      /* Send REMOVE_ID packet to routers. */
-      if (!server->standalone && server->router)
-       silc_server_send_notify_signoff(server, server->router->connection,
-                                       server->server_type == SILC_SERVER ?
-                                       FALSE : TRUE, user_data->id, 
-                                       SILC_ID_CLIENT_LEN, NULL);
-
-      /* Remove client from all channels */
-      silc_server_remove_from_channels(server, sock, user_data);
-
-      /* XXX must take some info to history before freeing */
-
-      /* Free the client entry and everything in it */
-      silc_idlist_del_data(user_data);
-      silc_idlist_del_client(server->local_list, user_data);
-      server->stat.my_clients--;
-      server->stat.clients--;
-      if (server->server_type == SILC_ROUTER)
-       server->stat.cell_clients--;
+      silc_server_free_client_data(server, sock, user_data, NULL);
       break;
     }
   case SILC_SOCKET_TYPE_SERVER:
@@ -1918,7 +1926,7 @@ int silc_server_remove_clients_by_server(SilcServer server,
        }
 
        /* Remove the client entry */
-       silc_server_remove_from_channels(server, NULL, client);
+       silc_server_remove_from_channels(server, NULL, client, NULL);
        silc_idlist_del_client(server->local_list, client);
 
        if (!silc_idcache_list_next(list, &id_cache))
@@ -1943,7 +1951,7 @@ int silc_server_remove_clients_by_server(SilcServer server,
        }
 
        /* Remove the client entry */
-       silc_server_remove_from_channels(server, NULL, client);
+       silc_server_remove_from_channels(server, NULL, client, NULL);
        silc_idlist_del_client(server->global_list, client);
 
        if (!silc_idcache_list_next(list, &id_cache))
@@ -1994,7 +2002,8 @@ int silc_server_channel_has_local(SilcChannelEntry channel)
 
 void silc_server_remove_from_channels(SilcServer server, 
                                      SilcSocketConnection sock,
-                                     SilcClientEntry client)
+                                     SilcClientEntry client,
+                                     char *signoff_message)
 {
   SilcChannelEntry channel;
   SilcChannelClientEntry chl;
@@ -2043,8 +2052,11 @@ void silc_server_remove_from_channels(SilcServer server,
       /* Notify about leaving client if this channel has global users. */
       if (channel->global_users)
        silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
-                                          SILC_NOTIFY_TYPE_SIGNOFF, 1,
-                                          clidp->data, clidp->len);
+                                          SILC_NOTIFY_TYPE_SIGNOFF, 
+                                          signoff_message ? 2 : 1,
+                                          clidp->data, clidp->len,
+                                          signoff_message, signoff_message ?
+                                          strlen(signoff_message) : 0);
 
       if (!silc_idlist_del_channel(server->local_list, channel))
        silc_idlist_del_channel(server->global_list, channel);
@@ -2055,8 +2067,11 @@ void silc_server_remove_from_channels(SilcServer server,
     /* Send notify to channel about client leaving SILC and thus
        the entire channel. */
     silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
-                                      SILC_NOTIFY_TYPE_SIGNOFF, 1,
-                                      clidp->data, clidp->len);
+                                      SILC_NOTIFY_TYPE_SIGNOFF, 
+                                      signoff_message ? 2 : 1,
+                                      clidp->data, clidp->len,
+                                      signoff_message, signoff_message ?
+                                      strlen(signoff_message) : 0);
   }
 
   silc_buffer_free(clidp);
index 9b3f64ac514a923c97e02842a7df4e9d5a3d2064..1b83e1a836216f968e0b4fd3fad50e784e18665d 100644 (file)
@@ -89,6 +89,9 @@ void silc_server_packet_parse_type(SilcServer server,
                                   SilcPacketContext *packet);
 void silc_server_close_connection(SilcServer server,
                                  SilcSocketConnection sock);
+void silc_server_free_client_data(SilcServer server, 
+                                 SilcSocketConnection sock,
+                                 SilcClientEntry user_data, char *signoff);
 void silc_server_free_sock_user_data(SilcServer server, 
                                     SilcSocketConnection sock);
 int silc_server_channel_has_global(SilcChannelEntry channel);
@@ -97,7 +100,8 @@ int silc_server_remove_clients_by_server(SilcServer server,
                                         SilcServerEntry entry);
 void silc_server_remove_from_channels(SilcServer server, 
                                      SilcSocketConnection sock,
-                                     SilcClientEntry client);
+                                     SilcClientEntry client,
+                                     char *signoff_message);
 int silc_server_remove_from_one_channel(SilcServer server, 
                                        SilcSocketConnection sock,
                                        SilcChannelEntry channel,
index c3c6372be2407bb805e1a2b7235e73ec6fa1484d..30d1be15be25307007fde5948e0781ddd36d7501 100644 (file)
@@ -1089,7 +1089,7 @@ ID's sent in arguments are sent inside ID Payload.
       and broadcast it to the network.
 
       Max Arguments:  2
-          Arguments:  (1) <Client ID>  (2)  <message>
+          Arguments:  (1) <Client ID>  (2) <message>
 
       The <Client ID> is the client who left SILC network.  The <message>
       is free text string indicating the reason of signoff.
index 81cf7e020650031db21904c42c722a7242836e94..4dd828f89bce4d088871d93af1755568c0b59c2b 100644 (file)
@@ -603,8 +603,7 @@ SILC_TASK_CALLBACK(silc_client_packet_process)
        return;
       }
       
-      client->ops->say(client, conn, "Connection closed: premature EOF");
-      SILC_LOG_DEBUG(("Premature EOF from connection %d", sock->sock));
+      SILC_LOG_DEBUG(("EOF from connection %d", sock->sock));
       client->ops->disconnect(client, conn);
       silc_client_close_connection(client, sock);
       return;
@@ -1531,8 +1530,13 @@ void silc_client_notify_by_server(SilcClient client,
     silc_idcache_del_by_id(conn->client_cache, SILC_ID_CLIENT, 
                           client_entry->id);
 
+    /* Get signoff message */
+    tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
+    if (tmp_len > 128)
+      tmp = NULL;
+
     /* Notify application */
-    client->ops->notify(client, conn, type, client_entry);
+    client->ops->notify(client, conn, type, client_entry, tmp);
 
     /* Free data */
     if (client_entry->nickname)
index b56ad210b4023526d280c95b2556963ce4101842..594b13f2591c7ef63fc601dddb4fac47cc252416 100644 (file)
@@ -32,7 +32,7 @@ SilcClientCommand silc_command_list[] =
   SILC_CLIENT_CMD(list, LIST, "LIST", SILC_CF_LAG | SILC_CF_REG, 2),
   SILC_CLIENT_CMD(topic, TOPIC, "TOPIC", SILC_CF_LAG | SILC_CF_REG, 3),
   SILC_CLIENT_CMD(invite, INVITE, "INVITE", SILC_CF_LAG | SILC_CF_REG, 3),
-  SILC_CLIENT_CMD(quit, QUIT, "QUIT", SILC_CF_LAG | SILC_CF_REG, 1),
+  SILC_CLIENT_CMD(quit, QUIT, "QUIT", SILC_CF_LAG | SILC_CF_REG, 2),
   SILC_CLIENT_CMD(kill, KILL, "KILL", 
                  SILC_CF_LAG | SILC_CF_REG | SILC_CF_OPER, 2),
   SILC_CLIENT_CMD(info, INFO, "INFO", SILC_CF_LAG | SILC_CF_REG, 2),
@@ -519,12 +519,29 @@ SILC_CLIENT_CMD_FUNC(invite)
   silc_client_command_free(cmd);
 }
 
+typedef struct {
+  SilcClient client;
+  SilcClientConnection conn;
+} *QuitInternal;
+
+SILC_TASK_CALLBACK(silc_client_command_quit_cb)
+{
+  QuitInternal q = (QuitInternal)context;
+
+  /* Close connection */
+  q->client->ops->disconnect(q->client, q->conn);
+  silc_client_close_connection(q->client, q->conn->sock);
+
+  silc_free(q);
+}
+
 /* Command QUIT. Closes connection with current server. */
  
 SILC_CLIENT_CMD_FUNC(quit)
 {
   SilcClientCommandContext cmd = (SilcClientCommandContext)context;
   SilcBuffer buffer;
+  QuitInternal q;
 
   if (!cmd->conn) {
     SILC_NOT_CONNECTED(cmd->client, cmd->conn);
@@ -532,20 +549,26 @@ SILC_CLIENT_CMD_FUNC(quit)
     goto out;
   }
 
-  buffer = silc_command_payload_encode(SILC_COMMAND_QUIT, cmd->argc - 1, 
-                                      ++cmd->argv, ++cmd->argv_lens,
-                                      ++cmd->argv_types, 0);
+  if (cmd->argc > 1)
+    buffer = silc_command_payload_encode(SILC_COMMAND_QUIT, cmd->argc - 1, 
+                                        &cmd->argv[1], &cmd->argv_lens[1],
+                                        &cmd->argv_types[1], 0);
+  else
+    buffer = silc_command_payload_encode(SILC_COMMAND_QUIT, 0,
+                                        NULL, NULL, NULL, 0);
   silc_client_packet_send(cmd->client, cmd->conn->sock, SILC_PACKET_COMMAND, 
                          NULL, 0, NULL, NULL, 
                          buffer->data, buffer->len, TRUE);
   silc_buffer_free(buffer);
-  cmd->argv--;
-  cmd->argv_lens--;
-  cmd->argv_types--;
 
-  /* Close connection */
-  cmd->client->ops->disconnect(cmd->client, cmd->conn);
-  silc_client_close_connection(cmd->client, cmd->conn->sock);
+  q = silc_calloc(1, sizeof(*q));
+  q->client = cmd->client;
+  q->conn = cmd->conn;
+
+  /* We quit the connection with little timeout */
+  silc_task_register(cmd->client->timeout_queue, cmd->conn->sock->sock,
+                    silc_client_command_quit_cb, (void *)q,
+                    1, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL);
 
   /* Notify application */
   COMMAND;
index c8de900eefde4bc01d11c6a52311fe200e14371a..7a7f6b6983a5fcdb2e673e8580da9d3ab71908b0 100644 (file)
@@ -353,9 +353,8 @@ SilcSKEStatus silc_ske_initiator_finish(SilcSKE ske,
   /* Verify signature */
   silc_pkcs_public_key_data_set(ske->prop->pkcs, public_key->pk, 
                                public_key->pk_len);
-  if (ske->prop->pkcs->pkcs->verify(ske->prop->pkcs->context,
-                                   payload->sign_data, payload->sign_len,
-                                   hash, hash_len) == FALSE) {
+  if (silc_pkcs_verify(ske->prop->pkcs, payload->sign_data, 
+                      payload->sign_len, hash, hash_len) == FALSE) {
 
     SILC_LOG_DEBUG(("Signature don't match"));
 
@@ -658,9 +657,7 @@ SilcSKEStatus silc_ske_responder_finish(SilcSKE ske,
   /* Sign the hash value */
   silc_pkcs_private_key_data_set(ske->prop->pkcs, private_key->prv, 
                                 private_key->prv_len);
-  ske->prop->pkcs->pkcs->sign(ske->prop->pkcs->context,
-                             hash, hash_len,
-                             sign, &sign_len);
+  silc_pkcs_sign(ske->prop->pkcs, hash, hash_len, sign, &sign_len);
   ske->ke2_payload->sign_data = silc_calloc(sign_len, sizeof(unsigned char));
   memcpy(ske->ke2_payload->sign_data, sign, sign_len);
   memset(sign, 0, sizeof(sign));