+ /* Get founder public key */
+ tmp = silc_argument_get_arg_type(args, 6, &tmp_len);
+ if (tmp && mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
+ if (channel->founder_key)
+ silc_pkcs_public_key_free(channel->founder_key);
+ channel->founder_key = NULL;
+ silc_pkcs_public_key_decode(tmp, tmp_len, &channel->founder_key);
+
+ if (!channel->founder_key ||
+ (client && client->data.public_key &&
+ server->server_type == SILC_ROUTER &&
+ !silc_pkcs_public_key_compare(channel->founder_key,
+ client->data.public_key))) {
+ /* A really buggy server isn't checking public keys correctly.
+ It's not possible that the mode setter and founder wouldn't
+ have same public key. */
+ SILC_LOG_DEBUG(("Enforcing sender to change channel mode"));
+
+ mode &= ~SILC_CHANNEL_MODE_FOUNDER_AUTH;
+ silc_server_send_notify_cmode(server, sock, FALSE, channel,
+ mode, server->id, SILC_ID_SERVER,
+ channel->cipher,
+ channel->hmac_name,
+ channel->passphrase, NULL);
+ if (channel->founder_key)
+ silc_pkcs_public_key_free(channel->founder_key);
+ channel->founder_key = NULL;
+ } else if (!client->data.public_key) {
+ client->data.public_key =
+ silc_pkcs_public_key_copy(channel->founder_key);
+ }
+ }
+
+ /* Change mode */
+ channel->mode = mode;
+
+ if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) &&
+ channel->founder_key) {
+ silc_pkcs_public_key_free(channel->founder_key);
+ channel->founder_key = NULL;
+ }
+