of how to use the SILC Client Library.
*/
+/* General definitions */
+
+/* Key agreement status types indicating the status of the protocol. */
+typedef enum {
+ SILC_KEY_AGREEMENT_OK, /* Everything is Ok */
+ SILC_KEY_AGREEMENT_ERROR, /* Unknown error occurred */
+ SILC_KEY_AGREEMENT_FAILURE, /* The protocol failed */
+ SILC_KEY_AGREEMENT_TIMEOUT, /* The protocol timeout */
+} SilcKeyAgreementStatus;
+
+/* Key agreement callback that is called after the key agreement protocol
+ has been performed. This is called also if error occurred during the
+ key agreement protocol. The `key' is the allocated key material and
+ the caller is responsible of freeing it. The `key' is NULL if error
+ has occurred. The application can freely use the `key' to whatever
+ purpose it needs. See lib/silcske/silcske.h for the definition of
+ the SilcSKEKeyMaterial structure. */
+typedef void (*SilcKeyAgreementCallback)(SilcClient client,
+ SilcClientConnection conn,
+ SilcClientEntry client_entry,
+ SilcKeyAgreementStatus status,
+ SilcSKEKeyMaterial *key,
+ void *context);
+
+/* Structure to hold the list of private message keys. The array of this
+ structure is returned by the silc_client_list_private_message_keys
+ function. */
+typedef struct {
+ SilcClientEntry client_entry; /* The remote client entry */
+ char *cipher; /* The cipher name */
+ unsigned char *key; /* The original key, If the appliation
+ provided it. This is NULL if the
+ library generated the key or if
+ the SKE key material was used. */
+ uint32 key_len; /* The key length */
+} *SilcPrivateMessageKeys;
+
/******************************************************************************
SILC Client Operations
******************************************************************************/
+/* Ask passphrase callback. This is called by the application when the
+ library calls `ask_passphrase' client operation. The callback delivers
+ the passphrase to the library. */
+typedef void (*SilcAskPassphrase)(unsigned char *passphrase,
+ uint32 passphrase_len,
+ void *context);
+
+/* Public key (or certificate) verification callback. This is called
+ by the application to indicate that the public key verification was
+ either success or failure. */
+typedef void (*SilcVerifyPublicKey)(bool success, void *context);
+
/* SILC Client Operations. These must be implemented by the application. */
typedef struct {
/* Message sent to the application by library. `conn' associates the
The `channel' is the channel. */
void (*channel_message)(SilcClient client, SilcClientConnection conn,
SilcClientEntry sender, SilcChannelEntry channel,
- char *msg);
+ SilcMessageFlags flags, char *msg);
/* Private message to the client. The `sender' is the sender of the
message. */
void (*private_message)(SilcClient client, SilcClientConnection conn,
- SilcClientEntry sender, char *msg);
+ SilcClientEntry sender, SilcMessageFlags flags,
+ char *msg);
/* Notify message to the client. The notify arguments are sent in the
same order as servers sends them. The arguments are same as received
/* Command handler. This function is called always in the command function.
If error occurs it will be called as well. `conn' is the associated
client connection. `cmd_context' is the command context that was
- originally sent to the command. `success' is FALSE if error occured
+ originally sent to the command. `success' is FALSE if error occurred
during command. `command' is the command being processed. It must be
noted that this is not reply from server. This is merely called just
after application has called the command. Just to tell application
payload data received from server and it can be ignored. It is provided
if the application would like to re-parse the received command data,
however, it must be noted that the data is parsed already by the library
- thus the payload can be ignored. `success' is FALSE if error occured.
+ thus the payload can be ignored. `success' is FALSE if error occurred.
In this case arguments are not sent to the application. The `status' is
the command reply status server returned. The `command' is the command
reply being processed. The function has variable argument list and each
and `auth_data_len'. The function returns TRUE if authentication method
is found and FALSE if not. `conn' may be NULL. */
int (*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);
-
- /* Verifies received public key. The public key has been received from
- a server. If user decides to trust the key may be saved as trusted
- server key for later use. If user does not trust the key this returns
- FALSE. If everything is Ok this returns TRUE. */
- int (*verify_server_key)(SilcClient client, SilcClientConnection conn,
- unsigned char *pk, unsigned int pk_len,
- SilcSKEPKType pk_type);
-
- /* Ask (interact, that is) a passphrase from user. Returns the passphrase
- or NULL on error. */
- unsigned char *(*ask_passphrase)(SilcClient client,
- SilcClientConnection conn);
+ uint32 *auth_data_len);
+
+ /* 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. */
+ void (*verify_public_key)(SilcClient client, SilcClientConnection conn,
+ SilcSocketType conn_type, unsigned char *pk,
+ uint32 pk_len, SilcSKEPKType pk_type,
+ SilcVerifyPublicKey completion, void *context);
+
+ /* Ask (interact, that is) a passphrase from user. The passphrase is
+ returned to the library by calling the `completion' callback with
+ the `context'. */
+ void (*ask_passphrase)(SilcClient client, SilcClientConnection conn,
+ SilcAskPassphrase completion, void *context);
/* Notifies application that failure packet was received. This is called
if there is some protocol active in the client. The `protocol' is the
reply to our key agreement packet. This returns TRUE if the user wants
the library to perform the key agreement protocol and FALSE if it is not
desired (application may start it later by calling the function
- silc_client_perform_key_agreement). */
+ silc_client_perform_key_agreement). If TRUE is returned also the
+ `completion' and `context' arguments must be set by the application. */
int (*key_agreement)(SilcClient client, SilcClientConnection conn,
SilcClientEntry client_entry, char *hostname,
- int port);
+ int port,
+ SilcKeyAgreementCallback *completion,
+ void **context);
} SilcClientOperations;
******************************************************************************/
-/* Initialization functions */
+/* Initialization functions (client.c) */
/* Allocates new client object. This has to be done before client may
work. After calling this one must call silc_client_init to initialize
/* Initializes the client. This makes all the necessary steps to make
the client ready to be run. One must call silc_client_run to run the
- client. Returns FALSE if error occured, TRUE otherwise. */
+ client. Returns FALSE if error occurred, TRUE otherwise. */
int silc_client_init(SilcClient client);
/* Runs the client. This starts the scheduler from the utility library.
void silc_client_stop(SilcClient client);
-/* Connecting functions */
+/* Connecting functions (client.c) */
/* Connects to remote server. This is the main routine used to connect
to SILC server. Returns -1 on error and the created socket otherwise.
/* Removes connection from client. Frees all memory. */
void silc_client_del_connection(SilcClient client, SilcClientConnection conn);
+/* Adds listener socket to the listener sockets table. This function is
+ used to add socket objects that are listeners to the client. This should
+ not be used to add other connection objects. */
+void silc_client_add_socket(SilcClient client, SilcSocketConnection sock);
+
+/* Deletes listener socket from the listener sockets table. */
+void silc_client_del_socket(SilcClient client, SilcSocketConnection sock);
+
/* Start SILC Key Exchange (SKE) protocol to negotiate shared secret
key material between client and server. This function can be called
directly if application is performing its own connecting and does not
int fd);
/* Closes connection to remote end. Free's all allocated data except
- for some information such as nickname etc. that are valid at all time. */
+ for some information such as nickname etc. that are valid at all time.
+ If the `sock' is NULL then the conn->sock will be used. If `sock' is
+ provided it will be checked whether the sock and `conn->sock' are the
+ same (they can be different, ie. a socket can use `conn' as its
+ connection but `conn->sock' might be actually a different connection
+ than the `sock'). */
void silc_client_close_connection(SilcClient client,
+ SilcSocketConnection sock,
SilcClientConnection conn);
-/* Message sending functions */
+/* Message sending functions (client_channel.c and client_prvmsg.c) */
/* Sends packet to the `channel'. Packet to channel is always encrypted
differently from "normal" packets. SILC header of the packet is
encrypted with the next receiver's key and the rest of the packet is
encrypted with the channel specific key. Padding and HMAC is computed
with the next receiver's key. The `data' is the channel message. If
- the `force_send' is TRUE then the packet is sent immediately. */
+ the `force_send' is TRUE then the packet is sent immediately.
+
+ If `key' is provided then that private key is used to encrypt the
+ channel message. If it is not provided, private keys has not been
+ set at all, the normal channel key is used automatically. If private
+ keys are set then the first key (the key that was added first as
+ private key) is used. */
void silc_client_send_channel_message(SilcClient client,
SilcClientConnection conn,
SilcChannelEntry channel,
+ SilcChannelPrivateKey key,
+ SilcMessageFlags flags,
unsigned char *data,
- unsigned int data_len,
+ uint32 data_len,
int force_send);
/* Sends private message to remote client. If private message key has
not been set with this client then the message will be encrypted using
normal session keys. Private messages are special packets in SILC
- network hence we need this own function for them. This is similiar
+ network hence we need this own function for them. This is similar
to silc_client_packet_send_to_channel except that we send private
message. The `data' is the private message. If the `force_send' is
TRUE the packet is sent immediately. */
void silc_client_send_private_message(SilcClient client,
SilcClientConnection conn,
SilcClientEntry client_entry,
+ SilcMessageFlags flags,
unsigned char *data,
- unsigned int data_len,
+ uint32 data_len,
int force_send);
-/* Client and Channel entry retrieval */
+/* Client and Channel entry retrieval (idlist.c) */
/* Callback function given to the silc_client_get_client function. The
found entries are allocated into the `clients' array. The array must
typedef void (*SilcGetClientCallback)(SilcClient client,
SilcClientConnection conn,
SilcClientEntry *clients,
- unsigned int clients_count,
+ uint32 clients_count,
void *context);
/* Finds client entry or entries by the `nickname' and `server'. The
SilcClientConnection conn,
char *nickname,
char *server,
- unsigned int *clients_count);
+ uint32 *clients_count);
+
+/* Gets client entries by the list of client ID's `client_id_list'. This
+ always resolves those client ID's it does not know yet from the server
+ so this function might take a while. The `client_id_list' is a list
+ of ID Payloads added one after other. JOIN command reply and USERS
+ command reply for example returns this sort of list. The `completion'
+ will be called after the entries are available. */
+void silc_client_get_clients_by_list(SilcClient client,
+ SilcClientConnection conn,
+ uint32 list_count,
+ SilcBuffer client_id_list,
+ SilcGetClientCallback completion,
+ void *context);
/* Find entry for client by the client's ID. Returns the entry or NULL
if the entry was not found. */
char *channel);
-/* Command management */
+/* Command management (command.c) */
/* Allocate Command Context. The context is defined in `command.h' file.
The context is used by the library commands and applications should use
/* Generic function to send any command. The arguments must be sent already
encoded into correct form and in correct order. */
void silc_client_send_command(SilcClient client, SilcClientConnection conn,
- SilcCommand command, unsigned short ident,
- unsigned int argc, ...);
+ SilcCommand command, uint16 ident,
+ uint32 argc, ...);
/* Pending Command callback destructor. This is called after calling the
pending callback or if error occurs while processing the pending command.
identifier `ident'. */
void silc_client_command_pending(SilcClientConnection conn,
SilcCommand reply_cmd,
- unsigned short ident,
+ uint16 ident,
SilcClientPendingDestructor destructor,
SilcCommandCb callback,
void *context);
-/* Private Message key management */
+/* Private Message key management (client_prvmsg.c) */
/* Adds private message key to the client library. The key will be used to
encrypt all private message between the client and the remote client
SilcClientEntry client_entry,
char *cipher,
unsigned char *key,
- unsigned int key_len,
+ uint32 key_len,
int generate_key);
/* Same as above but takes the key material from the SKE key material
SilcClientConnection conn,
SilcClientEntry client_entry);
-/* Structure to hold the list of private message keys. The array of this
- structure is returned by the silc_client_list_private_message_keys
- function. */
-typedef struct {
- SilcClientEntry client_entry; /* The remote client entry */
- char *cipher; /* The cipher name */
- unsigned char *key; /* The original key, If the appliation
- provided it. This is NULL if the
- library generated the key or if
- the SKE key material was used. */
- unsigned int key_len; /* The key length */
-} *SilcPrivateMessageKeys;
-
/* Returns array of set private message keys associated to the connection
`conn'. Returns allocated SilcPrivateMessageKeys array and the array
count to the `key_count' argument. The array must be freed by the caller
SilcPrivateMessageKeys
silc_client_list_private_message_keys(SilcClient client,
SilcClientConnection conn,
- unsigned int *key_count);
+ uint32 *key_count);
/* Frees the SilcPrivateMessageKeys array returned by the function
silc_client_list_private_message_keys. */
void silc_client_free_private_message_keys(SilcPrivateMessageKeys keys,
- unsigned int key_count);
+ uint32 key_count);
-/* Channel private key management */
+/* Channel private key management (client_channel.c,
+ SilcChannelPrivateKey is defined in idlist.h) */
/* Adds private key for channel. This may be set only if the channel's mode
mask includes the SILC_CHANNEL_MODE_PRIVKEY. This returns FALSE if the
encrypted using that key. All clients on the channel must also know the
key in order to decrypt the messages. However, it is possible to have
several private keys per one channel. In this case only some of the
- clients on the channel may now the one key and only some the other key.
+ clients on the channel may know the one key and only some the other key.
The private key for channel is optional. If it is not set then the
channel messages are encrypted using the channel key generated by the
SilcClientConnection conn,
SilcChannelEntry channel,
char *cipher,
+ char *hmac,
unsigned char *key,
- unsigned int key_len);
+ uint32 key_len);
/* Removes all private keys from the `channel'. The old channel key is used
after calling this to protect the channel messages. Returns FALSE on
SilcClientConnection conn,
SilcChannelEntry channel);
-/* Structure to hold one channel private key. */
-typedef struct {
- char *cipher; /* The cipher name */
- unsigned char *key; /* The key */
- unsigned int key_len; /* The key length */
-} *SilcChannelPrivateKey;
-
/* Removes and frees private key `key' from the channel `channel'. The `key'
is retrieved by calling the function silc_client_list_channel_private_keys.
The key is not used after this. If the key was last private key then the
silc_client_list_channel_private_keys(SilcClient client,
SilcClientConnection conn,
SilcChannelEntry channel,
- unsigned int key_count);
+ uint32 *key_count);
/* Frees the SilcChannelPrivateKey array. */
void silc_client_free_channel_private_keys(SilcChannelPrivateKey *keys,
- unsigned int key_count);
-
+ uint32 key_count);
-/* Key Agreement routines */
-/* Key agreement callback that is called after the key agreement protocol
- has been performed. This is called also if error occured during the
- key agreement protocol. The `key' is the allocated key material and
- the caller is responsible of freeing it. The `key' is NULL if error
- has occured. The application can freely use the `key' to whatever
- purpose it needs. See lib/silcske/silcske.h for the definition of
- the SilcSKEKeyMaterial structure. */
-typedef void (*SilcKeyAgreementCallback)(SilcClient client,
- SilcClientConnection conn,
- SilcClientEntry client_entry,
- SilcSKEKeyMaterial *key,
- void *context);
+/* Key Agreement routines (client_keyagr.c) */
/* Sends key agreement request to the remote client indicated by the
`client_entry'. If the caller provides the `hostname' and the `port'
that port for the key agreement protocol. It also sends the `hostname'
and the `port' in the key agreement packet to the remote client. This
would indicate that the remote client may initiate the key agreement
- protocol to the `hostname' on the `port'.
+ protocol to the `hostname' on the `port'. If port is zero then the
+ bound port is undefined (the operating system defines it).
If the `hostname' and `port' is not provided then empty key agreement
packet is sent to the remote client. The remote client may reply with
or decides not to reply with the key agreement packet then we cannot
perform the key agreement at all. If the key agreement protocol is
performed the `completion' callback with the `context' will be called.
- If remote side decides to ignore the request the `completion' will never
- be called and the caller is responsible of freeing the `context' memory.
- The application can do this by setting, for example, timeout. */
+ If remote side decides to ignore the request the `completion' will be
+ called after the specified timeout, `timeout_secs'.
+
+ NOTE: There can be only one active key agreement for one client entry.
+ Before setting new one, the old one must be finished (it is finished
+ after calling the completion callback) or the function
+ silc_client_abort_key_agreement must be called. */
void silc_client_send_key_agreement(SilcClient client,
SilcClientConnection conn,
SilcClientEntry client_entry,
char *hostname,
int port,
+ uint32 timeout_secs,
SilcKeyAgreementCallback completion,
void *context);
and did not return TRUE from it.
The `hostname' is the remote hostname (or IP address) and the `port'
- is the remote port. The `completion' callblack with the `context' will
+ is the remote port. The `completion' callback with the `context' will
be called after the key agreement protocol.
NOTE: If the application returns TRUE in the `key_agreement' client
SilcKeyAgreementCallback completion,
void *context);
+/* Same as above but application has created already the connection to
+ the remote host. The `sock' is the socket to the remote connection.
+ Application can use this function if it does not want the client library
+ to create the connection. */
+void silc_client_perform_key_agreement_fd(SilcClient client,
+ SilcClientConnection conn,
+ SilcClientEntry client_entry,
+ int sock,
+ char *hostname,
+ SilcKeyAgreementCallback completion,
+ void *context);
+
/* This function can be called to unbind the hostname and the port for
the key agreement protocol. However, this function has effect only
before the key agreement protocol has been performed. After it has