X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilcclient%2Fsilcclient.h;h=898204a18f46663a571c0c38202d924fb9d3f089;hb=52e57c880aba9c5e89f59d962eb9af75670b76e0;hp=a819389688367d837a29aa6e1aae473d964a72de;hpb=c257b555225193e54d85daf541d29578b3c93882;p=silc.git diff --git a/lib/silcclient/silcclient.h b/lib/silcclient/silcclient.h index a8193896..898204a1 100644 --- a/lib/silcclient/silcclient.h +++ b/lib/silcclient/silcclient.h @@ -4,7 +4,7 @@ Author: Pekka Riikonen - Copyright (C) 2000 - 2005 Pekka Riikonen + Copyright (C) 2000 - 2007 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -22,25 +22,32 @@ * DESCRIPTION * * This interface defines the SILC Client Library API for the application. - * The client operations are defined first. These are callback functions that - * the application MUST implement since the library may call the functions - * at any time. At the end of file is the API for the application that - * it can use from the library. This is the only file that the application - * may include from the SIlC Client Library. - * - * o SILC Client Operations - * - * These functions must be implemented by the application calling the SILC - * client library. The client library can call these functions at any time. - * - * To use this structure: define a static SilcClientOperations variable, - * fill it and pass its pointer to silc_client_alloc function. - * - * o SILC Client Library API - * - * This is the API that is published by the SILC Client Library for the - * applications. These functions are implemented in the SILC Client Library. - * Application may freely call these functions from the library. + * The Client Library is a full featured SILC client without user interface. + * A simple interface called SILC Client Operations (SilcClientOperations) + * is provided for applications to implmeent the necessary functions to use + * the client library. The silcclient.h header file includes client library + * API, such as command handling and message sending. The silcclient_entry.h + * header file includes entry handling, such as channel and user entry + * handling. + * + * Practically all functions in the Client Library API accepts SilcClient + * and SilcClientConnection as their first two argument. The first argument + * is the actual SilcClient context and the second is the SilcClientConnection + * context of the connection in question. Application may create and handle + * multiple connections in one SilcClient. Connections can be created to + * servers and other clients. + * + * The Client Library support multiple threads and is threads safe if used + * correctly. Messages can be sent from multiple threads without any + * locking. Messages however are always received only in one thread unless + * message waiting (see silc_client_private_message_wait as an example) is + * used. The threads can be turned on and off by giving a parameter to the + * SilcClient. When turned on, each new connection to remote host is always + * executed in an own thread. All tasks related to that connection are then + * executed in that thread. This means that client operation callbacks for + * that connections may be called from threads and application will need to + * employ concurrency control if the callbacks need to access shared data + * in the application. Messages are also received in that thread. * ***/ @@ -52,237 +59,184 @@ extern "C" { #endif #include "client.h" +#include "silcclient_entry.h" /* General definitions */ -/****s* silcclient/SilcClientAPI/SilcClient +/****d* silcclient/SilcClientAPI/SilcClientConnectionStatus * * NAME * - * typedef struct SilcClientStruct { ... } *SilcClient + * typedef enum { ... } SilcClientConnectionStatus * * DESCRIPTION * - * This is the actual SILC Client structure which represents one - * SILC Client. It is allocated with the silc_client_alloc function - * and given as argument to all SILC Client Library functions. It - * is initialized with silc_client_init function, and freed with - * silc_client_free function. + * This type is returned to the `connect' client operation to indicate + * the status of the created connection. It can indicate if it was + * successful or whether an error occurred. * * SOURCE */ -struct SilcClientStruct { - /* - * The following fields are set by application. Strings MUST be UTF-8 - * encoded strings. - */ - char *nickname; /* Nickname, MAY be set by application */ - char *username; /* Username, MUST be set by application */ - char *hostname; /* hostname, MUST be set by application */ - char *realname; /* Real name, MUST be set be application */ - - SilcPublicKey public_key; /* Public key of user, set by application */ - SilcPrivateKey private_key; /* Private key of user, set by application */ - SilcPKCS pkcs; /* PKCS allocated by application */ - - /* - * The following fields are set by the library - */ - - /* Scheduler, set by library. Application may use this pointer. */ - SilcSchedule schedule; - - /* Random Number Generator. Application should use this as its primary - random number generator. */ - SilcRng rng; - - /* Application specific user data pointer. Client library does not - touch this. This the context sent as argument to silc_client_alloc. - Application can use it freely. */ - void *application; - - /* Generic hash context for application usage */ - SilcHash md5hash; - SilcHash sha1hash; - - /* Internal data for client library. Application cannot access this - data at all. */ - SilcClientInternal internal; -}; +typedef enum { + SILC_CLIENT_CONN_SUCCESS, /* Successfully connected */ + SILC_CLIENT_CONN_SUCCESS_RESUME, /* Successfully connected and + resumed old detached session */ + SILC_CLIENT_CONN_DISCONNECTED, /* Remote host disconnected */ + SILC_CLIENT_CONN_ERROR, /* Error occurred during connecting */ + SILC_CLIENT_CONN_ERROR_KE, /* Key Exchange failed */ + SILC_CLIENT_CONN_ERROR_AUTH, /* Authentication failed */ + SILC_CLIENT_CONN_ERROR_RESUME, /* Resuming failed */ + SILC_CLIENT_CONN_ERROR_TIMEOUT, /* Timeout during connecting */ +} SilcClientConnectionStatus; /***/ -/****s* silcclient/SilcClientAPI/SilcClientConnection +/****f* silcclient/SilcClientAPI/SilcClientRunning * - * NAME + * SYNOPSIS * - * typedef struct SilcClientConnectionStruct { ... } - * *SilcClientConnection + * typedef void (*SilcClientRunning)(SilcClient client, void *context); * * DESCRIPTION * - * This structure represents a connection. When connection is created - * to server this is context is returned to the application in the - * "connected" client operation. It includes all the important - * data for the session, such as nickname, local and remote IDs, and - * other information. All strings in the structure are UTF-8 encoded. + * The callback given as argument to silc_client_init function. Once + * this is called the client library is running and application may + * start using the Client library API. * - * SOURCE - */ -struct SilcClientConnectionStruct { - /* - * Local data - */ - char *nickname; /* Current nickname */ - SilcClientEntry local_entry; /* Own Client Entry */ - SilcClientID *local_id; /* Current Client ID */ - unsigned char *local_id_data; /* Current Client ID decoded */ - SilcUInt32 local_id_data_len; - - /* - * Remote data - */ - char *remote_host; /* Remote host name, UTF-8 encoded */ - int remote_port; /* Remote port */ - SilcServerID *remote_id; /* Remote Server ID */ - unsigned char *remote_id_data; /* Remote Server ID decoded */ - SilcUInt32 remote_id_data_len; - - /* - * Common data - */ - - /* Current command identifier for a command that was sent last. - Application may get the value from this variable to find out the - command identifier for last command. */ - SilcUInt16 cmd_ident; - - /* User data context. Library does not touch this. Application may - freely set and use this pointer for its needs. */ - void *context; - - /* Pointer back to the SilcClient. Application may use this. */ - SilcClient client; - - /* Current channel. Application may use and set this pointer if needed. */ - SilcChannelEntry current_channel; + ***/ +typedef void (*SilcClientRunning)(SilcClient client, void *context); - /* Socket connection object for this connection. Application may - use this if needed. The sock->user_data is back pointer to this - structure. */ - SilcSocketConnection sock; +/****f* silcclient/SilcClientAPI/SilcClientStopped + * + * SYNOPSIS + * + * typedef void (*SilcClientStopped)(SilcClient client, void *context); + * + * DESCRIPTION + * + * The callback given as argument to silc_client_stop. Once this is + * called the client library has stopped and can be freed by calling + * silc_client_free. Note that this won't be called if there are + * active connections in the client. Connections must first be closed + * by calling silc_client_close_connection or by sending QUIT command to + * the server connection. + * + ***/ +typedef void (*SilcClientStopped)(SilcClient client, void *context); - /* Internal data for client library. Application cannot access this - data at all. */ - SilcClientConnectionInternal internal; -}; -/***/ +/****f* silcclient/SilcClientAPI/SilcClientConnectCallback + * + * SYNOPSIS + * + * void (*SilcClientConnectCallback)(SilcClient client, + * SilcClientConnection conn, + * SilcClientConnectionStatus status, + * SilcStatus error, + * const char *message, + * void *context); + * + * DESCRIPTION + * + * Connect callbak given as argument to silc_client_connect_to_server, + * silc_client_connect_to_client and silc_client_key_exchange functions. + * It is called to indicate the status of the connection, indicated + * by the `status'. It is called after the connection has been + * established to the remote host and when connection is disconnected + * by the remote host. The `context' is the context given as argument + * to the connecting function. If the `status' is an error the `error' + * may indicate more detailed error. If `error' is SILC_STATUS_OK no + * detailed error message is available. + * + * When the `status' is SILC_CLIENT_CONN_DISCONNECTED the `error' will + * indicate the reason for disconnection. If the `message' is non-NULL + * it delivers error or disconnection message. + * + * The `conn' is the connection to the remote host. In case error + * occurred the `conn' may be NULL, however, in some cases a valid `conn' + * is returned even in error. If `conn' is non-NULL the receiver is + * responsible of closing the connection with silc_client_close_connection + * function, except when SILC_CLINET_CONN_DISCONNECTED or some error + * was received. In these cases the library will close the connection. + * + ***/ +typedef void (*SilcClientConnectCallback)(SilcClient client, + SilcClientConnection conn, + SilcClientConnectionStatus status, + SilcStatus error, + const char *message, + void *context); -/****s* silcclient/SilcClientAPI/SilcClientEntry +/****s* silcclient/SilcClientAPI/SilcClient * * NAME * - * typedef struct SilcClientEntryStruct { ... } *SilcClientEntry + * typedef struct SilcClientStruct { ... } *SilcClient * * DESCRIPTION * - * This structure represents a client or a user in the SILC network. - * The local user has this structure also and it can be accessed from - * SilcClientConnection structure. All other users in the SILC network - * that are accessed using the Client Library routines will have their - * own SilcClientEntry structure. For example, when finding users by - * their nickname the Client Library returns this structure back to - * the application. All strings in the structure are UTF-8 encoded. + * This is the actual SILC Client structure which represents one + * SILC Client. It is allocated with the silc_client_alloc function + * and given as argument to all SILC Client Library functions. It + * is initialized with silc_client_init function, and freed with + * silc_client_free function. + * + * This context represents the client. Each connection to remote server + * is represented by SilcClientConnection context. * * SOURCE */ -struct SilcClientEntryStruct { - /* General information */ - char *nickname; /* nickname */ - char *username; /* username */ - char *hostname; /* hostname */ - char *server; /* SILC server name */ - char *realname; /* Realname (userinfo) */ - - /* Mode, ID and other information */ - SilcUInt32 mode; /* User mode in SILC, see SilcUserMode */ - SilcClientID *id; /* The Client ID */ - SilcDList attrs; /* Requested Attributes (maybe NULL) */ - unsigned char *fingerprint; /* Fingerprint of client's public key */ - SilcUInt32 fingerprint_len; /* Length of the fingerprint */ - SilcPublicKey public_key; /* User's public key, may be NULL */ - - /* Private message keys */ - SilcCipher send_key; /* Private message key for sending */ - SilcCipher receive_key; /* Private message key for receiving */ - SilcHmac hmac_send; /* Private mesage key HMAC for sending */ - SilcHmac hmac_receive; /* Private mesage key HMAC for receiving */ - unsigned char *key; /* Set only if application provided the - key material. NULL if the library - generated the key. */ - SilcUInt32 key_len; /* Key length */ - SilcClientKeyAgreement ke; /* Current key agreement context or NULL */ - - /* SilcClientEntry status information */ - SilcEntryStatus status; /* Status mask */ - SilcHashTable channels; /* All channels client has joined */ - SilcUInt16 resolve_cmd_ident; /* Command identifier when resolving */ - unsigned int generated : 1; /* TRUE if library generated `key' */ - unsigned int valid : 1; /* FALSE if this entry is not valid */ - unsigned int prv_resp : 1; /* TRUE if private message key indicator - has been received (responder). */ - - /* Application specific data. Application may set here whatever it wants. */ - void *context; +struct SilcClientStruct { + char *username; /* Username */ + char *hostname; /* hostname */ + char *realname; /* Real name */ + SilcSchedule schedule; /* Client scheduler */ + SilcRng rng; /* Random number generator */ + void *application; /* Application specific context, set with + silc_client_alloc. */ + + /* Internal data for client library. Application cannot access this. */ + SilcClientInternal internal; }; /***/ -/****s* silcclient/SilcClientAPI/SilcChannelEntry +/****s* silcclient/SilcClientAPI/SilcClientConnection * * NAME * - * typedef struct SilcChannelEntryStruct { ... } *SilcChannelEntry + * typedef struct SilcClientConnectionStruct { ... } + * *SilcClientConnection * * DESCRIPTION * - * This structure represents a channel in the SILC network. All - * channels that the client are aware of or have joined in will be - * represented as SilcChannelEntry. The structure includes information - * about the channel. All strings in the structure are UTF-8 encoded. + * This structure represents a connection. It is allocated and freed by + * the library. It is returned to application in SilcClientConnectCallback. + * It includes all the important data for the session such as local + * client entry (which includes current nickname), local and remote IDs, + * and other information. All strings in the structure are UTF-8 encoded. * * SOURCE */ -struct SilcChannelEntryStruct { - /* General information */ - char *channel_name; /* Channel name */ - SilcChannelID *id; /* Channel ID */ - SilcUInt32 mode; /* Channel mode, ChannelModes. */ - char *topic; /* Current topic, may be NULL */ - SilcPublicKey founder_key; /* Founder key, may be NULL */ - SilcUInt32 user_limit; /* User limit on channel */ - - /* All clients that has joined this channel. The key to the table is the - SilcClientEntry and the context is SilcChannelUser context. */ - SilcHashTable user_list; - - /* Channel keys */ - SilcCipher channel_key; /* The channel key */ - unsigned char *key; /* Raw key data */ - SilcUInt32 key_len; /* Raw key data length */ - unsigned char iv[SILC_CIPHER_MAX_IV_SIZE]; /* Current IV */ - SilcHmac hmac; /* Current HMAC */ - - /* Channel private keys */ - SilcDList private_keys; /* List of private keys or NULL */ - SilcChannelPrivateKey curr_key; /* Current private key */ - - /* SilcChannelEntry status information */ - SilcDList old_channel_keys; - SilcDList old_hmacs; - SilcUInt16 resolve_cmd_ident; /* Command identifier when - resolving this entry */ +struct SilcClientConnectionStruct { + SilcClientEntry local_entry; /* Our own Client Entry */ + SilcClientID *local_id; /* Our current Client ID */ + + char *remote_host; /* Remote host name */ + int remote_port; /* Remote port */ + SilcID remote_id; /* Remote ID */ + + SilcChannelEntry current_channel; /* Current joined channel */ + SilcPublicKey public_key; /* Public key used in this connection */ + SilcPrivateKey private_key; /* Private key */ + SilcPacketStream stream; /* Connection to remote host */ + SilcConnectionType type; /* Connection type */ + SilcClientConnectCallback callback; /* Connection callback */ + void *callback_context; /* Connection context */ + SilcClient client; /* Pointer back to SilcClient */ /* Application specific data. Application may set here whatever it wants. */ void *context; + + /* Internal data for client library. Application cannot access this. */ + SilcClientConnectionInternal internal; }; /***/ @@ -310,32 +264,36 @@ struct SilcChannelUserStruct { }; /***/ -/****s* silcclient/SilcClientAPI/SilcServerEntry +/****s* silcclient/SilcClientAPI/SilcClientStats * * NAME * - * typedef struct SilcServerEntryStruct { ... } *SilcServerEntry + * typedef struct { ... } SilcClientStats; * * DESCRIPTION * - * This structure represents a server in the SILC network. All servers - * that the client is aware of and have for example resolved with - * SILC_COMMAND_INFO command have their on SilcServerEntry structure. - * All strings in the structure are UTF-8 encoded. + * This structure holds SILC network statistics returned by the + * SILC_COMMAND_STATS command reply to the application. * * SOURCE */ -struct SilcServerEntryStruct { - /* General information */ - char *server_name; /* Server name */ - char *server_info; /* Server info */ - SilcServerID *server_id; /* Server ID */ - SilcUInt16 resolve_cmd_ident; /* Command identifier when - resolving this entry */ - - /* Application specific data. Application may set here whatever it wants. */ - void *context; -}; +typedef struct SilcClientStatsStruct { + SilcUInt32 starttime; /* SILC server start time */ + SilcUInt32 uptime; /* SILC server uptime*/ + SilcUInt32 my_clients; /* Number of clients in the server */ + SilcUInt32 my_channels; /* Number of channel in the server */ + SilcUInt32 my_server_ops; /* Number of server operators in the server */ + SilcUInt32 my_router_ops; /* Number of router operators in the router */ + SilcUInt32 cell_clients; /* Number of clients in the cell */ + SilcUInt32 cell_channels; /* Number of channels in the cell */ + SilcUInt32 cell_servers; /* Number of server in the cell */ + SilcUInt32 clients; /* All clients in SILC network */ + SilcUInt32 channels; /* All channels in SILC network */ + SilcUInt32 servers; /* All servers in SILC network */ + SilcUInt32 routers; /* All routers in SILC network */ + SilcUInt32 server_ops; /* All server operators in SILC network */ + SilcUInt32 router_ops; /* All router operators in SILC network */ +} SilcClientStats; /***/ /****d* silcclient/SilcClientAPI/SilcKeyAgreementStatus @@ -360,6 +318,7 @@ typedef enum { SILC_KEY_AGREEMENT_ABORTED, /* The protocol aborted */ SILC_KEY_AGREEMENT_ALREADY_STARTED, /* Already started */ SILC_KEY_AGREEMENT_SELF_DENIED, /* Negotiationg with itself denied */ + SILC_KEY_AGREEMENT_NO_MEMORY, /* System out of memory */ } SilcKeyAgreementStatus; /***/ @@ -389,7 +348,7 @@ typedef void (*SilcKeyAgreementCallback)(SilcClient client, SilcClientConnection conn, SilcClientEntry client_entry, SilcKeyAgreementStatus status, - SilcSKEKeyMaterial *key, + SilcSKEKeyMaterial key, void *context); /****s* silcclient/SilcClientAPI/SilcPrivateMessageKeys @@ -400,18 +359,17 @@ typedef void (*SilcKeyAgreementCallback)(SilcClient client, * * DESCRIPTION * - * Structure to hold the list of private message keys. The array of this - * structure is returned by the silc_client_list_private_message_keys + * Structure to hold the list of private message keys. The list of these + * structures is returned by the silc_client_list_private_message_keys * function. * * SOURCE */ -typedef struct { +typedef struct SilcPrivateMessageKeysStruct { 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 + provided it. This is NULL if the SKE key material was used. */ SilcUInt32 key_len; /* The key length */ } *SilcPrivateMessageKeys; @@ -433,10 +391,9 @@ typedef struct { */ struct SilcChannelPrivateKeyStruct { char *name; /* Application given name */ - SilcCipher cipher; /* The cipher and key */ + SilcCipher send_key; /* The cipher and key */ + SilcCipher receive_key; /* The cipher and key */ SilcHmac hmac; /* The HMAC and hmac key */ - unsigned char *key; /* The key data */ - SilcUInt32 key_len; /* The key length */ }; /***/ @@ -444,7 +401,7 @@ struct SilcChannelPrivateKeyStruct { * * SYNOPSIS * - * typedef void (*SilcAskPassphrase)(unsigned char *passphrase, + * typedef void (*SilcAskPassphrase)(const unsigned char *passphrase, * SilcUInt32 passphrase_len, * void *context); * @@ -457,7 +414,7 @@ struct SilcChannelPrivateKeyStruct { * encoded, and if it is not then library will attempt to encode it. * ***/ -typedef void (*SilcAskPassphrase)(unsigned char *passphrase, +typedef void (*SilcAskPassphrase)(const unsigned char *passphrase, SilcUInt32 passphrase_len, void *context); @@ -465,7 +422,7 @@ typedef void (*SilcAskPassphrase)(unsigned char *passphrase, * * SYNOPSIS * - * typedef void (*SilcVerifyPublicKey)(bool success, void *context); + * typedef void (*SilcVerifyPublicKey)(SilcBool success, void *context); * * DESCRIPTION * @@ -474,33 +431,37 @@ typedef void (*SilcAskPassphrase)(unsigned char *passphrase, * either success or failure. * ***/ -typedef void (*SilcVerifyPublicKey)(bool success, void *context); +typedef void (*SilcVerifyPublicKey)(SilcBool success, void *context); /****f* silcclient/SilcClientAPI/SilcGetAuthMeth * * SYNOPSIS * - * typedef void (*SilcGetAuthMeth)(bool success, - * SilcProtocolAuthMeth auth_meth, - * const unsigned char *auth_data, - * SilcUInt32 auth_data_len, void *context); + * typedef void (*SilcGetAuthMeth)(SilcAuthMethod auth_meth, + * const void *auth, SilcUInt32 auth_len, + * void *context); * * DESCRIPTION * - * Authentication method resolving callback. This is called by the - * application to return the resolved authentication method. The client + * Authentication data resolving callback. This is called by the + * application to return the resolved authentication data. The client * library has called the get_auth_method client operation and given - * this function pointer as argument. The `success' will indicate whether - * the authentication method could be resolved. The `auth_meth' is the - * resolved authentication method. The `auth_data' and the `auth_data_len' + * this function pointer as argument. The `auth_meth' is the selected + * authentication method. The `auth_data' and the `auth_data_len' * are the resolved authentication data. The `context' is the libary's * context sent to the get_auth_method client operation. * + * If the `auth_method' is SILC_AUTH_PASSWORD then `auth' and `auth_len' + * is the passphrase and its length. If it is SILC_AUTH_PUBLIC_KEY the + * `auth' must be NULL. The library will use the private key given as + * argument to silc_client_connect_to_server, silc_client_connect_to_client + * or silc_client_key_exchange. If it is SILC_AUTH_NONE, both `auth' and + * `auth_len' are ignored. + * ***/ -typedef void (*SilcGetAuthMeth)(bool success, - SilcProtocolAuthMeth auth_meth, - const unsigned char *auth_data, - SilcUInt32 auth_data_len, void *context); +typedef void (*SilcGetAuthMeth)(SilcAuthMethod auth_meth, + const void *auth, SilcUInt32 auth_len, + void *context); /****d* silcclient/SilcClientAPI/SilcClientMessageType * @@ -519,37 +480,11 @@ typedef enum { SILC_CLIENT_MESSAGE_INFO, /* Informational */ SILC_CLIENT_MESSAGE_WARNING, /* Warning */ SILC_CLIENT_MESSAGE_ERROR, /* Error */ + SILC_CLIENT_MESSAGE_COMMAND_ERROR, /* Error during command */ SILC_CLIENT_MESSAGE_AUDIT, /* Auditable */ } SilcClientMessageType; /***/ -/****d* silcclient/SilcClientAPI/SilcClientConnectionStatus - * - * NAME - * - * typedef enum { ... } SilcClientConnectionStatus - * - * DESCRIPTION - * - * This type is returned to the `connect' client operation to indicate - * the status of the created connection. It can indicate if it was - * successful or whether an error occurred. - * - * SOURCE - */ -typedef enum { - SILC_CLIENT_CONN_SUCCESS, /* Successfully connected */ - SILC_CLIENT_CONN_SUCCESS_RESUME, /* Successfully connected and - resumed old detached session */ - SILC_CLIENT_CONN_ERROR, /* Unknown error occurred during - connecting */ - SILC_CLIENT_CONN_ERROR_KE, /* Key Exchange failed */ - SILC_CLIENT_CONN_ERROR_AUTH, /* Authentication failed */ - SILC_CLIENT_CONN_ERROR_RESUME, /* Resuming failed */ - SILC_CLIENT_CONN_ERROR_TIMEOUT, /* Timeout during connecting */ -} SilcClientConnectionStatus; -/***/ - /****s* silcclient/SilcClientAPI/SilcClientOperations * * NAME @@ -565,7 +500,7 @@ typedef enum { * * SOURCE */ -typedef struct { +typedef struct SilcClientOperationsStruct { /* Message sent to the application by library. `conn' associates the message to a specific connection. `conn', however, may be NULL. The `type' indicates the type of the message sent by the library. @@ -579,7 +514,8 @@ typedef struct { The `channel' is the channel. The `message' is the message. Note that `message' maybe NULL. The `flags' indicates message flags and it is used to determine how the message can be interpreted - (like it may tell the message is multimedia message). */ + (like it may tell the message is multimedia message). The `payload' + may be used to retrieve all the details of the message. */ void (*channel_message)(SilcClient client, SilcClientConnection conn, SilcClientEntry sender, SilcChannelEntry channel, SilcMessagePayload payload, @@ -591,127 +527,92 @@ typedef struct { message. The message is `message'and maybe NULL. The `flags' indicates message flags and it is used to determine how the message can be interpreted (like it may tell the message is multimedia - message). */ + message). The `payload' may be used to retrieve all the details of + the message. */ void (*private_message)(SilcClient client, SilcClientConnection conn, SilcClientEntry sender, SilcMessagePayload payload, - SilcMessageFlags flags, - const unsigned char *message, + SilcMessageFlags flags, const unsigned char *message, SilcUInt32 message_len); - /* Notify message to the client. The notify arguments are sent in the - same order as servers sends them. The arguments are same as received - from the server except for ID's. If ID is received application receives - the corresponding entry to the ID. For example, if Client ID is received - application receives SilcClientEntry. Also, if the notify type is - for channel the channel entry is sent to application (even if server - does not send it because client library gets the channel entry from - the Channel ID in the packet's header). */ + /* Notify message to the client. The arguments are notify `type' specific. + See separate documentation in the Toolkit Reference Manual for the notify + arguments. */ void (*notify)(SilcClient client, SilcClientConnection conn, SilcNotifyType type, ...); - /* 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 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 - that the command really was processed. */ + /* Command handler. This function is called always after application has + called a command. It will be called to indicate that the command + was processed. It will also be called if error occurs while processing + the command. The `success' indicates whether the command was sent + or if error occurred. The `status' indicates the actual error. + The `argc' and `argv' are the command line arguments sent to the + command by application. Note that, this is not reply to the command + from server, this is merely and indication to application that the + command was processed. */ void (*command)(SilcClient client, SilcClientConnection conn, - SilcClientCommandContext cmd_context, bool success, - SilcCommand command, SilcStatus status); - - /* Command reply handler. This function is called always in the command reply - function. If error occurs it will be called as well. Normal scenario - is that it will be called after the received command data has been parsed - and processed. The function is used to pass the received command data to - the application. - - `conn' is the associated client connection. `cmd_payload' is the command - 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 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 - command defines the number and type of arguments it passes to the - application (on error they are not sent). - - The arguments are sent in the same order as servers sends them. The - arguments are same as received from the server except for ID's. If - ID is received application receives the corresponding entry to the - ID. For example, if Client ID is receives application receives - SilcClientEntry. */ + SilcBool success, SilcCommand command, SilcStatus status, + SilcUInt32 argc, unsigned char **argv); + + /* Command reply handler. Delivers a reply to command that was sent + earlier. The `conn' is the associated client connection. The `command' + indicates the command reply type. If the `status' other than + SILC_STATUS_OK an error occurred. In this case the `error' will indicate + the error. It is possible to receive list of command replies and list + of errors. In this case the `status' will indicate it is an list entry + (the `status' is SILC_STATUS_LIST_START, SILC_STATUS_LIST_ITEM and/or + SILC_STATUS_LIST_END). + + The arguments received in `ap' are command specific. See a separate + documentation in the Toolkit Reference Manual for the command reply + arguments. */ void (*command_reply)(SilcClient client, SilcClientConnection conn, - SilcCommandPayload cmd_payload, bool success, - SilcCommand command, SilcStatus status, ...); - - /* Called to indicate that connection was either successfully established - or connecting failed. This is also the first time application receives - the SilcClientConnection object which it should save somewhere. - The `status' indicated whether the connection were successful. If it - is error value the application must always call the function - silc_client_close_connection. */ - void (*connected)(SilcClient client, SilcClientConnection conn, - SilcClientConnectionStatus status); - - /* Called to indicate that connection was disconnected to the server. - The `status' may tell the reason of the disconnection, and if the - `message' is non-NULL it may include the disconnection message - received from server. Application must not call the - silc_client_close_connection in this callback. The 'conn' is also - invalid after this function returns back to library. */ - void (*disconnected)(SilcClient client, SilcClientConnection conn, - SilcStatus status, const char *message); + SilcCommand command, SilcStatus status, + SilcStatus error, va_list ap); /* Find authentication method and authentication data by hostname and - port. The hostname may be IP address as well. When the authentication - method has been resolved the `completion' callback with the found - authentication method and authentication data is called. The `conn' - may be NULL. */ + port. The hostname may be IP address as well. The `auth_method' is + the authentication method the remote connection requires. It is + however possible that remote accepts also some other authentication + method. Application should use the method that may have been + configured for this connection. If none has been configured it should + use the required `auth_method'. If the `auth_method' is + SILC_AUTH_NONE, server does not require any authentication or the + required authentication method is not known. The `completion' + callback must be called to deliver the chosen authentication method + and data. The `conn' may be NULL. */ void (*get_auth_method)(SilcClient client, SilcClientConnection conn, char *hostname, SilcUInt16 port, + SilcAuthMethod auth_method, SilcGetAuthMeth completion, void *context); - /* Verifies received public key. The `conn_type' indicates which entity - (server, client etc.) has sent the public key. If user decides to trust - the application may save the key as trusted public key for later - use. The `completion' must be called after the public key has been - verified. */ + /* Called to verify received public key. The `conn_type' indicates which + entity (server or client) has sent the public key. If user decides to + trust the key the application may save the key 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, - SilcUInt32 pk_len, SilcSKEPKType pk_type, + SilcConnectionType conn_type, + SilcPublicKey public_key, SilcVerifyPublicKey completion, void *context); - /* Ask (interact, that is) a passphrase from user. The passphrase is + /* Ask from end user a passphrase or a password. The passphrase is returned to the library by calling the `completion' callback with the `context'. The returned passphrase SHOULD be in UTF-8 encoded, if not then the library will attempt to encode. */ 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 - protocol context. The `failure' is opaque pointer to the failure - indication. Note, that the `failure' is protocol dependant and - application must explicitly cast it to correct type. Usually `failure' - is 32 bit failure type (see protocol specs for all protocol failure - types). */ - void (*failure)(SilcClient client, SilcClientConnection conn, - SilcProtocol protocol, void *failure); - - /* Asks whether the user would like to perform the key agreement protocol. - This is called after we have received an key agreement packet or an - 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). If TRUE is returned also the - `completion' and `context' arguments must be set by the application. */ - bool (*key_agreement)(SilcClient client, SilcClientConnection conn, - SilcClientEntry client_entry, const char *hostname, - SilcUInt16 port, SilcKeyAgreementCallback *completion, - void **context); + /* Called to indicate that incoming key agreement request has been + received. If the application wants to perform key agreement it may + call silc_client_perform_key_agreement to initiate key agreement or + silc_client_send_key_agreement to provide connection point to the + remote client in case the `hostname' is NULL. If key agreement is + not desired this request can be ignored. The `protocol' is either + value 0 for TCP or value 1 for UDP. */ + void (*key_agreement)(SilcClient client, SilcClientConnection conn, + SilcClientEntry client_entry, + const char *hostname, SilcUInt16 protocol, + SilcUInt16 port); /* Notifies application that file transfer protocol session is being requested by the remote client indicated by the `client_entry' from @@ -722,48 +623,9 @@ typedef struct { void (*ftp)(SilcClient client, SilcClientConnection conn, SilcClientEntry client_entry, SilcUInt32 session_id, const char *hostname, SilcUInt16 port); - - /* Delivers SILC session detachment data indicated by `detach_data' to the - application. If application has issued SILC_COMMAND_DETACH command - the client session in the SILC network is not quit. The client remains - in the network but is detached. The detachment data may be used later - to resume the session in the SILC Network. The appliation is - responsible of saving the `detach_data', to for example in a file. - - The detachment data can be given as argument to the functions - silc_client_connect_to_server, or silc_client_add_connection when - creating connection to remote server, inside SilcClientConnectionParams - structure. If it is provided the client library will attempt to resume - the session in the network. After the connection is created - successfully, the application is responsible of setting the user - interface for user into the same state it was before detaching (showing - same channels, channel modes, etc). It can do this by fetching the - information (like joined channels) from the client library. */ - void (*detach)(SilcClient client, SilcClientConnection conn, - const unsigned char *detach_data, - SilcUInt32 detach_data_len); } SilcClientOperations; /***/ -/****f* silcclient/SilcClientAPI/SilcNicknameFormatParse - * - * SYNOPSIS - * - * typedef void (*SilcNicknameFormatParse)(const char *nickname, - * char **ret_nickname); - * - * DESCRIPTION - * - * A callback function provided by the application for the library in - * SilcClientParams structure. This function parses the formatted - * nickname string `nickname' and returns the true nickname to the - * `ret_nickname' pointer. The library can call this function at - * any time. - * - ***/ -typedef void (*SilcNicknameFormatParse)(const char *nickname, - char **ret_nickname); - /****s* silcclient/SilcClientAPI/SilcClientParams * * NAME @@ -778,52 +640,41 @@ typedef void (*SilcNicknameFormatParse)(const char *nickname, * * SOURCE */ -typedef struct { - /* Number of maximum tasks the client library's scheduler can handle. - If set to zero, the default value will be used (200). For WIN32 - systems this should be set to 64 as it is the hard limit dictated - by the WIN32. */ - int task_max; - - /* Rekey timeout in seconds. The client will perform rekey in this - time interval. If set to zero, the default value will be used. */ - unsigned int rekey_secs; - - /* Connection authentication method request timeout. If server does not - reply back the current authentication method when we've requested it - in this time interval we'll assume the reply will not come at all. - If set to zero, the default value (2 seconds) will be used. */ - unsigned int connauth_request_secs; +typedef struct SilcClientParamsStruct { + /* If this boolean is set to TRUE then the client library will use + threads. Any of the callback functions in the SilcClientOperations + and other callbacks may be called at any time in a thread. The + application may need to employ appropriate concurrency control + in the callbacks to protect application specific data. */ + SilcBool threads; /* Nickname format string. This can be used to order the client library to save the nicknames in the library in a certain format. Since nicknames are not unique in SILC it is possible to have multiple same nicknames. Using this format string it is possible to order the library - to separate the multiple same nicknames from each other. The format - types are defined below and they can appear in any order in the format - string. If this is NULL then default format is used which is the - default nickname without anything else. The string MUST be NULL - terminated. + to separate the multiple same nicknames from each other. If this is + empty then default format is used which is the default nickname + without anything else. The string MUST be NULL terminated. Following format types are available: %n nickname - the real nickname returned by the server (mandatory) + %a number - ascending number in case there are several + same nicknames (fe. nick#2 and nick#3) %h hostname - the stripped hostname of the client %H full hostname - the full hostname of the client - %s server name - the server name the client is connected - %S full server - the full server name the client is connected - %a number - ascending number in case there are several - same nicknames (fe. nick@host and nick@host2) - Example format strings: "%n@%h%a" (fe. nick@host, nick@host2) - "%a!%n@%s" (fe. nick@server, 2!nick@server) - "%n@%H" (fe. nick@host.domain.com) - - By default this format is employed to the nicknames by the libary - only when there appears multiple same nicknames. If the library has - only one nickname cached the nickname is saved as is and without the - defined format. If you want always to save the nickname in the defined - format set the boolean field `nickname_force_format' to value TRUE. + Example format strings: "%n#%a" (fe. nick#2, nick#3) + "%n#%h%a" (fe. nick#host, nick#host2) + "%a!%n#%h" (fe. nick#host, 2!nick#host) + + Note that there must always be some separator characters around '%n' + format. It is not possible to put format characters before or after + '%n' without separators (such ash '#'). Also note that the separator + character should be a character that cannot be part of normal nickname. + Note that, using '@' as a separator is not recommended as the nickname + string may contain it to separate a server name from the nickname (eg. + nickname@silcnet.org). */ char nickname_format[32]; @@ -833,30 +684,27 @@ typedef struct { is employed only if the library will receive a nickname that is already saved in the cache. It is recommended to leave this to FALSE value. */ - bool nickname_force_format; - - /* A callback function provided by the application for the library to - parse the nickname from the formatted nickname string. Even though - the libary formats the nicknames the application knows generally the - format better so this function should be provided for the library - if the application sets the `nickname_format' field. The library - will call this to get the true nickname from the provided formatted - nickname string whenever it needs the true nickname. */ - SilcNicknameFormatParse nickname_parse; - - /* If this is set to TRUE then the client will ignore all incoming - Requested Attributes queries and does not reply anything back. This - usually leads into situation where server does not anymore send - the queries after seeing that client does not reply anything back. - If your application does not support Requested Attributes or you do - not want to use them set this to TRUE. See SilcAttribute and - silc_client_attribute_add for more information on attributes. */ - bool ignore_requested_attributes; + SilcBool nickname_force_format; + + /* If this is set to TRUE then all nickname strings returned by the library + and stored by the library are in the format of 'nickname@server', eg. + nickname@silcnet.org. If this is FALSE then the server name of the + nickname is available only from the SilcClientEntry structure. When this + is TRUE the server name is still parsed to SilcClientEntry. */ + SilcBool full_nicknames; + + /* If this is set to TRUE then all channel name strings returned by the + library and stored by the library are in the format of 'channel@server', + eg. silc@silcnet.org. If this is FALSE then the server name of the + channel is available only from the SilcChannelEntry structure. When this + is TRUE the server name is still parsed to SilcChannelEntry. Note that, + not all SILC server versions return such channel name strings. */ + SilcBool full_channel_names; /* If this is set to TRUE, the silcclient library will not register and deregister the cipher, pkcs, hash and hmac algorithms. The application itself will need to handle that. */ - bool dont_register_crypto_library; + SilcBool dont_register_crypto_library; } SilcClientParams; /***/ @@ -908,7 +756,9 @@ void silc_client_free(SilcClient client); * * SYNOPSIS * - * bool silc_client_init(SilcClient client); + * SilcBool silc_client_init(SilcClient client, const char *username, + * const char *hostname, const char *realname, + * SilcClientRunning running, void *context); * * DESCRIPTION * @@ -916,8 +766,20 @@ void silc_client_free(SilcClient client); * the client ready to be run. One must call silc_client_run to run the * client. Returns FALSE if error occurred, TRUE otherwise. * + * The `username' and `hostname' strings must be given and they must be + * UTF-8 encoded. The `username' is the client's username in the + * operating system, `hostname' is the client's host name and the + * `realname' is the user's real name. + * + * The `running' callback with `context' is called after the client is + * running after silc_client_run or silc_client_run_one has been called. + * Application may start using the Client library API after that. Setting + * the callback is optional, but highly recommended. + * ***/ -bool silc_client_init(SilcClient client); +SilcBool silc_client_init(SilcClient client, const char *username, + const char *hostname, const char *realname, + SilcClientRunning running, void *context); /****f* silcclient/SilcClientAPI/silc_client_run * @@ -927,8 +789,8 @@ bool silc_client_init(SilcClient client); * * DESCRIPTION * - * Runs the client. This starts the scheduler from the utility library. - * When this functions returns the execution of the appliation is over. + * Runs the client. This starts the scheduler from the utility library. + * When this functions returns the execution of the application is over. * The client must be initialized before calling this. * ***/ @@ -957,764 +819,473 @@ void silc_client_run_one(SilcClient client); * * SYNOPSIS * - * void silc_client_stop(SilcClient client); - * - * DESCRIPTION - * - * Stops the client. This is called to stop the client and thus to stop - * the program. The client context must be freed with the silc_client_free - * function. - * - ***/ -void silc_client_stop(SilcClient client); - - -/* Connecting functions (client.c) */ - -/****s* silcclient/SilcClientAPI/SilcClientConnectionParams - * - * NAME - * - * typedef struct { ... } SilcClientConnectionParams; - * - * DESCRIPTION - * - * Client connection parameters. This can be filled by the application - * and given as argument to silc_client_connect_to_server or to - * silc_client_add_connection. - * - * SOURCE - */ -typedef struct { - /* The SILC session detachment data that was returned by `detach' client - operation when the application detached from the network. Application - is responsible of saving the data and giving it as argument here - for resuming the session in the SILC network. - - If this is provided here the client library will attempt to resume - the session in the network. After the connection is created - successfully, the application is responsible of setting the user - interface for user into the same state it was before detaching (showing - same channels, channel modes, etc). It can do this by fetching the - information (like joined channels) from the client library. */ - unsigned char *detach_data; - SilcUInt32 detach_data_len; - -} SilcClientConnectionParams; -/***/ - -/****f* silcclient/SilcClientAPI/silc_client_connect_to_server - * - * SYNOPSIS - * - * int silc_client_connect_to_server(SilcClient client, - * SilcClientConnectionParams *params, - * int port, char *host, void *context); - * - * DESCRIPTION - * - * Connects to remote server. This is the main routine used to connect - * to SILC server. Returns -1 on error and the created socket otherwise. - * The `context' is user context that is saved into the SilcClientConnection - * that is created after the connection is created. Note that application - * may handle the connecting process outside the library. If this is the - * case then this function is not used at all. When the connecting is - * done the `connect' client operation is called, and the `context' is - * accessible with conn->context, conn being SilcClientConnection. - * If the `params' is provided they are used by the routine. - * - ***/ -int silc_client_connect_to_server(SilcClient client, - SilcClientConnectionParams *params, - int port, char *host, void *context); - -/****f* silcclient/SilcClientAPI/silc_client_add_connection - * - * SYNOPSIS - * - * - * SilcClientConnection - * silc_client_add_connection(SilcClient client, - * SilcClientConnectionParams *params, - * char *hostname, int port, void *context); - * - * DESCRIPTION - * - * Allocates and adds new connection to the client. This adds the allocated - * connection to the connection table and returns a pointer to it. A client - * can have multiple connections to multiple servers. Every connection must - * be added to the client using this function. User data `context' may - * be sent as argument. If the `params' is provided they are used by - * the routine. - * - * NOTES - * - * This function is normally used only if the application performed - * the connecting outside the library, and did not called the - * silc_client_connect_to_server function at all. The library - * however may use this internally. - * - ***/ -SilcClientConnection -silc_client_add_connection(SilcClient client, - SilcClientConnectionParams *params, - char *hostname, int port, void *context); - -/****f* silcclient/SilcClientAPI/silc_client_del_connection - * - * SYNOPSIS - * - * void silc_client_del_connection(SilcClient client, - * SilcClientConnection conn); - * - * DESCRIPTION - * - * Removes connection from client. Frees all memory. The library - * call this function automatically for all connection contexts. - * The application however may free the connection contexts it has - * allocated. - * - ***/ -void silc_client_del_connection(SilcClient client, SilcClientConnection conn); - -/****f* silcclient/SilcClientAPI/silc_client_add_socket - * - * SYNOPSIS - * - * void silc_client_add_socket(SilcClient client, - * SilcSocketConnection sock); - * - * DESCRIPTION - * - * 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); - -/****f* silcclient/SilcClientAPI/silc_client_del_socket - * - * SYNOPSIS - * - * void silc_client_del_socket(SilcClient client, - * SilcSocketConnection sock); - * - * DESCRIPTION - * - * Deletes listener socket from the listener sockets table. If the - * application has added a socket with silc_client_add_socket it must - * also free it using this function. - * - ***/ -void silc_client_del_socket(SilcClient client, SilcSocketConnection sock); - -/****f* silcclient/SilcClientAPI/silc_client_start_key_exchange - * - * SYNOPSIS - * - * void silc_client_start_key_exchange(SilcClient client, - * SilcClientConnection conn, - * int fd); - * - * DESCRIPTION - * - * 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 - * use the connecting provided by this library. This function is normally - * used only if the application performed the connecting outside the - * library. The library however may use this internally. After the - * key exchange is performed the `connect' client operation is called. - * - * NOTES - * - * The silc_client_add_connection must be called before calling this - * function to create the SilcClientConnection context for this - * connection. - * - ***/ -void silc_client_start_key_exchange(SilcClient client, - SilcClientConnection conn, - int fd); - -/****f* silcclient/SilcClientAPI/silc_client_close_connection - * - * SYNOPSIS - * - * void silc_client_close_connection(SilcClient client, - * SilcClientConnection conn); - * - * DESCRIPTION - * - * Closes connection to remote end. Free's all allocated data except - * for some information such as nickname etc. that are valid at all time. - * Usually application does not need to directly call this, except - * when explicitly closing the connection, or if an error occurs - * during connection to server (see 'connect' client operation for - * more information). - * - ***/ -void silc_client_close_connection(SilcClient client, - SilcClientConnection conn); - - -/* Message sending functions (client_channel.c and client_prvmsg.c) */ - -/****f* silcclient/SilcClientAPI/silc_client_send_channel_message - * - * SYNOPSIS - * - * bool silc_client_send_channel_message(SilcClient client, - * SilcClientConnection conn, - * SilcChannelEntry channel, - * SilcChannelPrivateKey key, - * SilcMessageFlags flags, - * unsigned char *data, - * SilcUInt32 data_len, - * bool_force_send); - * - * DESCRIPTION - * - * 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. - * - * 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. - * - * If the `flags' includes SILC_MESSAGE_FLAG_SIGNED the message will be - * digitally signed with the SILC key pair. - * - * Returns TRUE if the message was sent, and FALSE if error occurred or - * the sending is not allowed due to channel modes (like sending is - * blocked). - * - ***/ -bool silc_client_send_channel_message(SilcClient client, - SilcClientConnection conn, - SilcChannelEntry channel, - SilcChannelPrivateKey key, - SilcMessageFlags flags, - unsigned char *data, - SilcUInt32 data_len, - bool force_send); - -/****f* silcclient/SilcClientAPI/silc_client_send_private_message - * - * SYNOPSIS - * - * bool silc_client_send_private_message(SilcClient client, - * SilcClientConnection conn, - * SilcClientEntry client_entry, - * SilcMessageFlags flags, - * unsigned char *data, - * SilcUInt32 data_len, - * bool force_send); - * - * DESCRIPTION - * - * 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 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. - * - * If the `flags' includes SILC_MESSAGE_FLAG_SIGNED the message will be - * digitally signed with the SILC key pair. - * - * Returns TRUE if the message was sent, and FALSE if error occurred. - * - ***/ -bool silc_client_send_private_message(SilcClient client, - SilcClientConnection conn, - SilcClientEntry client_entry, - SilcMessageFlags flags, - unsigned char *data, - SilcUInt32 data_len, - bool force_send); - - -/* Client and Channel entry retrieval (idlist.c) */ - -/****f* silcclient/SilcClientAPI/SilcGetClientCallback - * - * SYNOPSIS - * - * typedef void (*SilcGetClientCallback)(SilcClient client, - * SilcClientConnection conn, - * SilcClientEntry *clients, - * SilcUInt32 clients_count, - * void *context); - * - * DESCRIPTION - * - * Callback function given to the silc_client_get_client function. The - * found entries are allocated into the `clients' array. The array must - * not be freed by the receiver, the library will free it later. If the - * `clients' is NULL, no such clients exist in the SILC Network. - * - ***/ -typedef void (*SilcGetClientCallback)(SilcClient client, - SilcClientConnection conn, - SilcClientEntry *clients, - SilcUInt32 clients_count, - void *context); - -/****f* silcclient/SilcClientAPI/silc_client_get_clients - * - * SYNOPSIS - * - * void silc_client_get_clients(SilcClient client, - * SilcClientConnection conn, - * const char *nickname, - * const char *server, - * SilcGetClientCallback completion, - * void *context); - * - * DESCRIPTION - * - * Finds client entry or entries by the `nickname' and `server'. The - * completion callback will be called when the client entries has been - * found. After the server returns the client information it is cached - * and can be accesses locally at a later time. The resolving is done - * with IDENTIFY command. The `server' may be NULL. - * - * NOTES - * - * NOTE: This function is always asynchronous and resolves the client - * information from the server. Thus, if you already know the client - * information then use the silc_client_get_client_by_id function to - * get the client entry since this function may be very slow and should - * be used only to initially get the client entries. - * - * Since this routine resolves with IDENTIFY command only the relevant - * information (user's nickname and username) is resolved. For example, - * user's real name, channel list and others are not resolved. Caller - * can/must resolve those separately if they are needed (for example, - * with silc_client_get_client_by_id_resolve). - * - ***/ -void silc_client_get_clients(SilcClient client, - SilcClientConnection conn, - const char *nickname, - const char *server, - SilcGetClientCallback completion, - void *context); - -/****f* silcclient/SilcClientAPI/silc_client_get_clients_whois - * - * SYNOPSIS - * - * void silc_client_get_clients_whois(SilcClient client, - * SilcClientConnection conn, - * const char *nickname, - * const char *server, - * SilcBuffer attributes, - * SilcGetClientCallback completion, - * void *context); - * - * DESCRIPTION - * - * Finds client entry or entries by the `nickname' and `server'. The - * completion callback will be called when the client entries has been - * found. After the server returns the client information it is cached - * and can be accesses locally at a later time. The resolving is done - * with WHOIS command. The `server' may be NULL. - * - * If the `attributes' is non-NULL then the buffer includes Requested - * Attributes which can be used to fetch very detailed information - * about the user. If it is NULL then only normal WHOIS query is - * made (for more information about attributes see SilcAttribute). - * Caller may create the `attributes' with silc_client_attributes_request - * function. - * - * NOTES - * - * The resolving is done with WHOIS command. For this reason this - * command may take a long time because it resolves detailed user - * information. - * - ***/ -void silc_client_get_clients_whois(SilcClient client, - SilcClientConnection conn, - const char *nickname, - const char *server, - SilcBuffer attributes, - SilcGetClientCallback completion, - void *context); - -/****f* silcclient/SilcClientAPI/silc_client_get_clients_local - * - * SYNOPSIS - * - * SilcClientEntry *silc_client_get_clients_local(SilcClient client, - * SilcClientConnection conn, - * const char *nickname, - * const char *format, - * SilcUInt32 *clients_count); - * - * DESCRIPTION - * - * Same as silc_client_get_clients function but does not resolve anything - * from the server. This checks local cache and returns all matching - * clients from the local cache. If none was found this returns NULL. - * The `nickname' is the real nickname of the client, and the `format' - * is the formatted nickname to find exact match from multiple found - * entries. The format must be same as given in the SilcClientParams - * structure to the client library. If the `format' is NULL all found - * clients by `nickname' are returned. The caller must return the - * returned array. - * - ***/ -SilcClientEntry *silc_client_get_clients_local(SilcClient client, - SilcClientConnection conn, - const char *nickname, - const char *format, - SilcUInt32 *clients_count); - -/****f* silcclient/SilcClientAPI/silc_client_get_clients_by_channel - * - * SYNOPSIS - * - * void silc_client_get_clients_by_channel(SilcClient client, - * SilcClientConnection conn, - * SilcChannelEntry channel, - * SilcGetClientCallback completion, - * void *context); - * - * DESCRIPTION - * - * Gets client entries by the channel indicated by `channel'. Thus, - * it resovles the users currently on that channel. If all users are - * already resolved this returns the users from the channel. If the - * users are resolved only partially this resolves the complete user - * information. If no users are resolved on this channel at all, this - * calls USERS command to resolve all users on the channel. The `completion' - * will be called after the entries are available. When server returns - * the client information it will be cached and can be accessed locally - * at a later time. - * - * This function can be used for example in SILC_COMMAND_JOIN command - * reply handling in application to resolve users on that channel. It - * also can be used after calling silc_client_get_channel_resolve to - * resolve users on that channel. - * - * NOTES - * - * The resolving is done with WHOIS command. For this reason this - * command may take a long time because it resolves detailed user - * information. - * - ***/ -void silc_client_get_clients_by_channel(SilcClient client, - SilcClientConnection conn, - SilcChannelEntry channel, - SilcGetClientCallback completion, - void *context); - -/****f* silcclient/SilcClientAPI/silc_client_get_clients_by_list - * - * SYNOPSIS - * - * void silc_client_get_clients_by_list(SilcClient client, - * SilcClientConnection conn, - * SilcUInt32 list_count, - * SilcBuffer client_id_list, - * SilcGetClientCallback completion, - * void *context); - * - * DESCRIPTION - * - * 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. When server returns - * the client information it will be cached and can be accessed locally - * at a later time. - * - * NOTES - * - * The resolving is done with IDENTIFY command. This means that only - * the relevant information of user (it's nickname and username) is - * resolved. For example, user's real name, channel lists and others - * are not resolved. Caller can/must resolve those separately if they - * are needed (for example, with silc_client_get_client_by_id_resolve). - * - ***/ -void silc_client_get_clients_by_list(SilcClient client, - SilcClientConnection conn, - SilcUInt32 list_count, - SilcBuffer client_id_list, - SilcGetClientCallback completion, - void *context); - -/****f* silcclient/SilcClientAPI/silc_client_get_client_by_id - * - * SYNOPSIS - * - * SilcClientEntry silc_client_get_client_by_id(SilcClient client, - * SilcClientConnection conn, - * SilcClientID *client_id); - * - * DESCRIPTION - * - * Find entry for client by the client's ID. Returns the entry or NULL - * if the entry was not found. This checks the local cache and does - * not resolve anything from server. - * - ***/ -SilcClientEntry silc_client_get_client_by_id(SilcClient client, - SilcClientConnection conn, - SilcClientID *client_id); - -/****f* silcclient/SilcClientAPI/silc_client_get_client_by_id_resolve - * - * SYNOPSIS - * - * void - * silc_client_get_client_by_id_resolve(SilcClient client, - * SilcClientConnection conn, - * SilcClientID *client_id, - * SilcBuffer attributes, - * SilcGetClientCallback completion, - * void *context); + * void silc_client_stop(SilcClient client, SilcClientStopped stopped, + * void *context); * * DESCRIPTION * - * Same as silc_client_get_client_by_id but will always resolve the - * information from the server. Use this only if you know that you - * do not have the entry and the only thing you know about the client - * is its ID. When server returns the client information it will be - * cache and can be accessed locally at a later time. The resolving - * is done by sending WHOIS command. + * Stops the client. This is called to stop the client and thus to stop + * the program. The client context must be freed with the silc_client_free + * function. All connections that exist in this client must be closed + * before calling this function. Connections can be closed by calling + * silc_client_close_connection. * - * If the `attributes' is non-NULL then the buffer includes Requested - * Attributes which can be used to fetch very detailed information - * about the user. If it is NULL then only normal WHOIS query is - * made (for more information about attributes see SilcAttribute). - * Caller may create the `attributes' with silc_client_attributes_request - * function. + * The `stopped' will be called once the client and all connections have + * finished. The client may be freed after that. Note that the `stopped' + * won't be called before all connections have finished. Setting the + * callback is optional. * ***/ -void silc_client_get_client_by_id_resolve(SilcClient client, - SilcClientConnection conn, - SilcClientID *client_id, - SilcBuffer attributes, - SilcGetClientCallback completion, - void *context); +void silc_client_stop(SilcClient client, SilcClientStopped stopped, + void *context); + +/* Connecting functions */ -/****f* silcclient/SilcClientAPI/silc_client_del_client +/****s* silcclient/SilcClientAPI/SilcClientConnectionParams * - * SYNOPSIS + * NAME * - * bool silc_client_del_client(SilcClient client, SilcClientConnection conn, - * SilcClientEntry client_entry) + * typedef struct { ... } SilcClientConnectionParams; * * DESCRIPTION * - * Removes client from local cache by the client entry indicated by - * the `client_entry'. Returns TRUE if the deletion were successful. + * Client connection parameters. This can be filled by the application + * and given as argument to silc_client_connect_to_server, + * silc_client_connect_to_client, silc_client_key_exchange or + * silc_client_send_key_agreement. * - ***/ -bool silc_client_del_client(SilcClient client, SilcClientConnection conn, - SilcClientEntry client_entry); + * SOURCE + */ +typedef struct SilcClientConnectionParamsStruct { + /* If this is provided the user's nickname in the network will be the + string given here. If it is given, it must be UTF-8 encoded. If this + string is not given, the user's username by default is used as nickname. + The nickname may later be changed by using NICK command. The maximum + length for the nickname string is 128 bytes. */ + char *nickname; + + /* If this key repository pointer is non-NULL then public key received in + the key exchange protocol will be verified from this repository. If + this is not provided then the `verify_public_key' client operation will + be called back to application. If the boolean `verify_notfound' is set + to TRUE then the `verify_public_key' client operation will be called + in case the public key is not found in `repository'. Only public keys + added with at least SILC_SKR_USAGE_KEY_AGREEMENT in the repository will + be checked, other keys will be ignored. */ + SilcSKR repository; + SilcBool verify_notfound; + + /* Authentication data. Application may set here the authentication data + and authentication method to be used in connecting. If `auth_set' + boolean is TRUE then authentication data is provided by application. + If the authentication method is public key authentication then the key + pair given as argument when connecting will be used and `auth' field + is NULL. If it is passphrase authentication, it can be provided in + `auth' and `auth_len' fields. If `auth_set' is FALSE + the `get_auth_method' client operation will be called to get the + authentication method and data from application. */ + SilcBool auth_set; + SilcAuthMethod auth_method; + void *auth; + SilcUInt32 auth_len; + + /* If this boolean is set to TRUE then the connection will use UDP instead + of TCP. If UDP is set then also the next `local_ip' and `local_port' + must be set. */ + SilcBool udp; + + /* The `local_ip' specifies the local IP address used with the connection. + It must be non-NULL if `udp' boolean is TRUE. If the `local_port' is + non-zero it will be used as local port with UDP connection. The remote + host will also send packets to the specified address and port. If the + `bind_ip' is non-NULL a listener is bound to that address instead of + `local_ip'. */ + char *local_ip; + char *bind_ip; + int local_port; + + /* If this boolean is set to TRUE then the key exchange is done with + perfect forward secrecy. */ + SilcBool pfs; + + /* If this boolean is set to TRUE then connection authentication protocol + is not performed during connecting. Only key exchange protocol is + performed. This usually must be set to TRUE when connecting to another + client, but must be FALSE with server connections. */ + SilcBool no_authentication; + + /* The SILC session detachment data that was returned in the `command_reply' + client operation for SILC_COMMAND_DETACH command. If this is provided + here the client library will attempt to resume the session in the network. + After the connection is created and the session has been resumed the + client will receive SILC_COMMAND_NICK command_reply for the client's + nickname in the network and SILC_COMMAND_JOIN command reply for all the + channels that the client has joined in the network. It may also receive + SILC_COMMAND_UMODE command reply to set user's mode on the network. */ + unsigned char *detach_data; + SilcUInt32 detach_data_len; -/****f* silcclient/SilcClientAPI/SilcGetChannelCallback + /* Connection timeout. If non-zero, the connection will timeout unless + the SILC connection is completed in the specified amount of time. */ + SilcUInt32 timeout_secs; + + /* Rekey timeout in seconds. The client will perform rekey in this + time interval. If set to zero, the default value will be used + (3600 seconds, 1 hour). */ + SilcUInt32 rekey_secs; + + /* If this is set to TRUE then the client will ignore all incoming + Requested Attributes queries and does not reply anything back. This + usually leads into situation where server does not anymore send + the queries after seeing that client does not reply anything back. + If your application does not support Requested Attributes or you do + not want to use them set this to TRUE. See SilcAttribute and + silc_client_attribute_add for more information on attributes. */ + SilcBool ignore_requested_attributes; + +} SilcClientConnectionParams; +/***/ + +/****f* silcclient/SilcClientAPI/silc_client_connect_to_server * * SYNOPSIS * - * typedef void (*SilcGetChannelCallback)(SilcClient client, - * SilcClientConnection conn, - * SilcChannelEntry *channels, - * SilcUInt32 channels_count, - * void *context); + * SilcAsyncOperation + * silc_client_connect_to_server(SilcClient client, + * SilcClientConnectionParams *params, + * SilcPublicKey public_key, + * SilcPrivateKey private_key, + * char *remote_host, int port, + * SilcClientConnectCallback callback, + * void *context); * * DESCRIPTION * - * Callback function given to the silc_client_get_channel_* functions. - * The found entries are allocated into the `channels' array. The array - * must not be freed by the receiver, the library will free it later. - * If the `channel' is NULL, no such channel exist in the SILC Network. + * Connects to remote server `remote_host' at port `port'. This function + * can be used to create connection to remote SILC server and start + * SILC session in the SILC network. The `params' may be provided + * to provide various connection parameters. The `public_key' and the + * `private_key' is your identity used in this connection. When + * authentication method is based on digital signatures, this key pair + * will be used. The `callback' with `context' will be called after the + * connection has been created. It will also be called later when remote + * host disconnects. + * + * If application wishes to create the network connection itself, use + * the silc_client_key_exchange after creating the connection to start + * key exchange and authentication with the server. + * + * Returns SilcAsyncOperation which can be used to cancel the connecting, + * or NULL on error. Note that the returned pointer becomes invalid + * after the `callback' is called. * ***/ -typedef void (*SilcGetChannelCallback)(SilcClient client, - SilcClientConnection conn, - SilcChannelEntry *channels, - SilcUInt32 channels_count, - void *context); +SilcAsyncOperation +silc_client_connect_to_server(SilcClient client, + SilcClientConnectionParams *params, + SilcPublicKey public_key, + SilcPrivateKey private_key, + char *remote_host, int port, + SilcClientConnectCallback callback, + void *context); -/****f* silcclient/SilcClientAPI/silc_client_get_channel +/****f* silcclient/SilcClientAPI/silc_client_connect_to_client * * SYNOPSIS * - * SilcChannelEntry silc_client_get_channel(SilcClient client, - * SilcClientConnection conn, - * char *channel_name); + * SilcAsyncOperation + * silc_client_connect_to_client(SilcClient client, + * SilcClientConnectionParams *params, + * SilcPublicKey public_key, + * SilcPrivateKey private_key, + * char *remote_host, int port, + * SilcClientConnectCallback callback, + * void *context); * * DESCRIPTION * - * Finds entry for channel by the channel name. Returns the entry or NULL - * if the entry was not found. It is found only if the client is joined - * to the channel. Use silc_client_get_channel_resolve or - * silc_client_get_channel_by_id_resolve to resolve channel that client - * is not joined. + * Connects to remote client `remote_host' at port `port'. This function + * can be used to create peer-to-peer connection to another SILC client, + * for example, for direct conferencing, or file transfer or for other + * purposes. The `params' may be provided to provide various connection + * parameters. The `public_key' and the `private_key' is your identity + * used in this connection. The `callback' with `context' will be called + * after the connection has been created. It will also be called later + * when remote host disconnects. + * + * If application wishes to create the network connection itself, use + * the silc_client_key_exchange after creating the connection to start + * key exchange with the client. + * + * Returns SilcAsyncOperation which can be used to cancel the connecting, + * or NULL on error. Note that the returned pointer becomes invalid + * after the `callback' is called. * ***/ -SilcChannelEntry silc_client_get_channel(SilcClient client, - SilcClientConnection conn, - char *channel_name); +SilcAsyncOperation +silc_client_connect_to_client(SilcClient client, + SilcClientConnectionParams *params, + SilcPublicKey public_key, + SilcPrivateKey private_key, + char *remote_host, int port, + SilcClientConnectCallback callback, + void *context); -/****f* silcclient/SilcClientAPI/silc_client_get_channel_resolve +/****f* silcclient/SilcClientAPI/silc_client_key_exchange * * SYNOPSIS * - * void silc_client_get_channel_resolve(SilcClient client, - * SilcClientConnection conn, - * char *channel_name, - * SilcGetChannelCallback completion, - * void *context); + * SilcAsyncOperation + * silc_client_key_exchange(SilcClient client, + * SilcClientConnectionParams *params, + * SilcPublicKey public_key, + * SilcPrivateKey private_key, + * SilcStream stream, + * SilcConnectionType conn_type, + * SilcClientConnectCallback callback, + * void *context); * * DESCRIPTION * - * Resolves entry for channel by the channel name from the server. - * The resolving is done with IDENTIFY command. Note that users on - * the channel are not resolved at the same time. Use for example - * silc_client_get_clients_by_channel to resolve all users on a channel. + * Starts key exchange protocol and authentication protocol in the + * connection indicated by `stream'. This function can be be used to + * start SILC session with remote host (usually server) when the caller + * has itself created the connection, instead of calling the function + * silc_client_connect_to_server or silc_client_connect_to_client. If + * one of those functions was used this function must not be called as + * in that case the key exchange is performed automatically. * - ***/ -void silc_client_get_channel_resolve(SilcClient client, - SilcClientConnection conn, - char *channel_name, - SilcGetChannelCallback completion, - void *context); + * Use this function only if you have created the connection by yourself. + * After creating the connection the socket must be wrapped into a + * socket stream. See silcsocketstream.h for more information. Note that + * the `stream' must have valid remote IP address (and optionally also + * hostname) and port set. + * + * The `params' may be provided to provide various connection parameters. + * The `public_key' and the `private_key' is your identity used in this + * session. The `callback' with `context' will be called after the session + * has been set up. It will also be called later when remote host + * disconnects. The `conn_type' is the type of session this is going to + * be. If the remote is SILC server it is SILC_CONN_SERVER or if it is + * SILC client it is SILC_CONN_CLIENT. + * + * Returns SilcAsyncOperation which can be used to cancel the connecting, + * or NULL on error. Note that the returned pointer becomes invalid + * after the `callback' is called. + * + * EXAMPLE + * + * int sock; + * + * // Create remote connection stream. Resolve hostname and IP also. + * sock = create_connection(remote_host, port); + * silc_socket_tcp_stream_create(sock, TRUE, FALSE, schedule, + * stream_create_cb, app); + * + * // Stream callback delivers our new SilcStream context + * void stream_create_cb(SilcSocketStreamStatus status, SilcStream stream, + * void *context) + * { + * ... + * if (status != SILC_SOCKET_OK) + * error(status); + * + * // Start key exchange + * silc_client_key_exchange(client, NULL, public_key, private_key, + * stream, SILC_CONN_SERVER, connection_cb, app); + * ... + * } + * + ***/ +SilcAsyncOperation +silc_client_key_exchange(SilcClient client, + SilcClientConnectionParams *params, + SilcPublicKey public_key, + SilcPrivateKey private_key, + SilcStream stream, + SilcConnectionType conn_type, + SilcClientConnectCallback callback, + void *context); -/****f* silcclient/SilcClientAPI/silc_client_get_channel_by_id +/****f* silcclient/SilcClientAPI/silc_client_close_connection * * SYNOPSIS * - * SilcChannelEntry - * silc_client_get_channel_by_id(SilcClient client, - * SilcClientConnection conn, - * SilcChannelID *channel_id); + * void silc_client_close_connection(SilcClient client, + * SilcClientConnection conn); * * DESCRIPTION * - * Finds channel entry by the channel ID. Returns the entry or NULL - * if the entry was not found. This checks the local cache and does - * not resolve anything from server. + * Closes the remote connection `conn'. The `conn' will become invalid + * after this call. Usually this function is called only when explicitly + * closing connection for example in case of error, or when the remote + * connection was created by the application or when the remote is client + * connection. Server connections are usually closed by sending QUIT + * command to the server. However, this call may also be used. * ***/ -SilcChannelEntry silc_client_get_channel_by_id(SilcClient client, - SilcClientConnection conn, - SilcChannelID *channel_id); +void silc_client_close_connection(SilcClient client, + SilcClientConnection conn); + +/* Message sending functions */ -/****f* silcclient/SilcClientAPI/silc_client_get_channel_by_id_resolve +/****f* silcclient/SilcClientAPI/silc_client_send_channel_message * * SYNOPSIS * - * void - * silc_client_get_channel_by_id_resolve(SilcClient client, - * SilcClientConnection conn, - * SilcChannelID *channel_id, - * SilcGetClientCallback completion, - * void *context); + * SilcBool silc_client_send_channel_message(SilcClient client, + * SilcClientConnection conn, + * SilcChannelEntry channel, + * SilcChannelPrivateKey key, + * SilcMessageFlags flags, + * SilcHash hash, + * unsigned char *data, + * SilcUInt32 data_len); * * DESCRIPTION * - * Resolves the channel information (its name mainly) from the server - * by the `channel_id'. Use this only if you know that you do not have - * the entry cached locally. The resolving is done with IDENTIFY command. + * Sends encrypted message to the `channel'. The plaintext message is + * the `data' of `data_len' bytes in length. + * + * If `key' is provided then that private channel message key is used to + * encrypt the message. If it is not provided and the `channel' does not + * have SILC_CHANNEL_MODE_PRIVKEY set, the curent channel key is used + * instead. If the mode is set but `key' is NULL the key that was added + * first as private channel message key will be used. * - * Note that users on the channel are not resolved at the same time. - * Use for example silc_client_get_clients_by_channel to resolve all - * users on a channel. + * If the `flags' includes SILC_MESSAGE_FLAG_SIGNED the message will be + * digitally signed with the SILC key pair associated with the `conn'. + * In this case the `hash' pointer must be provided as well. + * + * Returns TRUE if the message was sent, and FALSE if error occurred or + * the sending is not allowed due to channel modes (like sending is + * blocked). This function is thread safe and private messages can be + * sent from multiple threads. * ***/ -void silc_client_get_channel_by_id_resolve(SilcClient client, - SilcClientConnection conn, - SilcChannelID *channel_id, - SilcGetChannelCallback completion, - void *context); +SilcBool silc_client_send_channel_message(SilcClient client, + SilcClientConnection conn, + SilcChannelEntry channel, + SilcChannelPrivateKey key, + SilcMessageFlags flags, + SilcHash hash, + unsigned char *data, + SilcUInt32 data_len); -/****f* silcclient/SilcClientAPI/silc_client_del_channel +/****f* silcclient/SilcClientAPI/silc_client_send_private_message * * SYNOPSIS * - * bool silc_client_del_channel(SilcClient client, - * SilcClientConnection conn, - * SilcChannelEntry channel) + * SilcBool silc_client_send_private_message(SilcClient client, + * SilcClientConnection conn, + * SilcClientEntry client_entry, + * SilcMessageFlags flags, + * SilcHash hash, + * unsigned char *data, + * SilcUInt32 data_len); * * DESCRIPTION * - * Removes channel from local cache by the channel entry indicated by - * the `channel'. Returns TRUE if the deletion were successful. + * Sends private message to remote client. If private message key has + * not been set with this client then the message will be encrypted using + * the session keys used in `conn' connection. If the `flags' includes + * SILC_MESSAGE_FLAG_SIGNED the message will be digitally signed with the + * SILC key pair associated with `conn'. In this case the caller must also + * provide the `hash' pointer. + * + * Returns TRUE if the message was sent, and FALSE if error occurred. + * This function is thread safe and private messages can be sent from + * multiple threads. * ***/ -bool silc_client_del_channel(SilcClient client, SilcClientConnection conn, - SilcChannelEntry channel); +SilcBool silc_client_send_private_message(SilcClient client, + SilcClientConnection conn, + SilcClientEntry client_entry, + SilcMessageFlags flags, + SilcHash hash, + unsigned char *data, + SilcUInt32 data_len); -/****f* silcclient/SilcClientAPI/silc_client_get_server +/****f* silcclient/SilcClientAPI/silc_client_private_message_wait_init * * SYNOPSIS * - * SilcServerEntry silc_client_get_server(SilcClient client, - * SilcClientConnection conn, - * char *server_name) + * SilcBool + * silc_client_private_message_wait_init(SilcClient client, + * SilcClientConnection conn, + * SilcClientEntry client_entry); * * DESCRIPTION * - * Finds entry for server by the server name. Returns the entry or NULL - * if the entry was not found. + * Initializes private message waiting functionality for the client + * indicated by `client_entry'. Once this is called private message + * from remote connection indicated by `conn' for `client_entry' may + * be waiter for, for example in a thread. The function + * silc_client_private_message_wait is used to block the current thread + * until a private message is received from a specified client entry. + * Return FALSE in case an internal error occurred. * ***/ -SilcServerEntry silc_client_get_server(SilcClient client, - SilcClientConnection conn, - char *server_name); +SilcBool silc_client_private_message_wait_init(SilcClient client, + SilcClientConnection conn, + SilcClientEntry client_entry); -/****f* silcclient/SilcClientAPI/silc_client_get_server_by_id +/****f* silcclient/SilcClientAPI/silc_client_private_message_wait_uninit * * SYNOPSIS * - * SilcServerEntry silc_client_get_server_by_id(SilcClient client, - * SilcClientConnection conn, - * SilcServerID *server_id); + * void + * silc_client_private_message_wait_uninit(SilcClient client, + * SilcClientConnection conn, + * SilcClientEntry client_entry); * * DESCRIPTION * - * Finds entry for server by the server ID. Returns the entry or NULL - * if the entry was not found. + * Unintializes private message waiting for client indicated by + * `client_entry'. After this call private message cannot be waited + * anymore and silc_client_private_message_wait will return with FALSE + * value. * ***/ -SilcServerEntry silc_client_get_server_by_id(SilcClient client, +void silc_client_private_message_wait_uninit(SilcClient client, SilcClientConnection conn, - SilcServerID *server_id); + SilcClientEntry client_entry); -/****f* silcclient/SilcClientAPI/silc_client_del_server +/****f* silcclient/SilcClientAPI/silc_client_private_message_wait * * SYNOPSIS * - * bool silc_client_del_server(SilcClient client, SilcClientConnection conn, - * SilcServerEntry server); + * SilcBool + * silc_client_private_message_wait(SilcClient client, + * SilcClientConnection conn, + * SilcClientEntry client_entry, + * SilcMessagePayload *payload); * * DESCRIPTION * - * Removes server from local cache by the server entry indicated by - * the `server'. Returns TRUE if the deletion were successful. + * Blocks current thread or process until a private message has been + * received from the remote client indicated by `client_entry'. Before + * private messages can be waited the silc_client_private_message_wait_init + * must be called. This function can be used from a thread to wait for + * private message from the specified client. Multiple threads can be + * created to wait messages from multiple clients. Any other private + * message received from the connection indicated by `conn' will be + * forwarded to the normal `private_message' client operation callback. + * The private messages from `client_entry' will not be delivered to the + * `private_message' client operation callback. + * + * Returns TRUE and the received private message into `payload'. The caller + * must free the returned SilcMessagePayload. If this function returns + * FALSE the private messages cannot be waited anymore. This happens + * when some other thread calls silc_client_private_message_wait_uninit. + * This returns FALSE also if silc_client_private_message_wait_init has + * not been called. * ***/ -bool silc_client_del_server(SilcClient client, SilcClientConnection conn, - SilcServerEntry server); +SilcBool silc_client_private_message_wait(SilcClient client, + SilcClientConnection conn, + SilcClientEntry client_entry, + SilcMessagePayload *payload); /****f* silcclient/SilcClientAPI/silc_client_on_channel * @@ -1733,15 +1304,16 @@ bool silc_client_del_server(SilcClient client, SilcClientConnection conn, SilcChannelUser silc_client_on_channel(SilcChannelEntry channel, SilcClientEntry client_entry); -/* Command management (command.c) */ + +/* Command management */ /****f* silcclient/SilcClientAPI/silc_client_command_call * * SYNOPSIS * - * bool silc_client_command_call(SilcClient client, - * SilcClientConnection conn, - * const char *command_line, ...); + * SilcUInt16 silc_client_command_call(SilcClient client, + * SilcClientConnection conn, + * const char *command_line, ...); * * DESCRIPTION * @@ -1755,13 +1327,16 @@ SilcChannelUser silc_client_on_channel(SilcChannelEntry channel, * be the command name. The variable argument list must be terminated * with NULL. * - * Returns FALSE if the command is not known and TRUE after command. - * execution. The "command" client operation is called when the - * command is executed to indicate whether the command executed - * successfully or not. + * Returns command identifier for this sent command. It can be used + * to additionally attach to the command reply using the function + * silc_client_command_pending, if needed. Returns 0 on error. + * + * The `command' client operation callback will be called when the + * command is executed to indicate whether or not the command executed + * successfully. * - * The "command_reply" client operation will be called when reply is - * received from the server to the command. Application may also use + * The `command_reply' client operation callbak will be called when reply + * is received from the server to the command. Application may also use * the silc_client_command_pending to attach to the command reply. * The command identifier for silc_client_command_pending function after * this function call is conn->cmd_ident, which application may use. @@ -1781,67 +1356,118 @@ SilcChannelUser silc_client_on_channel(SilcChannelEntry channel, * function instead. * ***/ -bool silc_client_command_call(SilcClient client, - SilcClientConnection conn, - const char *command_line, ...); +SilcUInt16 silc_client_command_call(SilcClient client, + SilcClientConnection conn, + const char *command_line, ...); + +/****f* silcclient/SilcClientAPI/SilcClientCommandReply + * + * SYNOPSIS + * + * typedef SilcBool (*SilcClientCommandReply)(SilcClient client, + * SilcClientConnection conn, + * SilcCommand command, + * SilcStatus status, + * SilcStatus error, + * void *context, + * va_list ap); + * + * DESCRIPTION + * + * The command reply callback function given as argument to functions + * silc_client_command_send and silc_client_command_pending. This is + * called to deliver the command replies to the caller. Each command + * reply received from the server to the `command' will be delivered + * separately to the caller by calling this callback. The `status' will + * indicate whether there is only one reply or multiple replies. The + * `error' will indicate if an error occurred. The `ap' will include + * command reply arguments. They are the same arguments as for + * `command_reply' client operation callback in SilcClientOperations. + * + * If `status' is SILC_STATUS_OK only one reply was received and error + * did not occur. If it is SILC_STATUS_LIST_START, SILC_STATUS_LIST_ITEM + * or SILC_STATUS_LIST_END, there are will be two or more replies. The + * first reply is SILC_STATUS_LIST_START and last one SILC_STATUS_LIST_END. + * + * If FALSE is returned in this function this callback will not be called + * again for `command' even if there are more comand replies. By returning + * FALSE the caller my stop the command reply handling when needed. + * + ***/ +typedef SilcBool (*SilcClientCommandReply)(SilcClient client, + SilcClientConnection conn, + SilcCommand command, + SilcStatus status, + SilcStatus error, + void *context, + va_list ap); /****f* silcclient/SilcClientAPI/silc_client_command_send * * SYNOPSIS * - * void silc_client_command_send(SilcClient client, - * SilcClientConnection conn, - * SilcCommand command, SilcUInt16 ident, - * SilcUInt32 argc, ...); + * SilcUInt16 silc_client_command_send(SilcClient client, + * SilcClientConnection conn, + * SilcCommand command, + * SilcClientCommandReply reply, + * void *reply_context, + * SilcUInt32 argc, ...); * * DESCRIPTION * - * Generic function to send any command. The arguments must be sent already - * encoded into correct form and in correct order. If application wants - * to perform the commands by itself, it can do so and send the data + * Generic function to send any command. The arguments must be given + * already encoded into correct format and in correct order. If application + * wants to perform the commands by itself, it can do so and send the data * directly to the server using this function. If application is using * the silc_client_command_call, this function is usually not used. - * Note that this overriders the Client Librarys commands and sends - * the command packet directly to server. - * * Programmer should get familiar with the SILC protocol commands * specification when using this function, as the arguments needs to * be encoded as specified in the protocol. * - * The variable arguments are a pair of { type, data, data_length }, - * and the `argc' is the number of these pairs. + * The variable arguments are a set of { type, data, data_length }, + * and the `argc' is the number of these sets. + * + * The `reply' callback must be provided, and it is called when the + * command reply is received from the server. Note that, when using this + * function the default `command_reply' client operation callback will not + * be called when reply is received. + * + * Returns command identifier for this sent command. It can be used + * to additionally attach to the command reply using the function + * silc_client_command_pending, if needed. Returns 0 on error. * * EXAMPLE * - * silc_client_command_send(client, conn, SILC_COMMAND_WHOIS, 0, 1, - * 1, nickname, strlen(nickname)); + * silc_client_command_send(client, conn, SILC_COMMAND_WHOIS, + * my_whois_command_reply, cmd_ctx, + * 1, 1, nickname, strlen(nickname)); * ***/ -void silc_client_command_send(SilcClient client, SilcClientConnection conn, - SilcCommand command, SilcUInt16 ident, - SilcUInt32 argc, ...); +SilcUInt16 silc_client_command_send(SilcClient client, + SilcClientConnection conn, + SilcCommand command, + SilcClientCommandReply reply, + void *reply_context, + SilcUInt32 argc, ...); /****f* silcclient/SilcClientAPI/silc_client_command_pending * * SYNOPSIS * * void silc_client_command_pending(SilcClientConnection conn, - * SilcCommand reply_cmd, - * SilcUInt16 ident, - * SilcCommandCb callback, + * SilcCommand command, + * SilcUInt16 cmd_ident, + * SilcClientCommandReply reply, * void *context); * * DESCRIPTION * * This function can be used to add pending command callback to be * called when an command reply is received to an earlier sent command. - * The `reply_cmd' is the command that must be received in order for + * The `command' is the command that must be received in order for * the pending command callback indicated by `callback' to be called. - * The `callback' will deliver the `context' and - * SilcClientCommandReplyContext which includes the internals of the - * command reply. * - * The `ident' is a command identifier which was set for the earlier + * The `cmd_ident' is a command identifier which was set for the earlier * sent command. The command reply will include the same identifier * and pending command callback will be called when the reply is * received with the same command identifier. It is possible to @@ -1850,9 +1476,7 @@ void silc_client_command_send(SilcClient client, SilcClientConnection conn, * * Application may use this function to add its own command reply * handlers if it wishes not to use the standard `command_reply' - * client operation. However, note that the pending command callback - * does not deliver parsed command reply, but application must parse - * it itself. + * client operation. * * Note also that the application is notified about the received command * reply through the `command_reply' client operation before calling @@ -1860,111 +1484,104 @@ void silc_client_command_send(SilcClient client, SilcClientConnection conn, * command reply handling, and is called regardless whether pending * command callbacks are used or not. * - * Commands that application calls with silc_client_command_call - * will use a command identifier from conn->cmd_ident variable. After - * calling the silc_client_command_call, the conn->cmd_ident includes - * the command identifier that was used for the command sending. - * * EXAMPLE * - * silc_client_command_call(client, conn, "PING silc.silcnet.org"); - * silc_client_command_pending(conn, SILC_COMMAND_PING, conn->cmd_ident, + * SilcUInt16 cmd_ident; + * cmd_ident = silc_client_command_call(client, conn, + * "PING silc.silcnet.org"); + * silc_client_command_pending(conn, SILC_COMMAND_PING, cmd_ident, * my_ping_handler, my_ping_context); * ***/ -void silc_client_command_pending(SilcClientConnection conn, - SilcCommand reply_cmd, - SilcUInt16 ident, - SilcCommandCb callback, - void *context); +SilcBool silc_client_command_pending(SilcClientConnection conn, + SilcCommand command, + SilcUInt16 cmd_ident, + SilcClientCommandReply reply, + void *context); -/* Private Message key management (client_prvmsg.c) */ +/* Private Message key management */ /****f* silcclient/SilcClientAPI/silc_client_add_private_message_key * * SYNOPSIS * - * bool silc_client_add_private_message_key(SilcClient client, - * SilcClientConnection conn, - * SilcClientEntry client_entry, - * const char *cipher, - * const char *hmac, - * unsigned char *key, - * SilcUInt32 key_len, - * bool generate_key, - * bool responder); + * SilcBool + * silc_client_add_private_message_key(SilcClient client, + * SilcClientConnection conn, + * SilcClientEntry client_entry, + * const char *cipher, + * const char *hmac, + * unsigned char *key, + * SilcUInt32 key_len); * * DESCRIPTION * - * 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 - * indicated by the `client_entry'. If the `key' is NULL and the boolean - * value `generate_key' is TRUE the library will generate random key. - * The `key' maybe for example pre-shared-key, passphrase or similar. - * The `cipher' and `hmac' MAY be provided but SHOULD be NULL to assure - * that the requirements of the SILC protocol are met. The API, however, - * allows to allocate any cipher and HMAC. + * Adds a static private message key to the client library. The key + * will be used to encrypt all private message between the client and + * the remote client indicated by the `client_entry'. The `key' can + * be for example a pre-shared-key, passphrase or similar shared secret + * string. The `cipher' and `hmac' MAY be provided but SHOULD be NULL + * to assure that the requirements of the SILC protocol are met. The + * API, however, allows to allocate any cipher and HMAC. * - * If `responder' is TRUE then the sending and receiving keys will be - * set according the client being the receiver of the private key. If - * FALSE the client is being the sender (or negotiator) of the private - * key. + * If the private message key is added to client without first receiving + * a request for it from the remote `client_entry' this function will + * send the request to `client_entry'. Note that, the actual key is + * not sent to the network. * * It is not necessary to set key for normal private message usage. If the * key is not set then the private messages are encrypted using normal - * session keys. Setting the private key, however, increases the security. + * session keys. Setting the private key, however, increases security. * * Returns FALSE if the key is already set for the `client_entry', TRUE * otherwise. * ***/ -bool silc_client_add_private_message_key(SilcClient client, - SilcClientConnection conn, - SilcClientEntry client_entry, - const char *cipher, - const char *hmac, - unsigned char *key, - SilcUInt32 key_len, - bool generate_key, - bool responder); +SilcBool silc_client_add_private_message_key(SilcClient client, + SilcClientConnection conn, + SilcClientEntry client_entry, + const char *cipher, + const char *hmac, + unsigned char *key, + SilcUInt32 key_len); /****f* silcclient/SilcClientAPI/silc_client_add_private_message_key_ske * * SYNOPSIS * - * bool + * SilcBool * silc_client_add_private_message_key_ske(SilcClient client, * SilcClientConnection conn, * SilcClientEntry client_entry, * const char *cipher, * const char *hmac, - * SilcSKEKeyMaterial *key); + * SilcSKEKeyMaterial key); * * DESCRIPTION * * Same as silc_client_add_private_message_key but takes the key material - * from the SKE key material structure. This structure is received if + * from the SKE key material structure. This structure is received if * the application uses the silc_client_send_key_agreement to negotiate - * the key material. The `cipher' and `hmac' SHOULD be provided as it is + * the key material. The `cipher' and `hmac' SHOULD be provided as it is * negotiated also in the SKE protocol. * ***/ -bool silc_client_add_private_message_key_ske(SilcClient client, - SilcClientConnection conn, - SilcClientEntry client_entry, - const char *cipher, - const char *hmac, - SilcSKEKeyMaterial *key, - bool responder); +SilcBool silc_client_add_private_message_key_ske(SilcClient client, + SilcClientConnection conn, + SilcClientEntry client_entry, + const char *cipher, + const char *hmac, + SilcSKEKeyMaterial key); /****f* silcclient/SilcClientAPI/silc_client_del_private_message_key * * SYNOPSIS * - * bool silc_client_del_private_message_key(SilcClient client, - * SilcClientConnection conn, - * SilcClientEntry client_entry); + * SilcBool + * silc_client_del_private_message_key(SilcClient client, + * SilcClientConnection conn, + * SilcClientEntry client_entry); * * DESCRIPTION * @@ -1973,9 +1590,9 @@ bool silc_client_add_private_message_key_ske(SilcClient client, * client. Returns FALSE on error, TRUE otherwise. * ***/ -bool silc_client_del_private_message_key(SilcClient client, - SilcClientConnection conn, - SilcClientEntry client_entry); +SilcBool silc_client_del_private_message_key(SilcClient client, + SilcClientConnection conn, + SilcClientEntry client_entry); /****f* silcclient/SilcClientAPI/silc_client_list_private_message_keys * @@ -2002,73 +1619,59 @@ silc_client_list_private_message_keys(SilcClient client, SilcClientConnection conn, SilcUInt32 *key_count); -/****f* silcclient/SilcClientAPI/silc_client_send_private_message_key_request +/****f* silcclient/SilcClientAPI/silc_client_free_private_message_keys * * SYNOPSIS * - * bool - * silc_client_send_private_message_key_request(SilcClient client, - * SilcClientConnection conn, - * SilcClientEntry client_entry); + * void silc_client_free_private_message_keys(SilcPrivateMessageKeys keys, + * SilcUInt32 key_count); * * DESCRIPTION * - * This function can be used to send an private message key indicator - * request to the remote client indicated by 'client_entry'. This can - * be used when setting a static or pre-shared private message key. - * The sender of this packet is the initiator and must set the 'responder' - * argument in silc_client_add_private_message_key function to FALSE. - * The receiver of this indicator request must set it to TRUE, if the - * receiver decides to set a private message key. By using this - * function applications may automate initiator/responder setting in - * private message key functions, without asking from user which one is - * the initiator and which one is responder. - * - * NOTES - * - * The sender of this packet must set the private message key for - * 'client_entry' before calling this function. The 'responder' - * argument MUST be set to FALSE when setting the key. + * Frees the SilcPrivateMessageKeys array returned by the function + * silc_client_list_private_message_keys. * ***/ -bool -silc_client_send_private_message_key_request(SilcClient client, - SilcClientConnection conn, - SilcClientEntry client_entry); +void silc_client_free_private_message_keys(SilcPrivateMessageKeys keys, + SilcUInt32 key_count); -/****f* silcclient/SilcClientAPI/silc_client_free_private_message_keys +/****f* silcclient/SilcClientAPI/silc_client_private_message_key_is_set * * SYNOPSIS * - * void silc_client_free_private_message_keys(SilcPrivateMessageKeys keys, - * SilcUInt32 key_count); + * SilcBool + * silc_client_private_message_key_is_set(SilcClient client, + * SilcClientConnection conn, + * SilcClientEntry client_entry); * * DESCRIPTION * - * Frees the SilcPrivateMessageKeys array returned by the function - * silc_client_list_private_message_keys. + * Returns TRUE if the private message key has been set for the client + * entry indicated by `client_entry'. * ***/ -void silc_client_free_private_message_keys(SilcPrivateMessageKeys keys, - SilcUInt32 key_count); +SilcBool +silc_client_private_message_key_is_set(SilcClient client, + SilcClientConnection conn, + SilcClientEntry client_entry); -/* Channel private key management (client_channel.c, - SilcChannelPrivateKey is defined in idlist.h) */ +/* Channel private key management */ /****f* silcclient/SilcClientAPI/silc_client_add_channel_private_key * * SYNOPSIS * - * bool silc_client_add_channel_private_key(SilcClient client, - * SilcClientConnection conn, - * SilcChannelEntry channel, - * const char *name, - * char *cipher, - * char *hmac, - * unsigned char *key, - * SilcUInt32 key_len, - * SilcChannelPrivateKey *ret_key); + * SilcBool + * silc_client_add_channel_private_key(SilcClient client, + * SilcClientConnection conn, + * SilcChannelEntry channel, + * const char *name, + * char *cipher, + * char *hmac, + * unsigned char *key, + * SilcUInt32 key_len, + * SilcChannelPrivateKey *ret_key); * * DESCRIPTION * @@ -2105,23 +1708,23 @@ void silc_client_free_private_message_keys(SilcPrivateMessageKeys keys, * as channel private key. However, this API allows it. * ***/ -bool silc_client_add_channel_private_key(SilcClient client, - SilcClientConnection conn, - SilcChannelEntry channel, - const char *name, - char *cipher, - char *hmac, - unsigned char *key, - SilcUInt32 key_len, - SilcChannelPrivateKey *ret_key); +SilcBool silc_client_add_channel_private_key(SilcClient client, + SilcClientConnection conn, + SilcChannelEntry channel, + const char *name, + char *cipher, + char *hmac, + unsigned char *key, + SilcUInt32 key_len, + SilcChannelPrivateKey *ret_key); /****f* silcclient/SilcClientAPI/silc_client_del_channel_private_keys * * SYNOPSIS * - * bool silc_client_del_channel_private_keys(SilcClient client, - * SilcClientConnection conn, - * SilcChannelEntry channel); + * SilcBool silc_client_del_channel_private_keys(SilcClient client, + * SilcClientConnection conn, + * SilcChannelEntry channel); * * DESCRIPTION * @@ -2130,18 +1733,18 @@ bool silc_client_add_channel_private_key(SilcClient client, * on error, TRUE otherwise. * ***/ -bool silc_client_del_channel_private_keys(SilcClient client, - SilcClientConnection conn, - SilcChannelEntry channel); +SilcBool silc_client_del_channel_private_keys(SilcClient client, + SilcClientConnection conn, + SilcChannelEntry channel); /****f* silcclient/SilcClientAPI/silc_client_del_channel_private_key * * SYNOPSIS * - * bool silc_client_del_channel_private_key(SilcClient client, - * SilcClientConnection conn, - * SilcChannelEntry channel, - * SilcChannelPrivateKey key); + * SilcBool silc_client_del_channel_private_key(SilcClient client, + * SilcClientConnection conn, + * SilcChannelEntry channel, + * SilcChannelPrivateKey key); * * DESCRIPTION * @@ -2153,50 +1756,32 @@ bool silc_client_del_channel_private_keys(SilcClient client, * on error, TRUE otherwise. * ***/ -bool silc_client_del_channel_private_key(SilcClient client, - SilcClientConnection conn, - SilcChannelEntry channel, - SilcChannelPrivateKey key); +SilcBool silc_client_del_channel_private_key(SilcClient client, + SilcClientConnection conn, + SilcChannelEntry channel, + SilcChannelPrivateKey key); /****f* silcclient/SilcClientAPI/silc_client_list_channel_private_keys * * SYNOPSIS * - * SilcChannelPrivateKey * + * SilcDList * silc_client_list_channel_private_keys(SilcClient client, * SilcClientConnection conn, - * SilcChannelEntry channel, - * SilcUInt32 *key_count); - * - * DESCRIPTION - * - * Returns array (pointers) of private keys associated to the `channel'. - * The caller must free the array by calling the function - * silc_client_free_channel_private_keys. The pointers in the array may be - * used to delete the specific key by giving the pointer as argument to the - * function silc_client_del_channel_private_key. - * - ***/ -SilcChannelPrivateKey * -silc_client_list_channel_private_keys(SilcClient client, - SilcClientConnection conn, - SilcChannelEntry channel, - SilcUInt32 *key_count); - -/****f* silcclient/SilcClientAPI/silc_client_free_channel_private_keys - * - * SYNOPSIS - * - * void silc_client_free_channel_private_keys(SilcChannelPrivateKey *keys, - * SilcUInt32 key_count); + * SilcChannelEntry channel); * * DESCRIPTION * - * Frees the SilcChannelPrivateKey array. + * Returns list of private keys associated to the `channel'. The caller + * must free the returned list with silc_dlist_uninit. The pointers in + * the list may be used to delete the specific key by giving the pointer + * as argument to the function silc_client_del_channel_private_key. Each + * entry in the list is SilcChannelPrivateKey. * ***/ -void silc_client_free_channel_private_keys(SilcChannelPrivateKey *keys, - SilcUInt32 key_count); +SilcDList silc_client_list_channel_private_keys(SilcClient client, + SilcClientConnection conn, + SilcChannelEntry channel); /****f* silcclient/SilcClientAPI/silc_client_current_channel_private_key * @@ -2220,7 +1805,7 @@ void silc_client_current_channel_private_key(SilcClient client, SilcChannelPrivateKey key); -/* Key Agreement routines (client_keyagr.c) */ +/* Key Agreement routines */ /****f* silcclient/SilcClientAPI/silc_client_send_key_agreement * @@ -2229,62 +1814,63 @@ void silc_client_current_channel_private_key(SilcClient client, * void silc_client_send_key_agreement(SilcClient client, * SilcClientConnection conn, * SilcClientEntry client_entry, - * char *hostname, - * int port, - * SilcUInt32 timeout_secs, + * SilcClientConnectionParams *params, + * SilcPublicKey public_key, + * SilcPrivateKey private_key, * SilcKeyAgreementCallback completion, * void *context); * * DESCRIPTION * * Sends key agreement request to the remote client indicated by the - * `client_entry'. If the caller provides the `hostname' and the `port' - * arguments then the library will bind the client to that hostname and - * 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'. 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 - * the same packet including its hostname and port. If the library receives - * the reply from the remote client the `key_agreement' client operation - * callback will be called to verify whether the user wants to perform the - * key agreement or not. - * - * NOTES + * `client_entry'. + * + * If `params' is non-NULL and it has the `local_ip' and `local_port' set + * the caller will provide the connection endpoint for the key agreement + * connection. The `bind_ip' can be used to bind to that IP instead of + * `local_ip'. If the `udp' is set to TRUE the connection will be UDP + * instead of TCP. Caller may also set the `repository', `verify_notfound' + * and `timeout_secs' fields in `params'. Other fields are ignored. + * If `params' is NULL, then the `client_entry' is expected to provide + * the connection endpoint for us. It is recommended the `timeout_secs' + * is specified in case the remote client does not reply anything to + * the request. + * + * The `public_key' and `private_key' is our identity in the key agreement. + * + * In case we do not provide the connection endpoint, we will receive + * the `key_agreement' client operation when the remote send its own + * key agreement request packet. We may then there start the key + * agreement with silc_client_perform_key_agreement. If we provided the + * the connection endpoint, the client operation will not be called. + * + * There can be only one active key agreement for `client_entry'. Old + * key agreement may be aborted by calling silc_client_abort_key_agreement. * - * NOTE: If the application provided the `hostname' and the `port' and the - * remote side initiates the key agreement protocol it is not verified - * from the user anymore whether the protocol should be executed or not. - * By setting the `hostname' and `port' the user gives permission to - * perform the protocol (we are responder in this case). - * - * NOTE: If the remote side decides not to initiate the key agreement - * 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 be - * called after the specified timeout, `timeout_secs'. + * EXAMPLE * - * NOTE: If the `hostname' and the `port' was not provided the `completion' - * will not be called at all since this does nothing more than sending - * a packet to the remote host. + * // Send key agreement request (we don't provide connection endpoint) + * silc_client_send_key_agreement(client, conn, remote_client, + * NULL, public_key, private_key, + * my_keyagr_completion, my_context); * - * 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. + * // Another example where we provide connection endpoint (TCP). + * SilcClientConnectionParams params; + * memset(¶ms, 0, sizeof(params)); + * params.local_ip = local_ip; + * params.local_port = local_port; + * params.timeout_secs = 60; + * silc_client_send_key_agreement(client, conn, remote_client, + * ¶ms, public_key, private_key, + * my_keyagr_completion, my_context); * ***/ void silc_client_send_key_agreement(SilcClient client, SilcClientConnection conn, SilcClientEntry client_entry, - const char *hostname, - const char *bindhost, - int port, - SilcUInt32 timeout_secs, + SilcClientConnectionParams *params, + SilcPublicKey public_key, + SilcPrivateKey private_key, SilcKeyAgreementCallback completion, void *context); @@ -2296,72 +1882,70 @@ void silc_client_send_key_agreement(SilcClient client, * silc_client_perform_key_agreement(SilcClient client, * SilcClientConnection conn, * SilcClientEntry client_entry, - * char *hostname, - * int port, + * SilcClientConnectionParams *params, + * SilcPublicKey public_key, + * SilcPrivateKey private_key, + * char *hostname, int port, * SilcKeyAgreementCallback completion, * void *context); * * DESCRIPTION * - * Performs the actual key agreement protocol. Application may use this - * to initiate the key agreement protocol. This can be called for example - * after the application has received the `key_agreement' client operation, - * and did not return TRUE from it. + * Performs the key agreement protocol. Application may use this to + * initiate the key agreement protocol. Usually this is called after + * receiving the `key_agreement' client operation. * * The `hostname' is the remote hostname (or IP address) and the `port' - * is the remote port. The `completion' callback with the `context' will + * is the remote port. The `completion' callback with the `context' will * be called after the key agreement protocol. * - * NOTES - * - * NOTE: If the application returns TRUE in the `key_agreement' client - * operation the library will automatically start the key agreement. In this - * case the application must not call this function. However, application - * may choose to just ignore the `key_agreement' client operation (and - * merely just print information about it on the screen) and call this - * function when the user whishes to do so (by, for example, giving some - * specific command). Thus, the API provides both, automatic and manual - * initiation of the key agreement. Calling this function is the manual - * initiation and returning TRUE in the `key_agreement' client operation - * is the automatic initiation. + * The `params' is connection parameters and it may be used to define + * the key agreement connection related parameters. It may be NULL. * ***/ void silc_client_perform_key_agreement(SilcClient client, SilcClientConnection conn, SilcClientEntry client_entry, - char *hostname, - int port, + SilcClientConnectionParams *params, + SilcPublicKey public_key, + SilcPrivateKey private_key, + char *hostname, int port, SilcKeyAgreementCallback completion, void *context); -/****f* silcclient/SilcClientAPI/silc_client_perform_key_agreement_fd +/****f* silcclient/SilcClientAPI/silc_client_perform_key_agreement_stream * * SYNOPSIS * * void - * silc_client_perform_key_agreement_fd(SilcClient client, - * SilcClientConnection conn, - * SilcClientEntry client_entry, - * int sock, - * char *hostname, - * SilcKeyAgreementCallback completion, - * void *context); + * silc_client_perform_key_agreement_stream( + * SilcClient client, + * SilcClientConnection conn, + * SilcClientEntry client_entry, + * SilcClientConnectionParams *params, + * SilcPublicKey public_key, + * SilcPrivateKey private_key, + * SilcStream stream, + * SilcKeyAgreementCallback completion, + * void *context); * * DESCRIPTION * - * 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. + * Same as silc_client_perform_key_agreement but the caller has created + * the connection to remote client. The `stream' is the created + * connection. * ***/ -void silc_client_perform_key_agreement_fd(SilcClient client, - SilcClientConnection conn, - SilcClientEntry client_entry, - int sock, - char *hostname, - SilcKeyAgreementCallback completion, - void *context); +void +silc_client_perform_key_agreement_stream(SilcClient client, + SilcClientConnection conn, + SilcClientEntry client_entry, + SilcClientConnectionParams *params, + SilcPublicKey public_key, + SilcPrivateKey private_key, + SilcStream stream, + SilcKeyAgreementCallback completion, + void *context); /****f* silcclient/SilcClientAPI/silc_client_abort_key_agreement * @@ -2393,9 +1977,9 @@ void silc_client_abort_key_agreement(SilcClient client, * * SYNOPSIS * - * void silc_client_set_away_message(SilcClient client, - * SilcClientConnection conn, - * char *message); + * SilcBool silc_client_set_away_message(SilcClient client, + * SilcClientConnection conn, + * char *message); * * DESCRIPTION * @@ -2405,73 +1989,47 @@ void silc_client_abort_key_agreement(SilcClient client, * automatically back to the the client who send private message. If * away message is already set this replaces the old message with the * new one. If `message' is NULL the old away message is removed. - * The sender may freely free the memory of the `message'. + * The sender may freely free the memory of the `message'. Returns + * FALSE on error. * ***/ -void silc_client_set_away_message(SilcClient client, - SilcClientConnection conn, - char *message); +SilcBool silc_client_set_away_message(SilcClient client, + SilcClientConnection conn, + char *message); -/****f* silcclient/SilcClientAPI/SilcConnectionAuthRequest +/****d* silcclient/SilcClientAPI/SilcClientMonitorStatus * - * SYNOPSIS + * NAME * - * typedef void (*SilcConnectionAuthRequest)(SilcClient client, - * SilcClientConnection conn, - * SilcAuthMethod auth_meth, - * void *context); + * typedef enum { ... } SilcClientMonitorStatus; * * DESCRIPTION * - * Connection authentication method request callback. This is called - * by the client library after it has received the authentication method - * that the application requested by calling the function - * silc_client_request_authentication_method. - * - ***/ -typedef void (*SilcConnectionAuthRequest)(SilcClient client, - SilcClientConnection conn, - SilcAuthMethod auth_meth, - void *context); - -/****f* silcclient/SilcClientAPI/silc_client_request_authentication_method - * - * SYNOPSIS - * - * void - * silc_client_request_authentication_method(SilcClient client, - * SilcClientConnection conn, - * SilcConnectionAuthRequest - * callback, - * void *context); - * - * DESCRIPTION + * File transmission session status types. These will indicate + * the status of the file transmission session. * - * This function can be used to request the current authentication method - * from the server. This may be called when connecting to the server - * and the client library requests the authentication data from the - * application. If the application does not know the current authentication - * method it can request it from the server using this function. - * The `callback' with `context' will be called after the server has - * replied back with the current authentication method. + * The SILC_CLIENT_FILE_MONITOR_KEY_AGREEMENT is called when session + * is key exchange phase. * - ***/ -void -silc_client_request_authentication_method(SilcClient client, - SilcClientConnection conn, - SilcConnectionAuthRequest callback, - void *context); - -/****d* silcclient/SilcClientAPI/SilcClientMonitorStatus + * The SILC_CLIENT_FILE_MONITOR_SEND is called when data is being sent + * to remote client. * - * NAME + * The SILC_CLIENT_FILE_MONITOR_RECEIVE is called when data is being + * recieved from remote client. * - * typedef enum { ... } SilcClientMonitorStatus; + * The SILC_CLIENT_FILE_MONITOR_CLOSED will be called when the user + * issues silc_client_file_close. If needed, it may be ignored in the + * monitor callback. * - * DESCRIPTION + * The SILC_CLIENT_FILE_MONITOR_DISCONNECT will be called if remote + * disconnects the session connection. The silc_client_file_close must + * be called when this status is received. The session is over when + * this is received. * - * File transmission session status types. These will indicate - * the status of the file transmission session. + * The SILC_CLIENLT_FILE_MONITOR_ERROR is called in case some error + * occured. The SilcClientFileError will indicate more detailed error + * condition. The silc_client_file_close must be called when this status + * is received. The session is over when this is received. * * SOURCE */ @@ -2479,9 +2037,10 @@ typedef enum { SILC_CLIENT_FILE_MONITOR_KEY_AGREEMENT, /* In key agreemenet phase */ SILC_CLIENT_FILE_MONITOR_SEND, /* Sending file */ SILC_CLIENT_FILE_MONITOR_RECEIVE, /* Receiving file */ - SILC_CLIENT_FILE_MONITOR_GET, - SILC_CLIENT_FILE_MONITOR_PUT, + SILC_CLIENT_FILE_MONITOR_GET, /* Unsupported */ + SILC_CLIENT_FILE_MONITOR_PUT, /* Unsupported */ SILC_CLIENT_FILE_MONITOR_CLOSED, /* Session closed */ + SILC_CLIENT_FILE_MONITOR_DISCONNECT, /* Session disconnected */ SILC_CLIENT_FILE_MONITOR_ERROR, /* Error during session */ } SilcClientMonitorStatus; /***/ @@ -2502,12 +2061,15 @@ typedef enum { */ typedef enum { SILC_CLIENT_FILE_OK, - SILC_CLIENT_FILE_ERROR, - SILC_CLIENT_FILE_UNKNOWN_SESSION, - SILC_CLIENT_FILE_ALREADY_STARTED, - SILC_CLIENT_FILE_NO_SUCH_FILE, - SILC_CLIENT_FILE_PERMISSION_DENIED, - SILC_CLIENT_FILE_KEY_AGREEMENT_FAILED, + SILC_CLIENT_FILE_ERROR, /* Generic error */ + SILC_CLIENT_FILE_UNKNOWN_SESSION, /* Unknown session ID */ + SILC_CLIENT_FILE_ALREADY_STARTED, /* Session already started */ + SILC_CLIENT_FILE_NO_SUCH_FILE, /* No such file */ + SILC_CLIENT_FILE_PERMISSION_DENIED, /* Permission denied */ + SILC_CLIENT_FILE_KEY_AGREEMENT_FAILED, /* Key exchange failed */ + SILC_CLIENT_FILE_CONNECT_FAILED, /* Error during connecting */ + SILC_CLIENT_FILE_TIMEOUT, /* Connecting timedout */ + SILC_CLIENT_FILE_NO_MEMORY, /* System out of memory */ } SilcClientFileError; /***/ @@ -2535,7 +2097,8 @@ typedef enum { * currently transmitted amount of total `filesize'. The `client_entry' * indicates the remote client, and the transmission session ID is the * `session_id'. The filename being transmitted is indicated by the - * `filepath'. + * `filepath'. The `conn' is NULL if the connection to remote client + * does not exist yet. * ***/ typedef void (*SilcClientFileMonitor)(SilcClient client, @@ -2580,7 +2143,7 @@ typedef void (*SilcClientFileName)(const char *filepath, * * DESCRIPTION * - * File name asking callback, that is called if it is given to the + * File name asking callback that is called if it is given to the * silc_client_file_receive and the path given to that as argument was * NULL. The library calls this to ask the filename and filepath to * where the file is to be saved. The 'remote_filename' is the file @@ -2604,13 +2167,13 @@ typedef void (*SilcClientFileAskName)(SilcClient client, * SilcClientFileError * silc_client_file_send(SilcClient client, * SilcClientConnection conn, + * SilcClientEntry client_entry, + * SilcClientConnectionParams *params, + * SilcPublicKey public_key, + * SilcPrivateKey private_key, * SilcClientFileMonitor monitor, * void *monitor_context, - * const char *local_ip, - * SilcUInt32 local_port, - * bool do_not_bind, - * SilcClientEntry client_entry, - * const char *filepath); + * const char *filepath, * SilcUInt32 *session_id); * * DESCRIPTION @@ -2626,29 +2189,32 @@ typedef void (*SilcClientFileAskName)(SilcClient client, * abort the file transmission) by calling the silc_client_file_close * function. The session ID is also returned in the `monitor' callback. * - * If the `local_ip' is provided then this will try to bind the - * listener for key exchange protocol to that IP. If `local_port' is - * non-zero that port is used. If `local_ip' is NULL then this will - * automatically attempt to bind it to local IP address of the machine. - * If `do_not_bind' is TRUE then the `local_ip' and `local_port' are - * ignored and it is expected that the receiver will provide the - * point of contact. This is usefull if the sender is behind NAT. + * If `params' is non-NULL and it has the `local_ip' and `local_port' set + * the caller will provide the connection endpoint for the key agreement + * connection. The `bind_ip' can be used to bind to that IP instead of + * `local_ip'. Caller may also set the `repository', `verify_notfound' + * and `timeout_secs' fields in `params'. Other fields are ignored. + * If `params' is NULL, then the `client_entry' is expected to provide + * the connection endpoint for us. It is recommended the `timeout_secs' + * is specified in case the remote client does not reply anything to + * the request. * - * If error will occur during the file transfer process the error - * status will be returned in the monitor callback. In this case - * the application must call silc_client_file_close to close the - * session. + * The `public_key' and `private_key' is our identity in the key agreement. + * + * If error will occur during the file transfer process the error status + * will be returned in the monitor callback. In this case the application + * must call silc_client_file_close to close the session. * ***/ SilcClientFileError silc_client_file_send(SilcClient client, SilcClientConnection conn, + SilcClientEntry client_entry, + SilcClientConnectionParams *params, + SilcPublicKey public_key, + SilcPrivateKey private_key, SilcClientFileMonitor monitor, void *monitor_context, - const char *local_ip, - SilcUInt32 local_port, - bool do_not_bind, - SilcClientEntry client_entry, const char *filepath, SilcUInt32 *session_id); @@ -2659,6 +2225,9 @@ silc_client_file_send(SilcClient client, * SilcClientFileError * silc_client_file_receive(SilcClient client, * SilcClientConnection conn, + * SilcClientConnectionParams *params, + * SilcPublicKey public_key, + * SilcPrivateKey private_key, * SilcClientFileMonitor monitor, * void *monitor_context, * const char *path, @@ -2670,7 +2239,7 @@ silc_client_file_send(SilcClient client, * * Receives a file from a client indicated by the `client_entry'. The * `session_id' indicates the file transmission session and it has been - * received in the `ftp' client operation function. This will actually + * received in the `ftp' client operation callback. This will actually * perform the key agreement protocol with the remote client before * actually starting the file transmission. The `monitor' callback * will be called to monitor the transmission. If `path' is non-NULL @@ -2679,15 +2248,26 @@ silc_client_file_send(SilcClient client, * callback is non-NULL. In this case the callback is called to ask * the path and filename from application. * - * If error will occur during the file transfer process the error - * status will be returned in the monitor callback. In this case - * the application must call silc_client_file_close to close the - * session. + * The `params' is the connection related parameters. If the remote client + * provided connection point the `params' will be used when creating + * connection to the remote client. If remote client did not provide + * connection point the `params' is used to provide connection point + * locally for the remote client. See silc_client_file_send for more + * information on providing connection point for remote client. + * + * The `public_key' and `private_key' is our identity in the key agreement. + * + * If error will occur during the file transfer process the error status + * will be returned in the monitor callback. In this case the application + * must call silc_client_file_close to close the session. * ***/ SilcClientFileError silc_client_file_receive(SilcClient client, SilcClientConnection conn, + SilcClientConnectionParams *params, + SilcPublicKey public_key, + SilcPrivateKey private_key, SilcClientFileMonitor monitor, void *monitor_context, const char *path, @@ -2760,7 +2340,7 @@ SilcAttributePayload silc_client_attribute_add(SilcClient client, * * SYNOPSIS * - * bool silc_client_attribute_del(SilcClient client, + * SilcBool silc_client_attribute_del(SilcClient client, * SilcClientConnection conn, * SilcAttribute attribute, * SilcAttributePayload attr); @@ -2777,10 +2357,10 @@ SilcAttributePayload silc_client_attribute_add(SilcClient client, * This function Returns TRUE if the attribute was found and deleted. * ***/ -bool silc_client_attribute_del(SilcClient client, - SilcClientConnection conn, - SilcAttribute attribute, - SilcAttributePayload attr); +SilcBool silc_client_attribute_del(SilcClient client, + SilcClientConnection conn, + SilcAttribute attribute, + SilcAttributePayload attr); /****f* silcclient/SilcClientAPI/silc_client_attributes_get * @@ -2800,8 +2380,8 @@ bool silc_client_attribute_del(SilcClient client, * payload while traversing the table. * ***/ -const SilcHashTable silc_client_attributes_get(SilcClient client, - SilcClientConnection conn); +SilcHashTable silc_client_attributes_get(SilcClient client, + SilcClientConnection conn); /****f* silcclient/SilcClientAPI/silc_client_attributes_request * @@ -2832,38 +2412,64 @@ const SilcHashTable silc_client_attributes_get(SilcClient client, ***/ SilcBuffer silc_client_attributes_request(SilcAttribute attribute, ...); -/* Low level packet sending functions */ +/****f* silcclient/SilcClientAPI/silc_client_nickname_format + * + * SYNOPSIS + * + * SilcClientEntry + * silc_client_nickname_format(SilcClient client, + * SilcClientConnection conn, + * SilcClientEntry client_entry, + * SilcBool priority); + * + * DESCRIPTION + * + * Formats the nickname of `client_entry' according to the nickname + * formatting rules set in SilcClientParams. If the `priority' is TRUE + * then the `client_entry' will always get the unformatted nickname. + * If FALSE and there are more than one same nicknames in the client + * the nickname will be formatted. + * + * This returns NULL on error. Otherwise, the client entry that was + * formatted is returned. If `priority' is FALSE this always returns + * the `client_entry'. If it is TRUE, this may return the client entry + * that was formatted after giving the `client_entry' the unformatted + * nickname. + * + * Usually application does not need to call this function, as the library + * automatically formats nicknames. However, if application wants to + * for example force the `client_entry' to always have the unformatted + * nickname it may call this function to do so. + * + ***/ +SilcClientEntry silc_client_nickname_format(SilcClient client, + SilcClientConnection conn, + SilcClientEntry client_entry, + SilcBool priority); -/****f* silcclient/SilcClientAPI/silc_client_send_packet +/****f* silcclient/SilcClientAPI/silc_client_nickname_parse * * SYNOPSIS * - * bool silc_client_send_packet(SilcClient client, - * SilcClientConnection conn, - * SilcPacketType type, - * const unsigned char *data, - * SilcUInt32 data_len); + * SilcBool silc_client_nickname_parse(SilcClient client, + * SilcClientConnection conn, + * char *nickname, + * char **ret_nick); * * DESCRIPTION * - * This routine can be used by application to send packets directly - * to a connection indicated by `conn'. Usually application does not - * need this routine since the Client Library handles the packet - * sending. The `type' indicates the packet type. If `data' is - * NULL then empty packet is sent. This returns FALSE if packet cannot - * be sent. + * Parses the `nickname' according to the format string given in the + * SilcClientParams. Returns the parsed nickname into the `ret_nick'. + * The caller must free the returned pointer. Returns FALSE if error + * occurred during parsing. Returns TRUE if the nickname was parsed, + * it was not formatted or if the format string has not been specified + * in SilcClientParams. * ***/ -bool silc_client_send_packet(SilcClient client, - SilcClientConnection conn, - SilcPacketType type, - const unsigned char *data, - SilcUInt32 data_len); - -#include "command.h" -#include "command_reply.h" -#include "idlist.h" -#include "protocol.h" +SilcBool silc_client_nickname_parse(SilcClient client, + SilcClientConnection conn, + char *nickname, + char **ret_nick); #ifdef __cplusplus }