From ee4396c2b0129375d07aadb3f63af668c67d490d Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Sun, 11 Nov 2007 11:25:44 +0000 Subject: [PATCH] Fixed client resuming. Fixed prefer_passphrase_auth flag. Fixed disconnection of unauthenticated connection. Fixed OPER an SILCOPER public key authenticationn. --- apps/silcd/idlist.c | 4 +-- apps/silcd/idlist.h | 1 + apps/silcd/packet_receive.c | 43 ++++++++++++++--------- apps/silcd/server.c | 70 +++++++++++++++++++++++++++---------- apps/silcd/server_util.c | 7 ++++ 5 files changed, 88 insertions(+), 37 deletions(-) diff --git a/apps/silcd/idlist.c b/apps/silcd/idlist.c index e302b6e6..e4dbfbd6 100644 --- a/apps/silcd/idlist.c +++ b/apps/silcd/idlist.c @@ -55,8 +55,6 @@ void silc_idlist_del_data(void *entry) if (idata->hash) silc_hash_free(idata->hash); - if (idata->public_key) - silc_pkcs_public_key_free(idata->public_key); idata->hash = NULL; idata->public_key = NULL; @@ -338,6 +336,8 @@ silc_idlist_add_client(SilcIDList id_list, char *nickname, char *username, } client = silc_calloc(1, sizeof(*client)); + if (!client) + return NULL; client->nickname = nickname; client->username = username ? strdup(username) : NULL; client->userinfo = userinfo; diff --git a/apps/silcd/idlist.h b/apps/silcd/idlist.h index 25705a98..7b9c2ad1 100644 --- a/apps/silcd/idlist.h +++ b/apps/silcd/idlist.h @@ -554,6 +554,7 @@ typedef struct { const char *hostname; const char *ip; SilcUInt16 port; + SilcConnectionType conn_type; } *SilcUnknownEntry; /* Prototypes */ diff --git a/apps/silcd/packet_receive.c b/apps/silcd/packet_receive.c index 9b990ff8..c2c57ed7 100644 --- a/apps/silcd/packet_receive.c +++ b/apps/silcd/packet_receive.c @@ -3433,6 +3433,8 @@ void silc_server_resume_client(SilcServer server, SilcPublicKey public_key; const char *cipher, *hostname, *ip; + SILC_LOG_DEBUG(("Resuming client")); + silc_socket_stream_get_info(silc_packet_stream_get_stream(sock), NULL, &hostname, &ip, NULL); @@ -3696,6 +3698,7 @@ void silc_server_resume_client(SilcServer server, /* Take new keys and stuff into use in the old entry */ silc_idlist_del_data(detached_client); silc_idlist_add_data(detached_client, idata); + idata->public_key = NULL; if (detached_client->data.public_key) { /* Add the resumed client's public key back to repository. */ @@ -3807,14 +3810,17 @@ void silc_server_resume_client(SilcServer server, silc_buffer_free(nidp); } - /* Add the client again to the ID cache to get it to correct list */ - if (!silc_idcache_del_by_context(server->local_list->clients, client, - NULL)) - silc_idcache_del_by_context(server->global_list->clients, client, NULL); - silc_free(client->id); - *client->id = client_id; - silc_idcache_add(server->local_list->clients, nicknamec, - client->id, client); + /* Update entry */ + if (!silc_idcache_update_by_context(server->local_list->clients, client, + &client_id, NULL, FALSE)) + silc_idcache_update_by_context(server->global_list->clients, client, + &client_id, NULL, FALSE); + + /* Move entry to local list if it is in global list */ + if (silc_idcache_find_by_context(server->global_list->clients, client, + &id_cache)) + silc_idcache_move(server->global_list->clients, + server->local_list->clients, id_cache); /* Send some nice info to the client */ silc_server_send_connect_notifys(server, sock, client); @@ -3975,15 +3981,18 @@ void silc_server_resume_client(SilcServer server, server_entry->server_type == SILC_ROUTER) local = FALSE; - /* Change the client to correct list. */ - if (!silc_idcache_del_by_context(server->local_list->clients, - detached_client, NULL)) - silc_idcache_del_by_context(server->global_list->clients, - detached_client, NULL); - silc_idcache_add(local && server->server_type == SILC_ROUTER ? - server->local_list->clients : - server->global_list->clients, nicknamec, - detached_client->id, detached_client); + /* Move entry to correct list */ + if (local && server->server_type == SILC_ROUTER) { + if (silc_idcache_find_by_context(server->global_list->clients, + detached_client, &id_cache)) + silc_idcache_move(server->global_list->clients, + server->local_list->clients, id_cache); + } else { + if (silc_idcache_find_by_context(server->local_list->clients, + detached_client, &id_cache)) + silc_idcache_move(server->local_list->clients, + server->global_list->clients, id_cache); + } /* Change the owner of the client */ detached_client->router = server_entry; diff --git a/apps/silcd/server.c b/apps/silcd/server.c index 2680fc77..9f68e5b8 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -103,14 +103,16 @@ static SilcBool silc_server_packet_receive(SilcPacketEngine engine, !(idata->status & SILC_IDLIST_STATUS_REGISTERED)) && packet->type != SILC_PACKET_NEW_CLIENT && packet->type != SILC_PACKET_NEW_SERVER && + packet->type != SILC_PACKET_RESUME_CLIENT && packet->type != SILC_PACKET_CONNECTION_AUTH_REQUEST && packet->type != SILC_PACKET_DISCONNECT) return FALSE; - /* NEW_CLIENT and NEW_SERVER are accepted only without source ID - and for unregistered connection. */ + /* NEW_CLIENT, NEW_SERVER and RESUME_CLIENT are accepted only without + source ID and for unregistered connection. */ if (packet->src_id && (packet->type == SILC_PACKET_NEW_CLIENT || - packet->type == SILC_PACKET_NEW_SERVER) && + packet->type == SILC_PACKET_NEW_SERVER || + packet->type == SILC_PACKET_RESUME_CLIENT) && (idata->status & SILC_IDLIST_STATUS_REGISTERED)) return FALSE; @@ -2043,7 +2045,16 @@ silc_server_accept_get_auth(SilcConnAuth connauth, if (cconfig->publickeys) *repository = server->repository; - entry->data.conn_type = conn_type; + if (cconfig->publickeys) { + if (server->config->prefer_passphrase_auth) { + *repository = NULL; + } else { + *passphrase = NULL; + *passphrase_len = 0; + } + } + + entry->conn_type = conn_type; return TRUE; } @@ -2064,7 +2075,16 @@ silc_server_accept_get_auth(SilcConnAuth connauth, if (sconfig->publickeys) *repository = server->repository; - entry->data.conn_type = conn_type; + if (sconfig->publickeys) { + if (server->config->prefer_passphrase_auth) { + *repository = NULL; + } else { + *passphrase = NULL; + *passphrase_len = 0; + } + } + + entry->conn_type = conn_type; return TRUE; } @@ -2079,7 +2099,16 @@ silc_server_accept_get_auth(SilcConnAuth connauth, if (rconfig->publickeys) *repository = server->repository; - entry->data.conn_type = conn_type; + if (rconfig->publickeys) { + if (server->config->prefer_passphrase_auth) { + *repository = NULL; + } else { + *passphrase = NULL; + *passphrase_len = 0; + } + } + + entry->conn_type = conn_type; return TRUE; } @@ -2118,14 +2147,14 @@ silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success, SILC_LOG_DEBUG(("Checking whether connection is allowed")); - switch (entry->data.conn_type) { + switch (entry->conn_type) { case SILC_CONN_CLIENT: { SilcClientEntry client; SilcServerConfigClient *conn = entry->cconfig.ref_ptr; /* Verify whether this connection is after all allowed to connect */ - if (!silc_server_connection_allowed(server, sock, entry->data.conn_type, + if (!silc_server_connection_allowed(server, sock, entry->conn_type, &server->config->param, conn->param, silc_connauth_get_ske(connauth))) { @@ -2178,6 +2207,7 @@ silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success, goto out; } entry->data.status |= SILC_IDLIST_STATUS_LOCAL; + entry->data.conn_type = SILC_CONN_CLIENT; /* Statistics */ server->stat.my_clients++; @@ -2205,6 +2235,7 @@ silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success, } /* Add public key to repository */ + SILC_LOG_DEBUG(("Add client public key to repository")); if (!silc_server_get_public_key_by_client(server, client, NULL)) silc_skr_add_public_key_simple(server->repository, entry->data.public_key, @@ -2231,7 +2262,7 @@ silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success, and we do not have connection to primary router, do not allow the connection. */ if (server->server_type == SILC_BACKUP_ROUTER && - entry->data.conn_type == SILC_CONN_SERVER && + entry->conn_type == SILC_CONN_SERVER && !SILC_PRIMARY_ROUTE(server)) { SILC_LOG_INFO(("Will not accept server connection because we do " "not have primary router connection established")); @@ -2243,10 +2274,10 @@ silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success, goto out; } - if (entry->data.conn_type == SILC_CONN_ROUTER) { + if (entry->conn_type == SILC_CONN_ROUTER) { /* Verify whether this connection is after all allowed to connect */ if (!silc_server_connection_allowed(server, sock, - entry->data.conn_type, + entry->conn_type, &server->config->param, rconn ? rconn->param : NULL, silc_connauth_get_ske(connauth))) { @@ -2278,10 +2309,10 @@ silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success, } } - if (entry->data.conn_type == SILC_CONN_SERVER) { + if (entry->conn_type == SILC_CONN_SERVER) { /* Verify whether this connection is after all allowed to connect */ if (!silc_server_connection_allowed(server, sock, - entry->data.conn_type, + entry->conn_type, &server->config->param, srvconn ? srvconn->param : NULL, silc_connauth_get_ske(connauth))) { @@ -2337,11 +2368,11 @@ silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success, } SILC_LOG_DEBUG(("Remote host is %s", - entry->data.conn_type == SILC_CONN_SERVER ? + entry->conn_type == SILC_CONN_SERVER ? "server" : (backup_router ? "backup router" : "router"))); SILC_LOG_INFO(("Connection %s (%s) is %s", entry->hostname, - entry->ip, entry->data.conn_type == SILC_CONN_SERVER ? + entry->ip, entry->conn_type == SILC_CONN_SERVER ? "server" : (backup_router ? "backup router" : "router"))); @@ -2350,15 +2381,15 @@ silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success, server. We mark ourselves as router for this server if we really are router. */ new_server = - silc_idlist_add_server((entry->data.conn_type == SILC_CONN_SERVER ? + silc_idlist_add_server((entry->conn_type == SILC_CONN_SERVER ? server->local_list : (backup_router ? server->local_list : server->global_list)), NULL, - (entry->data.conn_type == SILC_CONN_SERVER ? + (entry->conn_type == SILC_CONN_SERVER ? SILC_SERVER : SILC_ROUTER), NULL, - (entry->data.conn_type == SILC_CONN_SERVER ? + (entry->conn_type == SILC_CONN_SERVER ? server->id_entry : (backup_router ? server->id_entry : NULL)), sock); @@ -2370,6 +2401,7 @@ silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success, goto out; } entry->data.status |= SILC_IDLIST_STATUS_LOCAL; + entry->data.conn_type = entry->conn_type; id_entry = (void *)new_server; @@ -2510,6 +2542,8 @@ silc_server_accept_completed(SilcSKE ske, SilcSKEStatus status, pk = silc_pkcs_public_key_encode(idata->public_key, &pk_len); silc_hash_make(server->sha1hash, pk, pk_len, idata->fingerprint); + silc_hash_alloc(silc_hash_get_name(prop->hash), &idata->hash); + SILC_LOG_DEBUG(("Starting connection authentication")); server->stat.auth_attempts++; diff --git a/apps/silcd/server_util.c b/apps/silcd/server_util.c index 19ea23e6..3fb71553 100644 --- a/apps/silcd/server_util.c +++ b/apps/silcd/server_util.c @@ -1112,6 +1112,13 @@ SilcPublicKey silc_server_get_public_key(SilcServer server, silc_skr_find(server->repository, server->schedule, find, find_callback, &public_key); +#ifdef SILC_DEBUG + if (public_key) + SILC_LOG_DEBUG(("Found public key")); + else + SILC_LOG_DEBUG(("Public key not found")); +#endif /* SILC_DEBUG */ + return public_key; } -- 2.24.0