SilcClientEntry client_entry, client_entry2;
SilcChannelEntry channel_entry;
char *tmp = NULL;
- unsigned int tmp_int;
+ uint32 tmp_int;
va_start(vp, type);
case SILC_NOTIFY_TYPE_CMODE_CHANGE:
client_entry = va_arg(vp, SilcClientEntry);
- tmp_int = va_arg(vp, unsigned int);
+ tmp_int = va_arg(vp, uint32);
(void)va_arg(vp, char *);
(void)va_arg(vp, char *);
channel_entry = va_arg(vp, SilcChannelEntry);
case SILC_NOTIFY_TYPE_CUMODE_CHANGE:
client_entry = va_arg(vp, SilcClientEntry);
- tmp_int = va_arg(vp, unsigned int);
+ tmp_int = va_arg(vp, uint32);
tmp = silc_client_chumode(tmp_int);
client_entry2 = va_arg(vp, SilcClientEntry);
channel_entry = va_arg(vp, SilcChannelEntry);
}
break;
+ case SILC_NOTIFY_TYPE_SERVER_SIGNOFF:
+ {
+ SilcClientEntry *clients;
+ uint32 clients_count;
+ int i;
+
+ (void)va_arg(vp, void *);
+ clients = va_arg(vp, SilcClientEntry *);
+ clients_count = va_arg(vp, uint32);
+
+ for (i = 0; i < clients_count; i++) {
+ if (clients[i]->server)
+ snprintf(message, sizeof(message), "Server signoff: %s@%s %s%s%s",
+ clients[i]->nickname, clients[i]->server,
+ tmp ? "(" : "", tmp ? tmp : "", tmp ? ")" : "");
+ else
+ snprintf(message, sizeof(message), "Server signoff: %s %s%s%s",
+ clients[i]->nickname,
+ tmp ? "(" : "", tmp ? tmp : "", tmp ? ")" : "");
+ silc_print(client, "*** %s", message);
+ memset(message, 0, sizeof(message));
+ }
+ return;
+ }
+
default:
break;
}
void silc_client_show_users(SilcClient client,
SilcClientConnection conn,
SilcClientEntry *clients,
- unsigned int clients_count,
+ uint32 clients_count,
void *context)
{
SilcChannelEntry channel = (SilcChannelEntry)context;
{
char buf[1024], *nickname, *username, *realname;
int len;
- unsigned int idle, mode;
+ uint32 idle, mode;
SilcBuffer channels;
if (status == SILC_STATUS_ERR_NO_SUCH_NICK ||
username = va_arg(vp, char *);
realname = va_arg(vp, char *);
channels = va_arg(vp, SilcBuffer);
- mode = va_arg(vp, unsigned int);
- idle = va_arg(vp, unsigned int);
+ mode = va_arg(vp, uint32);
+ idle = va_arg(vp, uint32);
memset(buf, 0, sizeof(buf));
silc_dlist_start(list);
while ((entry = silc_dlist_get(list)) != SILC_LIST_END) {
char *m = silc_client_chumode_char(silc_channel_get_mode(entry));
- unsigned int name_len;
+ uint32 name_len;
char *name = silc_channel_get_name(entry, &name_len);
if (m)
case SILC_COMMAND_JOIN:
{
- unsigned int mode;
+ uint32 mode;
char *topic;
SilcBuffer client_id_list;
- unsigned int list_count;
+ uint32 list_count;
SilcChannelEntry channel;
if (!success)
app->screen->bottom_line->channel = va_arg(vp, char *);
channel = va_arg(vp, SilcChannelEntry);
- mode = va_arg(vp, unsigned int);
- (void)va_arg(vp, unsigned int);
+ mode = va_arg(vp, uint32);
+ (void)va_arg(vp, uint32);
(void)va_arg(vp, unsigned char *);
(void)va_arg(vp, unsigned char *);
(void)va_arg(vp, unsigned char *);
topic = va_arg(vp, char *);
(void)va_arg(vp, unsigned char *);
- list_count = va_arg(vp, unsigned int);
+ list_count = va_arg(vp, uint32);
client_id_list = va_arg(vp, SilcBuffer);
if (topic)
case SILC_COMMAND_LIST:
{
char *topic, *name;
- unsigned int usercount;
+ int usercount;
unsigned char buf[256], tmp[16];
int i, len;
(void)va_arg(vp, SilcChannelEntry);
name = va_arg(vp, char *);
topic = va_arg(vp, char *);
- usercount = va_arg(vp, unsigned int);
+ usercount = va_arg(vp, int);
if (status == SILC_STATUS_LIST_START ||
status == SILC_STATUS_OK)
case SILC_COMMAND_UMODE:
{
- unsigned int mode;
+ uint32 mode;
if (!success)
return;
- mode = va_arg(vp, unsigned int);
+ mode = va_arg(vp, uint32);
if (!mode && app->screen->bottom_line->umode) {
silc_free(app->screen->bottom_line->umode);
}
break;
+ case SILC_COMMAND_GETKEY:
+ {
+ SilcIdType id_type;
+ void *entry;
+ SilcPublicKey public_key;
+ unsigned char *pk;
+ uint32 pk_len;
+
+ id_type = va_arg(vp, SilcIdType);
+ entry = va_arg(vp, void *);
+ public_key = va_arg(vp, SilcPublicKey);
+
+ pk = silc_pkcs_public_key_encode(public_key, &pk_len);
+
+ if (id_type == SILC_ID_CLIENT) {
+ silc_verify_public_key(client, conn, SILC_SOCKET_TYPE_CLIENT,
+ pk, pk_len, SILC_SKE_PK_TYPE_SILC);
+ }
+
+ silc_free(pk);
+ }
+
default:
break;
}
int silc_verify_public_key(SilcClient client,
SilcClientConnection conn,
SilcSocketType conn_type,
- unsigned char *pk, unsigned int pk_len,
+ unsigned char *pk, uint32 pk_len,
SilcSKEPKType pk_type)
{
- SilcSocketConnection sock = conn->sock;
+ int i;
char filename[256];
char file[256];
- char *hostname, *fingerprint;
+ char *fingerprint;
struct passwd *pw;
struct stat st;
char *entity = ((conn_type == SILC_SOCKET_TYPE_SERVER ||
conn_type == SILC_SOCKET_TYPE_ROUTER) ?
"server" : "client");
- hostname = sock->hostname ? sock->hostname : sock->ip;
-
if (pk_type != SILC_SKE_PK_TYPE_SILC) {
- silc_say(client, conn, "We don't support %s %s key type",
- entity, hostname);
+ silc_say(client, conn, "We don't support %s key type %d",
+ entity, pk_type);
return FALSE;
}
if (!pw)
return FALSE;
+ /* Replace all whitespaces with `_'. */
+ fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
+ for (i = 0; i < strlen(fingerprint); i++)
+ if (fingerprint[i] == ' ')
+ fingerprint[i] = '_';
+
memset(filename, 0, sizeof(filename));
memset(file, 0, sizeof(file));
- snprintf(file, sizeof(file) - 1, "%skey_%s_%d.pub", entity, hostname,
- sock->port);
+ snprintf(file, sizeof(file) - 1, "%skey_%s.pub", entity, fingerprint);
snprintf(filename, sizeof(filename) - 1, "%s/.silc/%skeys/%s",
pw->pw_dir, entity, file);
+ silc_free(fingerprint);
- /* Check wheter this key already exists */
+ fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
+
+ /* Check whether this key already exists */
if (stat(filename, &st) < 0) {
- fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
- silc_say(client, conn, "Received %s %s public key", entity, hostname);
- silc_say(client, conn, "Fingerprint for the %s %s key is", entity,
- hostname);
+ silc_say(client, conn, "Received %s public key", entity);
+ silc_say(client, conn, "Fingerprint for the %s key is", entity);
silc_say(client, conn, "%s", fingerprint);
- silc_free(fingerprint);
/* Ask user to verify the key and save it */
if (silc_client_ask_yes_no(client,
/* Save the key for future checking */
silc_pkcs_save_public_key_data(filename, pk, pk_len,
SILC_PKCS_FILE_PEM);
+ silc_free(fingerprint);
return TRUE;
}
} else {
/* The key already exists, verify it. */
SilcPublicKey public_key;
unsigned char *encpk;
- unsigned int encpk_len;
+ uint32 encpk_len;
/* Load the key file */
if (!silc_pkcs_load_public_key(filename, &public_key,
SILC_PKCS_FILE_PEM))
if (!silc_pkcs_load_public_key(filename, &public_key,
SILC_PKCS_FILE_BIN)) {
- fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
- silc_say(client, conn, "Received %s %s public key", entity, hostname);
- silc_say(client, conn, "Fingerprint for the %s %s key is",
- entity, hostname);
+ silc_say(client, conn, "Received %s public key", entity);
+ silc_say(client, conn, "Fingerprint for the %s key is", entity);
silc_say(client, conn, "%s", fingerprint);
- silc_free(fingerprint);
- silc_say(client, conn, "Could not load your local copy of the %s %s key",
- entity, hostname);
+ silc_say(client, conn, "Could not load your local copy of the %s key",
+ entity);
if (silc_client_ask_yes_no(client,
"Would you like to accept the key anyway (y/n)? "))
{
unlink(filename);
silc_pkcs_save_public_key_data(filename, pk, pk_len,
SILC_PKCS_FILE_PEM);
+ silc_free(fingerprint);
return TRUE;
}
+ silc_free(fingerprint);
return FALSE;
}
/* Encode the key data */
encpk = silc_pkcs_public_key_encode(public_key, &encpk_len);
if (!encpk) {
- fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
- silc_say(client, conn, "Received %s %s public key", entity, hostname);
- silc_say(client, conn, "Fingerprint for the %s %s key is",
- entity, hostname);
+ silc_say(client, conn, "Received %s public key", entity);
+ silc_say(client, conn, "Fingerprint for the %s key is", entity);
silc_say(client, conn, "%s", fingerprint);
- silc_free(fingerprint);
- silc_say(client, conn, "Your local copy of the %s %s key is malformed",
- entity, hostname);
+ silc_say(client, conn, "Your local copy of the %s key is malformed",
+ entity);
if (silc_client_ask_yes_no(client,
"Would you like to accept the key anyway (y/n)? "))
{
unlink(filename);
silc_pkcs_save_public_key_data(filename, pk, pk_len,
SILC_PKCS_FILE_PEM);
+ silc_free(fingerprint);
return TRUE;
}
+ silc_free(fingerprint);
return FALSE;
}
if (memcmp(encpk, pk, encpk_len)) {
- fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
- silc_say(client, conn, "Received %s %s public key", entity, hostname);
- silc_say(client, conn, "Fingerprint for the %s %s key is",
- entity, hostname);
+ silc_say(client, conn, "Received %s public key", entity);
+ silc_say(client, conn, "Fingerprint for the %s key is", entity);
silc_say(client, conn, "%s", fingerprint);
- silc_free(fingerprint);
- silc_say(client, conn, "%s %s key does not match with your local copy",
- entity, hostname);
- silc_say(client, conn, "It is possible that the key has expired or changed");
+ silc_say(client, conn, "%s key does not match with your local copy",
+ entity);
+ silc_say(client, conn,
+ "It is possible that the key has expired or changed");
silc_say(client, conn, "It is also possible that some one is performing "
"man-in-the-middle attack");
unlink(filename);
silc_pkcs_save_public_key_data(filename, pk, pk_len,
SILC_PKCS_FILE_PEM);
+ silc_free(fingerprint);
return TRUE;
}
- silc_say(client, conn, "Will not accept %s %s key", entity, hostname);
+ silc_say(client, conn, "Will not accept the %s key", entity);
+ silc_free(fingerprint);
return FALSE;
}
/* Local copy matched */
+ silc_free(fingerprint);
return TRUE;
}
- silc_say(client, conn, "Will not accept %s %s key", entity, hostname);
+ silc_say(client, conn, "Will not accept the %s key", entity);
+ silc_free(fingerprint);
return FALSE;
}
is found and FALSE if not. `conn' may be NULL. */
int silc_get_auth_method(SilcClient client, SilcClientConnection conn,
- char *hostname, unsigned short port,
+ char *hostname, uint16 port,
SilcProtocolAuthMeth *auth_meth,
unsigned char **auth_data,
- unsigned int *auth_data_len)
+ uint32 *auth_data_len)
{
SilcClientInternal app = (SilcClientInternal)client->application;
- if (app->config->conns) {
+ if (app->config && app->config->conns) {
SilcClientConfigSectionConnection *conn = NULL;
/* Check if we find a match from user configured connections */
void silc_failure(SilcClient client, SilcClientConnection conn,
SilcProtocol protocol, void *failure)
{
+ if (protocol->protocol->type == SILC_PROTOCOL_CLIENT_KEY_EXCHANGE) {
+ SilcSKEStatus status = (SilcSKEStatus)failure;
+
+ if (status == SILC_SKE_STATUS_BAD_VERSION)
+ silc_say(client, conn,
+ "You are running incompatible client version (it may be "
+ "too old or too new)");
+ if (status == SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY)
+ silc_say(client, conn, "Server does not support your public key type");
+ if (status == SILC_SKE_STATUS_UNKNOWN_GROUP)
+ silc_say(client, conn,
+ "Server does not support one of your proposed KE group");
+ if (status == SILC_SKE_STATUS_UNKNOWN_CIPHER)
+ silc_say(client, conn,
+ "Server does not support one of your proposed cipher");
+ if (status == SILC_SKE_STATUS_UNKNOWN_PKCS)
+ silc_say(client, conn,
+ "Server does not support one of your proposed PKCS");
+ if (status == SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION)
+ silc_say(client, conn,
+ "Server does not support one of your proposed hash function");
+ if (status == SILC_SKE_STATUS_UNKNOWN_HMAC)
+ silc_say(client, conn,
+ "Server does not support one of your proposed HMAC");
+ if (status == SILC_SKE_STATUS_INCORRECT_SIGNATURE)
+ silc_say(client, conn, "Incorrect signature");
+ }
+ if (protocol->protocol->type == SILC_PROTOCOL_CLIENT_CONNECTION_AUTH) {
+ uint32 err = (uint32)failure;
+
+ if (err == SILC_AUTH_FAILED)
+ silc_say(client, conn, "Authentication failed");
+ }
}
/* Asks whether the user would like to perform the key agreement protocol.
/* SILC client operations */
SilcClientOperations ops = {
- say: silc_say,
- channel_message: silc_channel_message,
- private_message: silc_private_message,
- notify: silc_notify,
- command: silc_command,
- command_reply: silc_command_reply,
- connect: silc_connect,
- disconnect: silc_disconnect,
- get_auth_method: silc_get_auth_method,
- verify_public_key: silc_verify_public_key,
- ask_passphrase: silc_ask_passphrase,
- failure: silc_failure,
- key_agreement: silc_key_agreement,
+ silc_say,
+ silc_channel_message,
+ silc_private_message,
+ silc_notify,
+ silc_command,
+ silc_command_reply,
+ silc_connect,
+ silc_disconnect,
+ silc_get_auth_method,
+ silc_verify_public_key,
+ silc_ask_passphrase,
+ silc_failure,
+ silc_key_agreement,
};