SilcServerConnection sconn = (SilcServerConnection)ctx->context;
SilcSocketConnection sock = NULL;
SilcServerConnAuthInternalContext *proto_ctx;
+ SilcServerConfigSectionServerConnection *conn = NULL;
SILC_LOG_DEBUG(("Start"));
proto_ctx->dest_id_type = ctx->dest_id_type;
proto_ctx->dest_id = ctx->dest_id;
- /* Resolve the authentication method used in this connection */
- proto_ctx->auth_meth = SILC_AUTH_PASSWORD;
- if (server->config->routers) {
- SilcServerConfigSectionServerConnection *conn = NULL;
-
- /* Check if we find a match from user configured connections */
- conn = silc_server_config_find_router_conn(server->config,
- sock->hostname,
- sock->port);
- if (conn) {
- /* Match found. Use the configured authentication method */
- proto_ctx->auth_meth = conn->auth_meth;
- if (conn->auth_data) {
- proto_ctx->auth_data = strdup(conn->auth_data);
- proto_ctx->auth_data_len = strlen(conn->auth_data);
- }
- } else {
- /* No match found. */
- /* XXX */
+ /* Resolve the authentication method used in this connection. Check if
+ we find a match from user configured connections */
+ conn = silc_server_config_find_router_conn(server->config,
+ sock->hostname,
+ sock->port);
+ if (conn) {
+ /* Match found. Use the configured authentication method */
+ proto_ctx->auth_meth = conn->auth_meth;
+ if (conn->auth_data) {
+ proto_ctx->auth_data = strdup(conn->auth_data);
+ proto_ctx->auth_data_len = strlen(conn->auth_data);
}
} else {
- /* XXX */
+ SILC_LOG_ERROR(("Could not find connection data for %s (%s) on port",
+ sock->hostname, sock->ip, sock->port));
+ silc_protocol_free(protocol);
+ silc_ske_free_key_material(ctx->keymat);
+ if (ctx->packet)
+ silc_packet_context_free(ctx->packet);
+ if (ctx->ske)
+ silc_ske_free(ctx->ske);
+ if (ctx->dest_id)
+ silc_free(ctx->dest_id);
+ silc_free(ctx);
+ silc_task_unregister_by_callback(server->timeout_queue,
+ silc_server_failure_callback);
+ silc_server_disconnect_remote(server, sock, "Server closed connection: "
+ "Key exchange failed");
+ return;
}
/* Free old protocol as it is finished now */
/* Check max connections */
if (sock > SILC_SERVER_MAX_CONNECTIONS) {
- if (server->config->redirect) {
- /* XXX Redirecting connection to somewhere else now?? */
- /*silc_server_send_notify("Server is full, trying to redirect..."); */
- } else {
- SILC_LOG_ERROR(("Refusing connection, server is full"));
- server->stat.conn_failures++;
- }
+ SILC_LOG_ERROR(("Refusing connection, server is full"));
+ server->stat.conn_failures++;
return;
}
and other information is created after we have received NEW_CLIENT
packet from client. */
client = silc_idlist_add_client(server->local_list,
- NULL, NULL, NULL, NULL, NULL, sock);
+ NULL, 0, NULL, NULL, NULL, NULL, sock);
if (!client) {
SILC_LOG_ERROR(("Could not add new client to cache"));
silc_free(sock->user_data);
SILC_LOG_DEBUG(("Connection authentication request packet"));
if (packet->flags & SILC_PACKET_FLAG_LIST)
break;
+ silc_server_connection_auth_request(server, sock, packet);
break;
/*
/* If there is pending outgoing data for the client then purge it
to the network before removing the client entry. */
- if (SILC_IS_OUTBUF_PENDING(sock) && (SILC_IS_DISCONNECTED(sock) == FALSE)) {
+ if (sock && SILC_IS_OUTBUF_PENDING(sock) &&
+ (SILC_IS_DISCONNECTED(sock) == FALSE)) {
server->stat.packets_sent++;
if (sock->outbuf->data - sock->outbuf->head)
return NULL;
}
+ entry->cipher = strdup(cipher);
+ entry->hmac_name = strdup(hmac);
+
/* Now create the actual key material */
silc_server_create_channel_key(server, entry,
silc_cipher_get_key_len(key) / 8);
goto out;
}
+ if (channel->cipher)
+ silc_free(channel->cipher);
+ channel->cipher = strdup(cipher);
+
/* Save the key */
channel->key_len = tmp_len * 8;
channel->key = silc_calloc(tmp_len, sizeof(unsigned char));
/* We don't have that client anywhere, add it. The client is added
to global list since server didn't have it in the lists so it must be
global. */
- client = silc_idlist_add_client(server->global_list, NULL, NULL, NULL,
+ client = silc_idlist_add_client(server->global_list, NULL, 0, NULL,
+ NULL,
silc_id_dup(client_id, SILC_ID_CLIENT),
sock->user_data, NULL);
if (!client) {
/* Lookups route to the client indicated by `id' client ID. The connection
object and internal data object is returned. Returns NULL if route
- could not be found to the client. */
+ could not be found to the client. If the `client_id' is specified then
+ it is used and the `id_data' is ignored. */
SilcSocketConnection silc_server_get_client_route(SilcServer server,
unsigned char *id_data,
unsigned int id_len,
+ SilcClientID *client_id,
SilcIDListData *idata)
{
SilcClientID *id;
SILC_LOG_DEBUG(("Start"));
/* Decode destination Client ID */
- id = silc_id_str2id(id_data, id_len, SILC_ID_CLIENT);
- if (!id) {
- SILC_LOG_ERROR(("Could not decode destination Client ID, dropped"));
- return NULL;
+ if (!client_id) {
+ id = silc_id_str2id(id_data, id_len, SILC_ID_CLIENT);
+ if (!id) {
+ SILC_LOG_ERROR(("Could not decode destination Client ID, dropped"));
+ return NULL;
+ }
+ } else {
+ id = silc_id_dup(client_id, SILC_ID_CLIENT);
}
/* If the destination belongs to our server we don't have to route
return buffer;
}
+
+/* Finds client entry by Client ID and if it is not found then resolves
+ it using WHOIS command. */
+
+SilcClientEntry silc_server_get_client_resolve(SilcServer server,
+ SilcClientID *client_id)
+{
+ SilcClientEntry client;
+
+ client = silc_idlist_find_client_by_id(server->local_list, client_id, NULL);
+ if (!client) {
+ client = silc_idlist_find_client_by_id(server->global_list,
+ client_id, NULL);
+ if (!client && server->server_type == SILC_ROUTER)
+ return NULL;
+ }
+
+ if (!client && server->standalone)
+ return NULL;
+
+ if (!client || !client->nickname || !client->username) {
+ SilcBuffer buffer, idp;
+
+ idp = silc_id_payload_encode(client_id, SILC_ID_CLIENT);
+ buffer = silc_command_payload_encode_va(SILC_COMMAND_WHOIS,
+ ++server->cmd_ident, 1,
+ 3, idp->data, idp->len);
+ silc_server_packet_send(server, client ? client->router->connection :
+ server->router->connection,
+ SILC_PACKET_COMMAND, 0,
+ buffer->data, buffer->len, FALSE);
+ silc_buffer_free(idp);
+ silc_buffer_free(buffer);
+ }
+
+ return client;
+}