#include "settings.h"
#include "fe-common/core/printtext.h"
#include "fe-common/core/fe-channels.h"
+#include "fe-common/core/keyboard.h"
+#include "fe-common/silc/module-formats.h"
/* Command line option variables */
-static char *opt_server = NULL;
-static int opt_port = 0;
-static char *opt_nickname = NULL;
-static char *opt_channel = NULL;
-static char *opt_cipher = NULL;
-static char *opt_public_key = NULL;
-static char *opt_private_key = NULL;
-static char *opt_config_file = NULL;
-static bool opt_no_silcrc = FALSE;
-
static bool opt_create_keypair = FALSE;
+static bool opt_debug = FALSE;
static char *opt_pkcs = NULL;
static char *opt_keyfile = NULL;
static int opt_bits = 0;
SilcClient silc_client = NULL;
SilcClientConfig silc_config = NULL;
extern SilcClientOperations ops;
+extern int silc_debug;
#ifdef SILC_SIM
/* SIM (SILC Module) table */
SilcSimContext **sims = NULL;
silc_command_reply(SilcClient client, SilcClientConnection conn,
SilcCommandPayload cmd_payload, int success,
SilcCommand command, SilcCommandStatus status, ...);
-
-static int silc_verify_public_key(SilcClient client,
- SilcClientConnection conn,
- SilcSocketType conn_type,
- unsigned char *pk, uint32 pk_len,
- SilcSKEPKType pk_type);
-static unsigned char *silc_ask_passphrase(SilcClient client,
- SilcClientConnection conn);
+static void
+silc_verify_public_key_internal(SilcClient client, SilcClientConnection conn,
+ SilcSocketType conn_type, unsigned char *pk,
+ uint32 pk_len, SilcSKEPKType pk_type,
+ SilcVerifyPublicKey completion, void *context);
+static void
+silc_verify_public_key(SilcClient client, SilcClientConnection conn,
+ SilcSocketType conn_type, unsigned char *pk,
+ uint32 pk_len, SilcSKEPKType pk_type,
+ SilcVerifyPublicKey completion, void *context);
+static void silc_ask_passphrase(SilcClient client, SilcClientConnection conn,
+ SilcAskPassphrase completion, void *context);
static int
silc_get_auth_method(SilcClient client, SilcClientConnection conn,
char *hostname, uint16 port,
va_start(va, msg);
str = g_strdup_vprintf(msg, va);
- printtext(server, "#silc", MSGLEVEL_CRAP, "%s", str);
+ printtext(server, NULL, MSGLEVEL_CRAP, "%s", str);
g_free(str);
va_end(va);
}
chanrec = silc_channel_find_entry(server, channel);
nick = silc_nicklist_find(chanrec, sender);
- signal_emit("message public", 6, server, msg,
- nick == NULL ? "[<unknown>]" : nick->nick,
- nick == NULL ? NULL : nick->host,
- chanrec->name, nick);
+
+ if (flags & SILC_MESSAGE_FLAG_ACTION)
+ ;
+ else if (flags & SILC_MESSAGE_FLAG_NOTICE)
+ ;
+ else
+ signal_emit("message public", 6, server, msg,
+ nick == NULL ? "[<unknown>]" : nick->nick,
+ nick == NULL ? NULL : nick->host,
+ chanrec->name, nick);
}
/* Private message to the client. The `sender' is the nickname of the
SilcChannelUser chu;
SILC_SERVER_REC *server = conn->context;
SILC_CHANNEL_REC *chanrec;
+ SilcClientEntry founder = NULL;
NICK_REC *ownnick;
if (!clients)
return;
- chanrec = silc_channel_find_entry(server, channel);
+ chanrec = silc_channel_find(server, channel->channel_name);
if (chanrec == NULL)
return;
silc_list_start(channel->clients);
- while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END)
+ while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) {
+ if (chu->mode & SILC_CHANNEL_UMODE_CHANFO)
+ founder = chu->client;
silc_nicklist_insert(chanrec, chu, FALSE);
+ }
ownnick = NICK(silc_nicklist_find(chanrec, conn->local_entry));
nicklist_set_own(CHANNEL(chanrec), ownnick);
signal_emit("channel joined", 1, chanrec);
+
+ if (chanrec->topic)
+ printformat_module("fe-common/silc", server, channel->channel_name,
+ MSGLEVEL_CRAP, SILCTXT_CHANNEL_TOPIC,
+ channel->channel_name, chanrec->topic);
+
fe_channels_nicklist(CHANNEL(chanrec), CHANNEL_NICKLIST_FLAG_ALL);
+
+ if (founder) {
+ if (founder == conn->local_entry)
+ printformat_module("fe-common/silc",
+ server, channel->channel_name, MSGLEVEL_CRAP,
+ SILCTXT_CHANNEL_FOUNDER_YOU,
+ channel->channel_name);
+ else
+ printformat_module("fe-common/silc",
+ server, channel->channel_name, MSGLEVEL_CRAP,
+ SILCTXT_CHANNEL_FOUNDER,
+ channel->channel_name, founder->nickname);
+ }
}
/* Command reply handler. This function is called always in the command reply
va_start(vp, status);
switch(command) {
- case SILC_COMMAND_WHOIS:
- {
- char buf[1024], *nickname, *username, *realname;
- int len;
- uint32 idle, mode;
- SilcBuffer channels;
-
- /* XXX should use irssi routines */
-
- if (status == SILC_STATUS_ERR_NO_SUCH_NICK ||
- status == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID) {
- char *tmp;
- tmp = silc_argument_get_arg_type(silc_command_get_args(cmd_payload),
- 3, NULL);
- if (tmp)
- client->ops->say(client, conn, "%s: %s", tmp,
- silc_client_command_status_message(status));
- else
- client->ops->say(client, conn, "%s",
- silc_client_command_status_message(status));
- break;
- }
-
- if (!success)
- return;
-
- (void)va_arg(vp, SilcClientEntry);
- nickname = va_arg(vp, char *);
- username = va_arg(vp, char *);
- realname = va_arg(vp, char *);
- channels = va_arg(vp, SilcBuffer);
- mode = va_arg(vp, uint32);
- idle = va_arg(vp, uint32);
-
- memset(buf, 0, sizeof(buf));
-
- if (nickname) {
- len = strlen(nickname);
- strncat(buf, nickname, len);
- strncat(buf, " is ", 4);
- }
+ case SILC_COMMAND_WHOIS:
+ {
+ char buf[1024], *nickname, *username, *realname;
+ int len;
+ uint32 idle, mode;
+ SilcBuffer channels;
+
+ /* XXX should use irssi routines */
+
+ if (status == SILC_STATUS_ERR_NO_SUCH_NICK ||
+ status == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID) {
+ char *tmp;
+ tmp = silc_argument_get_arg_type(silc_command_get_args(cmd_payload),
+ 3, NULL);
+ if (tmp)
+ client->ops->say(client, conn, "%s: %s", tmp,
+ silc_client_command_status_message(status));
+ else
+ client->ops->say(client, conn, "%s",
+ silc_client_command_status_message(status));
+ break;
+ }
+
+ if (!success)
+ return;
+
+ (void)va_arg(vp, SilcClientEntry);
+ nickname = va_arg(vp, char *);
+ username = va_arg(vp, char *);
+ realname = va_arg(vp, char *);
+ channels = va_arg(vp, SilcBuffer);
+ mode = va_arg(vp, uint32);
+ idle = va_arg(vp, uint32);
+
+ memset(buf, 0, sizeof(buf));
+
+ if (nickname) {
+ len = strlen(nickname);
+ strncat(buf, nickname, len);
+ strncat(buf, " is ", 4);
+ }
- if (username) {
- strncat(buf, username, strlen(username));
- }
+ if (username) {
+ strncat(buf, username, strlen(username));
+ }
- if (realname) {
- strncat(buf, " (", 2);
- strncat(buf, realname, strlen(realname));
- strncat(buf, ")", 1);
- }
-
- client->ops->say(client, conn, "%s", buf);
-
- if (channels) {
- SilcDList list = silc_channel_payload_parse_list(channels);
- if (list) {
- SilcChannelPayload entry;
-
- memset(buf, 0, sizeof(buf));
- strcat(buf, "on channels: ");
-
- silc_dlist_start(list);
- while ((entry = silc_dlist_get(list)) != SILC_LIST_END) {
- char *m = silc_client_chumode_char(silc_channel_get_mode(entry));
- uint32 name_len;
- char *name = silc_channel_get_name(entry, &name_len);
-
- if (m)
- strncat(buf, m, strlen(m));
- strncat(buf, name, name_len);
- strncat(buf, " ", 1);
- silc_free(m);
- }
-
- client->ops->say(client, conn, "%s", buf);
- silc_channel_payload_list_free(list);
+ if (realname) {
+ strncat(buf, " (", 2);
+ strncat(buf, realname, strlen(realname));
+ strncat(buf, ")", 1);
+ }
+
+ client->ops->say(client, conn, "%s", buf);
+
+ if (channels) {
+ SilcDList list = silc_channel_payload_parse_list(channels);
+ if (list) {
+ SilcChannelPayload entry;
+
+ memset(buf, 0, sizeof(buf));
+ strcat(buf, "on channels: ");
+
+ silc_dlist_start(list);
+ while ((entry = silc_dlist_get(list)) != SILC_LIST_END) {
+ char *m = silc_client_chumode_char(silc_channel_get_mode(entry));
+ uint32 name_len;
+ char *name = silc_channel_get_name(entry, &name_len);
+
+ if (m)
+ strncat(buf, m, strlen(m));
+ strncat(buf, name, name_len);
+ strncat(buf, " ", 1);
+ silc_free(m);
}
- }
- if (mode) {
- if ((mode & SILC_UMODE_SERVER_OPERATOR) ||
- (mode & SILC_UMODE_ROUTER_OPERATOR))
- client->ops->say(client, conn, "%s is %s", nickname,
- (mode & SILC_UMODE_SERVER_OPERATOR) ?
- "Server Operator" :
- (mode & SILC_UMODE_ROUTER_OPERATOR) ?
- "SILC Operator" : "[Unknown mode]");
-
- if (mode & SILC_UMODE_GONE)
- client->ops->say(client, conn, "%s is gone", nickname);
+ client->ops->say(client, conn, "%s", buf);
+ silc_channel_payload_list_free(list);
}
-
- if (idle && nickname)
- client->ops->say(client, conn, "%s has been idle %d %s",
- nickname,
- idle > 60 ? (idle / 60) : idle,
- idle > 60 ? "minutes" : "seconds");
}
- break;
-
- case SILC_COMMAND_WHOWAS:
- {
- char buf[1024], *nickname, *username, *realname;
- int len;
-
- /* XXX should use irssi routines */
-
- if (status == SILC_STATUS_ERR_NO_SUCH_NICK ||
- status == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID) {
- char *tmp;
- tmp = silc_argument_get_arg_type(silc_command_get_args(cmd_payload),
- 3, NULL);
- if (tmp)
- client->ops->say(client, conn, "%s: %s", tmp,
- silc_client_command_status_message(status));
- else
- client->ops->say(client, conn, "%s",
- silc_client_command_status_message(status));
- break;
- }
-
- if (!success)
- return;
-
- (void)va_arg(vp, SilcClientEntry);
- nickname = va_arg(vp, char *);
- username = va_arg(vp, char *);
- realname = va_arg(vp, char *);
-
- memset(buf, 0, sizeof(buf));
-
- if (nickname) {
- len = strlen(nickname);
- strncat(buf, nickname, len);
- strncat(buf, " was ", 5);
- }
-
- if (username) {
- strncat(buf, username, strlen(nickname));
- }
+
+ if (mode) {
+ if ((mode & SILC_UMODE_SERVER_OPERATOR) ||
+ (mode & SILC_UMODE_ROUTER_OPERATOR))
+ client->ops->say(client, conn, "%s is %s", nickname,
+ (mode & SILC_UMODE_SERVER_OPERATOR) ?
+ "Server Operator" :
+ (mode & SILC_UMODE_ROUTER_OPERATOR) ?
+ "SILC Operator" : "[Unknown mode]");
- if (realname) {
- strncat(buf, " (", 2);
- strncat(buf, realname, strlen(realname));
- strncat(buf, ")", 1);
- }
-
- client->ops->say(client, conn, "%s", buf);
+ if (mode & SILC_UMODE_GONE)
+ client->ops->say(client, conn, "%s is gone", nickname);
}
- break;
-
- case SILC_COMMAND_INVITE:
- {
- SilcChannelEntry channel;
- char *invite_list;
-
- if (!success)
- return;
-
- /* XXX should use irssi routines */
-
- channel = va_arg(vp, SilcChannelEntry);
- invite_list = va_arg(vp, char *);
-
- if (invite_list)
- silc_say(client, conn, "%s invite list: %s", channel->channel_name,
- invite_list);
+
+ if (idle && nickname)
+ client->ops->say(client, conn, "%s has been idle %d %s",
+ nickname,
+ idle > 60 ? (idle / 60) : idle,
+ idle > 60 ? "minutes" : "seconds");
+ }
+ break;
+
+ case SILC_COMMAND_WHOWAS:
+ {
+ char buf[1024], *nickname, *username, *realname;
+ int len;
+
+ /* XXX should use irssi routines */
+
+ if (status == SILC_STATUS_ERR_NO_SUCH_NICK ||
+ status == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID) {
+ char *tmp;
+ tmp = silc_argument_get_arg_type(silc_command_get_args(cmd_payload),
+ 3, NULL);
+ if (tmp)
+ client->ops->say(client, conn, "%s: %s", tmp,
+ silc_client_command_status_message(status));
else
- silc_say(client, conn, "%s invite list not set",
- channel->channel_name);
+ client->ops->say(client, conn, "%s",
+ silc_client_command_status_message(status));
+ break;
}
- break;
+
+ if (!success)
+ return;
+
+ (void)va_arg(vp, SilcClientEntry);
+ nickname = va_arg(vp, char *);
+ username = va_arg(vp, char *);
+ realname = va_arg(vp, char *);
+
+ memset(buf, 0, sizeof(buf));
+
+ if (nickname) {
+ len = strlen(nickname);
+ strncat(buf, nickname, len);
+ strncat(buf, " was ", 5);
+ }
+
+ if (username) {
+ strncat(buf, username, strlen(nickname));
+ }
+
+ if (realname) {
+ strncat(buf, " (", 2);
+ strncat(buf, realname, strlen(realname));
+ strncat(buf, ")", 1);
+ }
+
+ client->ops->say(client, conn, "%s", buf);
+ }
+ break;
+
+ case SILC_COMMAND_INVITE:
+ {
+ SilcChannelEntry channel;
+ char *invite_list;
+
+ if (!success)
+ return;
+
+ /* XXX should use irssi routines */
+
+ channel = va_arg(vp, SilcChannelEntry);
+ invite_list = va_arg(vp, char *);
+
+ if (invite_list)
+ silc_say(client, conn, "%s invite list: %s", channel->channel_name,
+ invite_list);
+ else
+ silc_say(client, conn, "%s invite list not set",
+ channel->channel_name);
+ }
+ break;
case SILC_COMMAND_JOIN:
{
list_count = va_arg(vp, uint32);
client_id_list = va_arg(vp, SilcBuffer);
- /* XXX what an earth do I do with the topic??? */
-
if (!success)
return;
else if (chanrec == NULL && success)
chanrec = silc_channel_create(server, channel, TRUE);
+ if (topic) {
+ g_free_not_null(chanrec->topic);
+ chanrec->topic = *topic == '\0' ? NULL : g_strdup(topic);
+ signal_emit("channel topic changed", 1, chanrec);
+ }
+
mode = silc_client_chmode(modei, channel_entry);
g_free_not_null(chanrec->mode);
chanrec->mode = g_strdup(mode == NULL ? "" : mode);
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_verify_public_key_internal(client, conn, SILC_SOCKET_TYPE_CLIENT,
+ pk, pk_len, SILC_SKE_PK_TYPE_SILC,
+ NULL, NULL);
}
silc_free(pk);
va_end(vp);
}
-/* Verifies received public key. If user decides to trust the key it is
- saved as public server key for later use. If user does not trust the
- key this returns FALSE. */
+/* Internal routine to verify public key. If the `completion' is provided
+ it will be called to indicate whether public was verified or not. */
-static int silc_verify_public_key(SilcClient client,
- SilcClientConnection conn,
- SilcSocketType conn_type,
- unsigned char *pk, uint32 pk_len,
- SilcSKEPKType pk_type)
+typedef struct {
+ SilcClient client;
+ SilcClientConnection conn;
+ char *filename;
+ char *entity;
+ unsigned char *pk;
+ uint32 pk_len;
+ SilcSKEPKType pk_type;
+ SilcVerifyPublicKey completion;
+ void *context;
+} *PublicKeyVerify;
+
+static void verify_public_key_completion(const char *line, void *context)
{
- return TRUE;
+ PublicKeyVerify verify = (PublicKeyVerify)context;
+
+ if (line[0] == 'Y' || line[0] == 'y') {
+ /* Call the completion */
+ if (verify->completion)
+ verify->completion(TRUE, verify->context);
+
+ /* Save the key for future checking */
+ silc_pkcs_save_public_key_data(verify->filename, verify->pk,
+ verify->pk_len, SILC_PKCS_FILE_PEM);
+ } else {
+ /* Call the completion */
+ if (verify->completion)
+ verify->completion(FALSE, verify->context);
+
+ silc_say(verify->client,
+ verify->conn, "Will not accept the %s key", verify->entity);
+ }
+
+ silc_free(verify->filename);
+ silc_free(verify->entity);
+ silc_free(verify);
+}
+
+static void
+silc_verify_public_key_internal(SilcClient client, SilcClientConnection conn,
+ SilcSocketType conn_type, unsigned char *pk,
+ uint32 pk_len, SilcSKEPKType pk_type,
+ SilcVerifyPublicKey completion, void *context)
+{
+ int i;
+ char file[256], filename[256], *fingerprint;
+ struct passwd *pw;
+ struct stat st;
+ char *entity = ((conn_type == SILC_SOCKET_TYPE_SERVER ||
+ conn_type == SILC_SOCKET_TYPE_ROUTER) ?
+ "server" : "client");
+ PublicKeyVerify verify;
+
+ if (pk_type != SILC_SKE_PK_TYPE_SILC) {
+ silc_say(client, conn, "We don't support %s public key type %d",
+ entity, pk_type);
+ if (completion)
+ completion(FALSE, context);
+ return;
+ }
+
+ pw = getpwuid(getuid());
+ if (!pw) {
+ if (completion)
+ completion(FALSE, context);
+ return;
+ }
+
+ memset(filename, 0, sizeof(filename));
+ memset(file, 0, sizeof(file));
+
+ if (conn_type == SILC_SOCKET_TYPE_SERVER ||
+ conn_type == SILC_SOCKET_TYPE_ROUTER) {
+ snprintf(file, sizeof(file) - 1, "%skey_%s_%d.pub", entity,
+ conn->sock->hostname, conn->sock->port);
+ snprintf(filename, sizeof(filename) - 1, "%s/.silc/%skeys/%s",
+ pw->pw_dir, entity, file);
+ } else {
+ /* Replace all whitespaces with `_'. */
+ fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
+ for (i = 0; i < strlen(fingerprint); i++)
+ if (fingerprint[i] == ' ')
+ fingerprint[i] = '_';
+
+ 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);
+ }
+
+ /* Take fingerprint of the public key */
+ fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
+
+ verify = silc_calloc(1, sizeof(*verify));
+ verify->client = client;
+ verify->conn = conn;
+ verify->filename = strdup(filename);
+ verify->entity = strdup(entity);
+ verify->pk = pk;
+ verify->pk_len = pk_len;
+ verify->pk_type = pk_type;
+ verify->completion = completion;
+ verify->context = context;
+
+ /* Check whether this key already exists */
+ if (stat(filename, &st) < 0) {
+ /* Key does not exist, ask user to verify the key and save it */
+
+ 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);
+
+ keyboard_entry_redirect((SIGNAL_FUNC)verify_public_key_completion,
+ "Would you like to accept the key (y/n)? ", 0,
+ verify);
+ silc_free(fingerprint);
+ return;
+ } else {
+ /* The key already exists, verify it. */
+ SilcPublicKey public_key;
+ unsigned char *encpk;
+ 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)) {
+ 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_say(client, conn, "Could not load your local copy of the %s key",
+ entity);
+ keyboard_entry_redirect((SIGNAL_FUNC)verify_public_key_completion,
+ "Would you like to accept the key "
+ "anyway (y/n)? ", 0,
+ verify);
+ silc_free(fingerprint);
+ return;
+ }
+
+ /* Encode the key data */
+ encpk = silc_pkcs_public_key_encode(public_key, &encpk_len);
+ if (!encpk) {
+ 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_say(client, conn, "Your local copy of the %s key is malformed",
+ entity);
+ keyboard_entry_redirect((SIGNAL_FUNC)verify_public_key_completion,
+ "Would you like to accept the key "
+ "anyway (y/n)? ", 0,
+ verify);
+ silc_free(fingerprint);
+ return;
+ }
+
+ /* Compare the keys */
+ if (memcmp(encpk, pk, encpk_len)) {
+ 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_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");
+
+ /* Ask user to verify the key and save it */
+ keyboard_entry_redirect((SIGNAL_FUNC)verify_public_key_completion,
+ "Would you like to accept the key "
+ "anyway (y/n)? ", 0,
+ verify);
+ silc_free(fingerprint);
+ return;
+ }
+
+ /* Local copy matched */
+ if (completion)
+ completion(TRUE, context);
+ silc_free(fingerprint);
+ }
+}
+
+/* Verifies received public key. The `conn_type' indicates which entity
+ (server, client etc.) has sent the public key. If user decides to trust
+ the key may be saved as trusted public key for later use. The
+ `completion' must be called after the public key has been verified. */
+
+static void
+silc_verify_public_key(SilcClient client, SilcClientConnection conn,
+ SilcSocketType conn_type, unsigned char *pk,
+ uint32 pk_len, SilcSKEPKType pk_type,
+ SilcVerifyPublicKey completion, void *context)
+{
+ silc_verify_public_key_internal(client, conn, conn_type, pk,
+ pk_len, pk_type,
+ completion, context);
}
/* Asks passphrase from user on the input line. */
-static unsigned char *silc_ask_passphrase(SilcClient client,
- SilcClientConnection conn)
+typedef struct {
+ SilcAskPassphrase completion;
+ void *context;
+} *AskPassphrase;
+
+static void ask_passphrase_completion(const char *passphrase, void *context)
+{
+ AskPassphrase p = (AskPassphrase)context;
+ p->completion((unsigned char *)passphrase,
+ passphrase ? strlen(passphrase) : 0, p->context);
+ silc_free(p);
+}
+
+static void silc_ask_passphrase(SilcClient client, SilcClientConnection conn,
+ SilcAskPassphrase completion, void *context)
{
- return NULL;
+ AskPassphrase p = silc_calloc(1, sizeof(*p));
+ p->completion = completion;
+ p->context = context;
+
+ keyboard_entry_redirect((SIGNAL_FUNC)ask_passphrase_completion,
+ "Passphrase: ", ENTRY_REDIRECT_FLAG_HIDDEN, p);
}
/* Find authentication method and authentication data by hostname and
silc_say_error("Server does not support one of your proposed PKCS");
if (status == SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION)
silc_say_error("Server does not support one of your proposed "
- "hash function");
+ "hash function");
if (status == SILC_SKE_STATUS_UNKNOWN_HMAC)
silc_say_error("Server does not support one of your proposed HMAC");
if (status == SILC_SKE_STATUS_INCORRECT_SIGNATURE)
}
}
+/* Log callbacks */
+
+static void silc_log_info(char *message)
+{
+ fprintf(stderr, "%s\n", message);
+}
+
+static void silc_log_warning(char *message)
+{
+ fprintf(stderr, "%s\n", message);
+}
+
+static void silc_log_error(char *message)
+{
+ fprintf(stderr, "%s\n", message);
+}
+
/* Init SILC. Called from src/fe-text/silc.c */
void silc_core_init(void)
"Set the length of the public key pair", "VALUE" },
{ "show-key", 'S', POPT_ARG_STRING, &opt_keyfile, 0,
"Show the contents of the public key", "FILE" },
+ { "debug", 'd', POPT_ARG_NONE, &opt_debug, 0,
+ "Enable debugging", NULL },
{ NULL, '\0', 0, NULL }
};
exit(0);
}
+ silc_debug = opt_debug;
+ silc_log_set_callbacks(silc_log_info, silc_log_warning,
+ silc_log_error, NULL);
+
+ /* Do some irssi initializing */
+ settings_add_bool("server", "skip_motd", FALSE);
+ settings_add_str("server", "alternate_nick", NULL);
+ silc_init_userinfo();
+
/* Allocate SILC client */
silc_client = silc_client_alloc(&ops, NULL);
chat_protocol_register(rec);
g_free(rec);
- silc_init_userinfo();
silc_server_init();
silc_channels_init();
silc_queries_init();
- idletag = g_timeout_add(100, (GSourceFunc) my_silc_scheduler, NULL);
+ idletag = g_timeout_add(50, (GSourceFunc) my_silc_scheduler, NULL);
}
/* Deinit SILC. Called from src/fe-text/silc.c */