updates.
[silc.git] / apps / silcd / command.c
index b4d5bcee37adf53669b7e5e77dde3ac515eb6dae..807faee2cf8743ed787d06a14f15ee52bc19eb36 100644 (file)
@@ -2165,7 +2165,7 @@ silc_server_command_list_send_reply(SilcServerCommandContext cmd,
       memset(usercount, 0, sizeof(usercount));
     } else {
       topic = entry->topic;
-      users = silc_hash_table_count(entry->user_list);
+      users = entry->user_count;
       SILC_PUT32_MSB(users, usercount);
     }
 
@@ -3141,10 +3141,8 @@ static void silc_server_command_join_channel(SilcServer server,
   if (channel->mode & SILC_CHANNEL_MODE_PASSPHRASE) {
     /* Get passphrase */
     tmp = silc_argument_get_arg_type(cmd->args, 3, &tmp_len);
-    if (tmp) {
-      passphrase = silc_calloc(tmp_len, sizeof(*passphrase));
-      memcpy(passphrase, tmp, tmp_len);
-    }
+    if (tmp)
+      passphrase = silc_memdup(tmp, tmp_len);
   
     if (!passphrase || !channel->passphrase ||
         memcmp(passphrase, channel->passphrase, strlen(channel->passphrase))) {
@@ -3187,6 +3185,7 @@ static void silc_server_command_join_channel(SilcServer server,
   chl->channel = channel;
   silc_hash_table_add(channel->user_list, client, chl);
   silc_hash_table_add(client->channels, channel, chl);
+  channel->user_count++;
 
   /* Get users on the channel */
   silc_server_get_users_on_channel(server, channel, &user_list, &mode_list,
@@ -4108,9 +4107,7 @@ SILC_SERVER_CMD_FUNC(cmode)
 
        if (channel->founder_method == SILC_AUTH_PASSWORD) {
          tmp = silc_auth_get_data(auth, &tmp_len);
-         channel->founder_passwd = 
-           silc_calloc(tmp_len + 1, sizeof(*channel->founder_passwd));
-         memcpy(channel->founder_passwd, tmp, tmp_len);
+         channel->founder_passwd = silc_memdup(tmp, tmp_len);
          channel->founder_passwd_len = tmp_len;
        } else {
          /* Verify the payload before setting the mode */
@@ -4583,8 +4580,9 @@ SILC_SERVER_CMD_FUNC(oper)
   SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
   unsigned char *username, *auth;
   uint32 tmp_len;
-  SilcServerConfigSectionAdmin *admin;
+  SilcServerConfigAdmin *admin;
   SilcIDListData idata = (SilcIDListData)client;
+  bool result = FALSE;
 
   SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_OPER, cmd, 1, 2);
 
@@ -4600,10 +4598,10 @@ SILC_SERVER_CMD_FUNC(oper)
   }
 
   /* Get the admin configuration */
-  admin = silc_server_config_find_admin(server->config, cmd->sock->ip,
+  admin = silc_server_config_find_admin(server, cmd->sock->ip,
                                        username, client->nickname);
   if (!admin) {
-    admin = silc_server_config_find_admin(server->config, cmd->sock->hostname,
+    admin = silc_server_config_find_admin(server, cmd->sock->hostname,
                                          username, client->nickname);
     if (!admin) {
       silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
@@ -4620,10 +4618,18 @@ SILC_SERVER_CMD_FUNC(oper)
     goto out;
   }
 
-  /* Verify the authentication data */
-  if (!silc_auth_verify_data(auth, tmp_len, admin->auth_meth, 
-                            admin->auth_data, admin->auth_data_len,
-                            idata->hash, client->id, SILC_ID_CLIENT)) {
+  /* Verify the authentication data. If both passphrase and public key
+     is set then try both of them. */
+  if (admin->passphrase)
+    result = silc_auth_verify_data(auth, tmp_len, SILC_AUTH_PASSWORD,
+                                  admin->passphrase, admin->passphrase_len,
+                                  idata->hash, client->id, SILC_ID_CLIENT);
+  if (!result && admin->publickey)
+    result = silc_auth_verify_data(auth, tmp_len, SILC_AUTH_PUBLIC_KEY,
+                                  admin->publickey, 0,
+                                  idata->hash, client->id, SILC_ID_CLIENT);
+  if (!result) {
+    /* Authentication failed */
     silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
                                          SILC_STATUS_ERR_AUTH_FAILED);
     goto out;
@@ -4661,8 +4667,9 @@ SILC_SERVER_CMD_FUNC(silcoper)
   SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
   unsigned char *username, *auth;
   uint32 tmp_len;
-  SilcServerConfigSectionAdmin *admin;
+  SilcServerConfigAdmin *admin;
   SilcIDListData idata = (SilcIDListData)client;
+  bool result = FALSE;
 
   SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_SILCOPER, cmd, 1, 2);
 
@@ -4684,10 +4691,10 @@ SILC_SERVER_CMD_FUNC(silcoper)
   }
 
   /* Get the admin configuration */
-  admin = silc_server_config_find_admin(server->config, cmd->sock->ip,
+  admin = silc_server_config_find_admin(server, cmd->sock->ip,
                                        username, client->nickname);
   if (!admin) {
-    admin = silc_server_config_find_admin(server->config, cmd->sock->hostname,
+    admin = silc_server_config_find_admin(server, cmd->sock->hostname,
                                          username, client->nickname);
     if (!admin) {
       silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
@@ -4704,11 +4711,19 @@ SILC_SERVER_CMD_FUNC(silcoper)
     goto out;
   }
 
-  /* Verify the authentication data */
-  if (!silc_auth_verify_data(auth, tmp_len, admin->auth_meth, 
-                            admin->auth_data, admin->auth_data_len,
-                            idata->hash, client->id, SILC_ID_CLIENT)) {
-    silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
+  /* Verify the authentication data. If both passphrase and public key
+     is set then try both of them. */
+  if (admin->passphrase)
+    result = silc_auth_verify_data(auth, tmp_len, SILC_AUTH_PASSWORD,
+                                  admin->passphrase, admin->passphrase_len,
+                                  idata->hash, client->id, SILC_ID_CLIENT);
+  if (!result && admin->publickey)
+    result = silc_auth_verify_data(auth, tmp_len, SILC_AUTH_PUBLIC_KEY,
+                                  admin->publickey, 0,
+                                  idata->hash, client->id, SILC_ID_CLIENT);
+  if (!result) {
+    /* Authentication failed */
+    silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
                                          SILC_STATUS_ERR_AUTH_FAILED);
     goto out;
   }