client->data.registered = FALSE;
cache->expire = SILC_ID_CACHE_EXPIRE_DEF;
+ server->stat.clients--;
+ if (server->server_type == SILC_ROUTER)
+ server->stat.cell_clients--;
break;
case SILC_NOTIFY_TYPE_TOPIC_SET:
if (channel->topic)
silc_free(channel->topic);
- channel->topic = silc_calloc(tmp_len, sizeof(*channel->topic));
+ channel->topic = silc_calloc(tmp_len + 1, sizeof(*channel->topic));
memcpy(channel->topic, tmp, tmp_len);
/* Send the same notify to the channel */
}
if (users_modes) {
silc_buffer_push(users_modes, users_modes->data - users_modes->head);
- silc_server_packet_send(server, sock,
- SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
- users_modes->data, users_modes->len, FALSE);
+ silc_server_packet_send_dest(server, sock,
+ SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
+ channel->id, SILC_ID_CHANNEL,
+ users_modes->data,
+ users_modes->len, FALSE);
silc_buffer_free(users_modes);
}
}
char *username = NULL, *realname = NULL, *id_string;
uint32 id_len;
int ret;
+ char *hostname, *nickname;
SILC_LOG_DEBUG(("Creating new client"));
return NULL;
}
+ if (strlen(username) > 128)
+ username[127] = '\0';
+
+ nickname = strdup(username);
+
+ /* Make sanity checks for the hostname of the client. If the hostname
+ is provided in the `username' check that it is the same than the
+ resolved hostname, or if not resolved the hostname that appears in
+ the client's public key. If the hostname is not present then put
+ it from the resolved name or from the public key. */
+ if (strchr(username, '@')) {
+ SilcPublicKeyIdentifier pident;
+ int tlen = strcspn(username, "@");
+ char *phostname = NULL;
+
+ hostname = silc_calloc((strlen(username) - tlen) + 1, sizeof(char));
+ memcpy(hostname, username + tlen + 1, strlen(username) - tlen - 1);
+
+ if (strcmp(sock->hostname, sock->ip) &&
+ strcmp(sock->hostname, hostname)) {
+ silc_free(username);
+ silc_free(hostname);
+ if (realname)
+ silc_free(realname);
+ silc_server_disconnect_remote(server, sock,
+ "Server closed connection: "
+ "Incomplete client information");
+ return NULL;
+ }
+
+ pident = silc_pkcs_decode_identifier(client->data.public_key->identifier);
+ if (pident) {
+ phostname = strdup(pident->host);
+ silc_pkcs_free_identifier(pident);
+ }
+
+ if (!strcmp(sock->hostname, sock->ip) &&
+ phostname && strcmp(phostname, hostname)) {
+ silc_free(username);
+ silc_free(hostname);
+ if (phostname)
+ silc_free(phostname);
+ if (realname)
+ silc_free(realname);
+ silc_server_disconnect_remote(server, sock,
+ "Server closed connection: "
+ "Incomplete client information");
+ return NULL;
+ }
+
+ if (phostname)
+ silc_free(phostname);
+ } else {
+ /* The hostname is not present, add it. */
+ char *newusername;
+ /* XXX For now we cannot take the host name from the public key since
+ they are not trusted or we cannot verify them as trusted. Just take
+ what the resolved name or address is. */
+#if 0
+ if (strcmp(sock->hostname, sock->ip)) {
+#endif
+ newusername = silc_calloc(strlen(username) +
+ strlen(sock->hostname) + 2,
+ sizeof(*newusername));
+ strncat(newusername, username, strlen(username));
+ strncat(newusername, "@", 1);
+ strncat(newusername, sock->hostname, strlen(sock->hostname));
+ silc_free(username);
+ username = newusername;
+#if 0
+ } else {
+ SilcPublicKeyIdentifier pident =
+ silc_pkcs_decode_identifier(client->data.public_key->identifier);
+
+ if (pident) {
+ newusername = silc_calloc(strlen(username) +
+ strlen(pident->host) + 2,
+ sizeof(*newusername));
+ strncat(newusername, username, strlen(username));
+ strncat(newusername, "@", 1);
+ strncat(newusername, pident->host, strlen(pident->host));
+ silc_free(username);
+ username = newusername;
+ silc_pkcs_free_identifier(pident);
+ }
+ }
+#endif
+ }
+
/* Create Client ID */
silc_id_create_client_id(server->id, server->rng, server->md5hash,
username, &client_id);
- if (strlen(username) > 128)
- username[127] = '\0';
-
/* Update client entry */
idata->registered = TRUE;
- client->nickname = strdup(username);
+ client->nickname = nickname;
client->username = username;
client->userinfo = realname ? realname : strdup(" ");
client->id = client_id;
/* Send some nice info to the client */
SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
- ("Welcome to the SILC Network %s@%s",
- username, sock->hostname));
+ ("Welcome to the SILC Network %s",
+ username));
SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
("Your host is %s, running version %s",
server->config->server_info->server_name,
return;
}
+ /* Get the mode and set it to the channel */
+ channel->mode = silc_channel_get_mode(payload);
+
/* Send the new channel key to the server */
chk = silc_channel_key_payload_encode(id_len, id,
strlen(channel->channel_key->
}
if (users_modes) {
silc_buffer_push(users_modes, users_modes->data - users_modes->head);
- silc_server_packet_send(server, sock,
- SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
- users_modes->data, users_modes->len, FALSE);
+ silc_server_packet_send_dest(server, sock,
+ SILC_PACKET_NOTIFY, SILC_PACKET_FLAG_LIST,
+ channel->id, SILC_ID_CHANNEL,
+ users_modes->data,
+ users_modes->len, FALSE);
silc_buffer_free(users_modes);
}
}