received in the packet. The `channel_name' is the name of the channel. */
void silc_channel_message(SilcClient client, SilcClientConnection conn,
- SilcClientEntry sender, SilcChannelEntry channel
- , char *msg)
+ SilcClientEntry sender, SilcChannelEntry channel,
+ SilcMessageFlags flags, char *msg)
{
/* Message from client */
if (conn && !strcmp(conn->current_channel->channel_name,
channel->channel_name))
- silc_print(client, "<%s> %s", sender ? sender->nickname : "[<unknown>]",
- msg);
+ if (flags & SILC_MESSAGE_FLAG_ACTION)
+ silc_print(client, "* %s %s", sender ? sender->nickname : "[<unknown>]",
+ msg);
+ else
+ silc_print(client, "<%s> %s", sender ? sender->nickname : "[<unknown>]",
+ msg);
else
- silc_print(client, "<%s:%s> %s", sender ? sender->nickname : "[<unknown>]",
- channel->channel_name, msg);
+ if (flags & SILC_MESSAGE_FLAG_ACTION)
+ silc_print(client, "* %s:%s %s", sender ? sender->nickname :
+ "[<unknown>]",
+ channel->channel_name, msg);
+ else
+ silc_print(client, "<%s:%s> %s", sender ? sender->nickname :
+ "[<unknown>]",
+ channel->channel_name, msg);
}
/* Private message to the client. The `sender' is the nickname of the
sender received in the packet. */
void silc_private_message(SilcClient client, SilcClientConnection conn,
- SilcClientEntry sender, char *msg)
+ SilcClientEntry sender, SilcMessageFlags flags,
+ char *msg)
{
silc_print(client, "*%s* %s", sender->nickname, msg);
}
break;
case SILC_NOTIFY_TYPE_INVITE:
+ (void)va_arg(vp, SilcChannelEntry);
+ tmp = va_arg(vp, char *);
client_entry = va_arg(vp, SilcClientEntry);
- channel_entry = va_arg(vp, SilcChannelEntry);
snprintf(message, sizeof(message), "%s invites you to channel %s",
- client_entry->nickname, channel_entry->channel_name);
+ client_entry->nickname, tmp);
break;
case SILC_NOTIFY_TYPE_JOIN:
case SILC_NOTIFY_TYPE_CMODE_CHANGE:
client_entry = va_arg(vp, SilcClientEntry);
- tmp = silc_client_chmode(va_arg(vp, unsigned int));
+ tmp_int = va_arg(vp, unsigned int);
+ (void)va_arg(vp, char *);
+ (void)va_arg(vp, char *);
channel_entry = va_arg(vp, SilcChannelEntry);
+
+ tmp = silc_client_chmode(tmp_int, channel_entry);
+
if (tmp)
- snprintf(message, sizeof(message), "%s changed channel mode to +%s",
+ snprintf(message, sizeof(message), "%s changed channel mode to +%s",
client_entry->nickname, tmp);
else
snprintf(message, sizeof(message), "%s removed all channel modes",
char buf[1024], *nickname, *username, *realname;
int len;
unsigned int idle, mode;
+ SilcBuffer channels;
- if (status == SILC_STATUS_ERR_NO_SUCH_NICK) {
+ 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);
nickname = va_arg(vp, char *);
username = va_arg(vp, char *);
realname = va_arg(vp, char *);
- (void)va_arg(vp, void *);
+ channels = va_arg(vp, SilcBuffer);
mode = va_arg(vp, unsigned int);
idle = va_arg(vp, unsigned int);
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));
+ unsigned int 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 (mode)
client->ops->say(client, conn, "%s is %s", nickname,
(mode & SILC_UMODE_SERVER_OPERATOR) ?
char buf[1024], *nickname, *username, *realname;
int len;
- if (status == SILC_STATUS_ERR_NO_SUCH_NICK) {
+ 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);
}
break;
+ case SILC_COMMAND_INVITE:
+ {
+ SilcChannelEntry channel;
+ char *invite_list;
+
+ if (!success)
+ return;
+
+ 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:
{
unsigned int mode;
client->ops->say(client, conn, "Topic for %s: %s",
app->screen->bottom_line->channel, topic);
- app->screen->bottom_line->channel_mode = silc_client_chmode(mode);
+ app->screen->bottom_line->channel_mode =
+ silc_client_chmode(mode, channel);
silc_screen_print_bottom_line(app->screen, 0);
/* Resolve the client information */
}
break;
+ case SILC_COMMAND_LIST:
+ {
+ char *topic, *name;
+ unsigned int usercount;
+ unsigned char buf[256], tmp[16];
+ int i, len;
+
+ if (!success)
+ return;
+
+ (void)va_arg(vp, SilcChannelEntry);
+ name = va_arg(vp, char *);
+ topic = va_arg(vp, char *);
+ usercount = va_arg(vp, unsigned int);
+
+ if (status == SILC_STATUS_LIST_START ||
+ status == SILC_STATUS_OK)
+ silc_say(client, conn,
+ " Channel Users Topic");
+
+ memset(buf, 0, sizeof(buf));
+ strncat(buf, " ", 2);
+ len = strlen(name);
+ strncat(buf, name, len > 40 ? 40 : len);
+ if (len < 40)
+ for (i = 0; i < 40 - len; i++)
+ strcat(buf, " ");
+ strcat(buf, " ");
+
+ memset(tmp, 0, sizeof(tmp));
+ if (usercount) {
+ snprintf(tmp, sizeof(tmp), "%d", usercount);
+ strcat(buf, tmp);
+ }
+ len = strlen(tmp);
+ if (len < 10)
+ for (i = 0; i < 10 - len; i++)
+ strcat(buf, " ");
+ strcat(buf, " ");
+
+ if (topic) {
+ len = strlen(topic);
+ strncat(buf, topic, len);
+ }
+
+ silc_say(client, conn, "%s", buf);
+ }
+ break;
+
case SILC_COMMAND_UMODE:
{
unsigned int mode;
silc_screen_print_bottom_line(app->screen, 0);
break;
}
+ }
break;
+
+ case SILC_COMMAND_BAN:
+ {
+ SilcChannelEntry channel;
+ char *ban_list;
+
+ if (!success)
+ return;
+
+ channel = va_arg(vp, SilcChannelEntry);
+ ban_list = va_arg(vp, char *);
+
+ if (ban_list)
+ silc_say(client, conn, "%s ban list: %s", channel->channel_name,
+ ban_list);
+ else
+ silc_say(client, conn, "%s ban list not set", channel->channel_name);
}
+ break;
+
+ default:
+ break;
}
}
}
/* Verifies received public key. If user decides to trust the key it is
- saved as trusted server key for later use. If user does not trust the
+ saved as public server key for later use. If user does not trust the
key this returns FALSE. */
-int silc_verify_server_key(SilcClient client,
+int silc_verify_public_key(SilcClient client,
SilcClientConnection conn,
+ SilcSocketType conn_type,
unsigned char *pk, unsigned int pk_len,
SilcSKEPKType pk_type)
{
char *hostname, *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 server %s key type", hostname);
+ silc_say(client, conn, "We don't support %s %s key type",
+ entity, hostname);
return FALSE;
}
memset(filename, 0, sizeof(filename));
memset(file, 0, sizeof(file));
- snprintf(file, sizeof(file) - 1, "serverkey_%s_%d.pub", hostname,
+ snprintf(file, sizeof(file) - 1, "%skey_%s_%d.pub", entity, hostname,
sock->port);
- snprintf(filename, sizeof(filename) - 1, "%s/.silc/serverkeys/%s",
- pw->pw_dir, file);
+ snprintf(filename, sizeof(filename) - 1, "%s/.silc/%skeys/%s",
+ pw->pw_dir, entity, file);
/* Check wheter this key already exists */
if (stat(filename, &st) < 0) {
fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
- silc_say(client, conn, "Received server %s public key", hostname);
- silc_say(client, conn, "Fingerprint for the server %s key is", hostname);
+ 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, "%s", fingerprint);
silc_free(fingerprint);
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 server %s public key", hostname);
- silc_say(client, conn, "Fingerprint for the server %s key is", hostname);
+ 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, "%s", fingerprint);
silc_free(fingerprint);
- silc_say(client, conn, "Could not load your local copy of the server %s key",
- hostname);
+ silc_say(client, conn, "Could not load your local copy of the %s %s key",
+ entity, hostname);
if (silc_client_ask_yes_no(client,
"Would you like to accept the key anyway (y/n)? "))
{
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 server %s public key", hostname);
- silc_say(client, conn, "Fingerprint for the server %s key is", hostname);
+ 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, "%s", fingerprint);
silc_free(fingerprint);
- silc_say(client, conn, "Your local copy of the server %s key is malformed",
- hostname);
+ silc_say(client, conn, "Your local copy of the %s %s key is malformed",
+ entity, hostname);
if (silc_client_ask_yes_no(client,
"Would you like to accept the key anyway (y/n)? "))
{
if (memcmp(encpk, pk, encpk_len)) {
fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
- silc_say(client, conn, "Received server %s public key", hostname);
- silc_say(client, conn, "Fingerprint for the server %s key is", hostname);
+ 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, "%s", fingerprint);
silc_free(fingerprint);
- silc_say(client, conn, "Server %s key does not match with your local copy",
- hostname);
+ 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, "It is also possible that some one is performing "
"man-in-the-middle attack");
return TRUE;
}
- silc_say(client, conn, "Will not accept server %s key", hostname);
+ silc_say(client, conn, "Will not accept %s %s key", entity, hostname);
return FALSE;
}
return TRUE;
}
- silc_say(client, conn, "Will not accept server %s key", hostname);
+ silc_say(client, conn, "Will not accept %s %s key", entity, hostname);
return FALSE;
}
}
}
- return FALSE;
+ *auth_meth = SILC_AUTH_NONE;
+ *auth_data = NULL;
+ *auth_data_len = 0;
+
+ return TRUE;
}
/* Notifies application that failure packet was received. This is called
SilcKeyAgreementCallback *completion,
void **context)
{
+ char host[256];
+
+ /* We will just display the info on the screen and return FALSE and user
+ will have to start the key agreement with a command. */
+
+ if (hostname) {
+ memset(host, 0, sizeof(host));
+ snprintf(host, sizeof(host) - 1, "(%s on port %d)", hostname, port);
+ }
+
+ silc_say(client, conn, "%s wants to perform key agreement %s",
+ client_entry->nickname, hostname ? host : "");
+
+ *completion = NULL;
+ *context = NULL;
return FALSE;
}
connect: silc_connect,
disconnect: silc_disconnect,
get_auth_method: silc_get_auth_method,
- verify_server_key: silc_verify_server_key,
+ verify_public_key: silc_verify_public_key,
ask_passphrase: silc_ask_passphrase,
failure: silc_failure,
key_agreement: silc_key_agreement,