updates.
[silc.git] / apps / silc / client_ops.c
index 690584b8be44206118dded0b790e8772637b9478..3165b7d86a57afcfc3c8ea2bdc39eb245f01c623 100644 (file)
@@ -46,24 +46,42 @@ void silc_say(SilcClient client, SilcClientConnection conn,
    received in the packet. The `channel_name' is the name of the channel. */
 
 void silc_channel_message(SilcClient client, SilcClientConnection conn,
-                         SilcClientEntry sender, SilcChannelEntry channel
-                         , char *msg)
+                         SilcClientEntry sender, SilcChannelEntry channel,
+                         SilcMessageFlags flags, char *msg)
 {
   /* Message from client */
   if (conn && !strcmp(conn->current_channel->channel_name, 
                      channel->channel_name))
-    silc_print(client, "<%s> %s", sender ? sender->nickname : "[<unknown>]", 
-              msg);
+    if (flags & SILC_MESSAGE_FLAG_ACTION)
+      silc_print(client, "* %s %s", sender ? sender->nickname : "[<unknown>]", 
+                msg);
+    else if (flags & SILC_MESSAGE_FLAG_NOTICE)
+      silc_print(client, "- %s %s", sender ? sender->nickname : "[<unknown>]", 
+                msg);
+    else
+      silc_print(client, "<%s> %s", sender ? sender->nickname : "[<unknown>]", 
+                msg);
   else
-    silc_print(client, "<%s:%s> %s", sender ? sender->nickname : "[<unknown>]",
-              channel->channel_name, msg);
+    if (flags & SILC_MESSAGE_FLAG_ACTION)
+      silc_print(client, "* %s:%s %s", sender ? sender->nickname : 
+                "[<unknown>]",
+                channel->channel_name, msg);
+    else if (flags & SILC_MESSAGE_FLAG_NOTICE)
+      silc_print(client, "- %s:%s %s", sender ? sender->nickname : 
+                "[<unknown>]",
+                channel->channel_name, msg);
+    else
+      silc_print(client, "<%s:%s> %s", sender ? sender->nickname : 
+                "[<unknown>]",
+                channel->channel_name, msg);
 }
 
 /* Private message to the client. The `sender' is the nickname of the
    sender received in the packet. */
 
 void silc_private_message(SilcClient client, SilcClientConnection conn,
-                         SilcClientEntry sender, char *msg)
+                         SilcClientEntry sender, SilcMessageFlags flags,
+                         char *msg)
 {
   silc_print(client, "*%s* %s", sender->nickname, msg);
 }
@@ -102,10 +120,11 @@ void silc_notify(SilcClient client, SilcClientConnection conn,
     break;
 
   case SILC_NOTIFY_TYPE_INVITE:
+    (void)va_arg(vp, SilcChannelEntry);
+    tmp = va_arg(vp, char *);
     client_entry = va_arg(vp, SilcClientEntry);
-    channel_entry = va_arg(vp, SilcChannelEntry);
     snprintf(message, sizeof(message), "%s invites you to channel %s", 
-            client_entry->nickname, channel_entry->channel_name);
+            client_entry->nickname, tmp);
     break;
 
   case SILC_NOTIFY_TYPE_JOIN:
@@ -182,14 +201,32 @@ void silc_notify(SilcClient client, SilcClientConnection conn,
 
   case SILC_NOTIFY_TYPE_CMODE_CHANGE:
     client_entry = va_arg(vp, SilcClientEntry);
-    tmp = silc_client_chmode(va_arg(vp, unsigned int));
+    tmp_int = va_arg(vp, unsigned int);
+    (void)va_arg(vp, char *);
+    (void)va_arg(vp, char *);
     channel_entry = va_arg(vp, SilcChannelEntry);
-    if (tmp)
-      snprintf(message, sizeof(message), "%s changed channel mode to +%s", 
-              client_entry->nickname, tmp);
-    else
-      snprintf(message, sizeof(message), "%s removed all channel modes", 
-              client_entry->nickname);
+    
+    tmp = silc_client_chmode(tmp_int, channel_entry);
+    
+    if (tmp) {
+      if (client_entry) {
+       snprintf(message, sizeof(message), "%s changed channel mode to +%s",
+                client_entry->nickname, tmp);
+      } else {
+       snprintf(message, sizeof(message), 
+                "channel mode was changed to +%s (forced by router)",
+                tmp);
+      }
+    } else {
+      if (client_entry) {
+       snprintf(message, sizeof(message), "%s removed all channel modes", 
+                client_entry->nickname);
+      } else {
+       snprintf(message, sizeof(message), 
+                "Removed all channel modes (forced by router)");
+      }
+    }
+
     if (app->screen->bottom_line->channel_mode)
       silc_free(app->screen->bottom_line->channel_mode);
     app->screen->bottom_line->channel_mode = tmp;
@@ -241,6 +278,7 @@ void silc_notify(SilcClient client, SilcClientConnection conn,
     return;
 
   case SILC_NOTIFY_TYPE_CHANNEL_CHANGE:
+    return;
     break;
 
   case SILC_NOTIFY_TYPE_KICKED:
@@ -484,12 +522,18 @@ void silc_command_reply(SilcClient client, SilcClientConnection conn,
          }
        }
 
-       if (mode)
-         client->ops->say(client, conn, "%s is %s", nickname,
-                          (mode & SILC_UMODE_SERVER_OPERATOR) ?
-                          "Server Operator" :
-                          (mode & SILC_UMODE_ROUTER_OPERATOR) ?
-                          "SILC Operator" : "[Unknown mode]");
+       if (mode) {
+         if ((mode & SILC_UMODE_SERVER_OPERATOR) ||
+             (mode & SILC_UMODE_ROUTER_OPERATOR))
+           client->ops->say(client, conn, "%s is %s", nickname,
+                            (mode & SILC_UMODE_SERVER_OPERATOR) ?
+                            "Server Operator" :
+                            (mode & SILC_UMODE_ROUTER_OPERATOR) ?
+                            "SILC Operator" : "[Unknown mode]");
+
+         if (mode & SILC_UMODE_GONE)
+           client->ops->say(client, conn, "%s is gone", nickname);
+       }
 
        if (idle && nickname)
          client->ops->say(client, conn, "%s has been idle %d %s",
@@ -548,6 +592,26 @@ void silc_command_reply(SilcClient client, SilcClientConnection conn,
       }
       break;
 
+    case SILC_COMMAND_INVITE:
+      {
+       SilcChannelEntry channel;
+       char *invite_list;
+
+       if (!success)
+         return;
+       
+       channel = va_arg(vp, SilcChannelEntry);
+       invite_list = va_arg(vp, char *);
+
+       if (invite_list)
+         silc_say(client, conn, "%s invite list: %s", channel->channel_name,
+                  invite_list);
+       else
+         silc_say(client, conn, "%s invite list not set", 
+                  channel->channel_name);
+      }
+      break;
+
     case SILC_COMMAND_JOIN:
       {
        unsigned int mode;
@@ -575,7 +639,8 @@ void silc_command_reply(SilcClient client, SilcClientConnection conn,
          client->ops->say(client, conn, "Topic for %s: %s", 
                           app->screen->bottom_line->channel, topic);
        
-       app->screen->bottom_line->channel_mode = silc_client_chmode(mode);
+       app->screen->bottom_line->channel_mode = 
+         silc_client_chmode(mode, channel);
        silc_screen_print_bottom_line(app->screen, 0);
 
        /* Resolve the client information */
@@ -712,8 +777,30 @@ void silc_command_reply(SilcClient client, SilcClientConnection conn,
          silc_screen_print_bottom_line(app->screen, 0);
          break;
        }
+      }
       break;
+
+    case SILC_COMMAND_BAN:
+      {
+       SilcChannelEntry channel;
+       char *ban_list;
+
+       if (!success)
+         return;
+       
+       channel = va_arg(vp, SilcChannelEntry);
+       ban_list = va_arg(vp, char *);
+
+       if (ban_list)
+         silc_say(client, conn, "%s ban list: %s", channel->channel_name,
+                  ban_list);
+       else
+         silc_say(client, conn, "%s ban list not set", channel->channel_name);
       }
+      break;
+
+    default:
+      break;
     }
 }
 
@@ -792,11 +879,12 @@ unsigned char *silc_ask_passphrase(SilcClient client,
 }
 
 /* Verifies received public key. If user decides to trust the key it is
-   saved as trusted server key for later use. If user does not trust the
+   saved as public server key for later use. If user does not trust the
    key this returns FALSE. */
 
-int silc_verify_server_key(SilcClient client,
+int silc_verify_public_key(SilcClient client,
                           SilcClientConnection conn, 
+                          SilcSocketType conn_type,
                           unsigned char *pk, unsigned int pk_len,
                           SilcSKEPKType pk_type)
 {
@@ -806,11 +894,15 @@ int silc_verify_server_key(SilcClient client,
   char *hostname, *fingerprint;
   struct passwd *pw;
   struct stat st;
+  char *entity = ((conn_type == SILC_SOCKET_TYPE_SERVER ||
+                  conn_type == SILC_SOCKET_TYPE_ROUTER) ? 
+                 "server" : "client");
 
   hostname = sock->hostname ? sock->hostname : sock->ip;
 
   if (pk_type != SILC_SKE_PK_TYPE_SILC) {
-    silc_say(client, conn, "We don't support server %s key type", hostname);
+    silc_say(client, conn, "We don't support %s %s key type", 
+            entity, hostname);
     return FALSE;
   }
 
@@ -820,17 +912,18 @@ int silc_verify_server_key(SilcClient client,
 
   memset(filename, 0, sizeof(filename));
   memset(file, 0, sizeof(file));
-  snprintf(file, sizeof(file) - 1, "serverkey_%s_%d.pub", hostname,
+  snprintf(file, sizeof(file) - 1, "%skey_%s_%d.pub", entity, hostname,
           sock->port);
-  snprintf(filename, sizeof(filename) - 1, "%s/.silc/serverkeys/%s", 
-          pw->pw_dir, file);
+  snprintf(filename, sizeof(filename) - 1, "%s/.silc/%skeys/%s", 
+          pw->pw_dir, entity, file);
 
   /* Check wheter this key already exists */
   if (stat(filename, &st) < 0) {
 
     fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
-    silc_say(client, conn, "Received server %s public key", hostname);
-    silc_say(client, conn, "Fingerprint for the server %s key is", hostname);
+    silc_say(client, conn, "Received %s %s public key", entity, hostname);
+    silc_say(client, conn, "Fingerprint for the %s %s key is", entity, 
+            hostname);
     silc_say(client, conn, "%s", fingerprint);
     silc_free(fingerprint);
 
@@ -855,12 +948,13 @@ int silc_verify_server_key(SilcClient client,
       if (!silc_pkcs_load_public_key(filename, &public_key, 
                                     SILC_PKCS_FILE_BIN)) {
        fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
-       silc_say(client, conn, "Received server %s public key", hostname);
-       silc_say(client, conn, "Fingerprint for the server %s key is", hostname);
+       silc_say(client, conn, "Received %s %s public key", entity, hostname);
+       silc_say(client, conn, "Fingerprint for the %s %s key is", 
+                entity, hostname);
        silc_say(client, conn, "%s", fingerprint);
        silc_free(fingerprint);
-       silc_say(client, conn, "Could not load your local copy of the server %s key",
-                hostname);
+       silc_say(client, conn, "Could not load your local copy of the %s %s key",
+                entity, hostname);
        if (silc_client_ask_yes_no(client, 
           "Would you like to accept the key anyway (y/n)? "))
          {
@@ -878,12 +972,13 @@ int silc_verify_server_key(SilcClient client,
     encpk = silc_pkcs_public_key_encode(public_key, &encpk_len);
     if (!encpk) {
       fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
-      silc_say(client, conn, "Received server %s public key", hostname);
-      silc_say(client, conn, "Fingerprint for the server %s key is", hostname);
+      silc_say(client, conn, "Received %s %s public key", entity, hostname);
+      silc_say(client, conn, "Fingerprint for the %s %s key is", 
+              entity, hostname);
       silc_say(client, conn, "%s", fingerprint);
       silc_free(fingerprint);
-      silc_say(client, conn, "Your local copy of the server %s key is malformed",
-              hostname);
+      silc_say(client, conn, "Your local copy of the %s %s key is malformed",
+              entity, hostname);
       if (silc_client_ask_yes_no(client, 
          "Would you like to accept the key anyway (y/n)? "))
        {
@@ -899,12 +994,13 @@ int silc_verify_server_key(SilcClient client,
 
     if (memcmp(encpk, pk, encpk_len)) {
       fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
-      silc_say(client, conn, "Received server %s public key", hostname);
-      silc_say(client, conn, "Fingerprint for the server %s key is", hostname);
+      silc_say(client, conn, "Received %s %s public key", entity, hostname);
+      silc_say(client, conn, "Fingerprint for the %s %s key is", 
+              entity, hostname);
       silc_say(client, conn, "%s", fingerprint);
       silc_free(fingerprint);
-      silc_say(client, conn, "Server %s key does not match with your local copy",
-              hostname);
+      silc_say(client, conn, "%s %s key does not match with your local copy",
+              entity, hostname);
       silc_say(client, conn, "It is possible that the key has expired or changed");
       silc_say(client, conn, "It is also possible that some one is performing "
                       "man-in-the-middle attack");
@@ -920,7 +1016,7 @@ int silc_verify_server_key(SilcClient client,
          return TRUE;
        }
 
-      silc_say(client, conn, "Will not accept server %s key", hostname);
+      silc_say(client, conn, "Will not accept %s %s key", entity, hostname);
       return FALSE;
     }
 
@@ -928,7 +1024,7 @@ int silc_verify_server_key(SilcClient client,
     return TRUE;
   }
 
-  silc_say(client, conn, "Will not accept server %s key", hostname);
+  silc_say(client, conn, "Will not accept %s %s key", entity, hostname);
   return FALSE;
 }
 
@@ -966,7 +1062,11 @@ int silc_get_auth_method(SilcClient client, SilcClientConnection conn,
     }
   }
 
-  return FALSE;
+  *auth_meth = SILC_AUTH_NONE;
+  *auth_data = NULL;
+  *auth_data_len = 0;
+
+  return TRUE;
 }
 
 /* Notifies application that failure packet was received.  This is called
@@ -995,6 +1095,21 @@ int silc_key_agreement(SilcClient client, SilcClientConnection conn,
                       SilcKeyAgreementCallback *completion,
                       void **context)
 {
+  char host[256];
+
+  /* We will just display the info on the screen and return FALSE and user
+     will have to start the key agreement with a command. */
+
+  if (hostname) {
+    memset(host, 0, sizeof(host));
+    snprintf(host, sizeof(host) - 1, "(%s on port %d)", hostname, port); 
+  }
+
+  silc_say(client, conn, "%s wants to perform key agreement %s",
+          client_entry->nickname, hostname ? host : "");
+
+  *completion = NULL;
+  *context = NULL;
 
   return FALSE;
 }
@@ -1010,7 +1125,7 @@ SilcClientOperations ops = {
   connect:              silc_connect,
   disconnect:           silc_disconnect,
   get_auth_method:      silc_get_auth_method,
-  verify_server_key:    silc_verify_server_key,
+  verify_public_key:    silc_verify_public_key,
   ask_passphrase:       silc_ask_passphrase,
   failure:              silc_failure,
   key_agreement:        silc_key_agreement,