5 Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
7 Copyright (C) 1997 - 2001 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
24 /* Forward declarations */
25 typedef struct SilcClientStruct *SilcClient;
26 typedef struct SilcClientConnectionStruct *SilcClientConnection;
27 typedef struct SilcClientPingStruct SilcClientPing;
28 typedef struct SilcClientAwayStruct SilcClientAway;
29 typedef struct SilcClientKeyAgreementStruct *SilcClientKeyAgreement;
35 /* Generic rekey context for connections */
37 /* Current sending encryption key, provided for re-key. The `pfs'
38 is TRUE if the Perfect Forward Secrecy is performed in re-key. */
39 unsigned char *send_enc_key;
47 /* Connection structure used in client to associate all the important
48 connection specific data to this structure. */
49 struct SilcClientConnectionStruct {
55 /* Local client ID for this connection */
56 SilcClientID *local_id;
58 /* Decoded local ID so that the above defined ID would not have
59 to be decoded for every packet. */
60 unsigned char *local_id_data;
61 uint32 local_id_data_len;
63 /* Own client entry. */
64 SilcClientEntry local_entry;
74 /* Remote server ID for this connection */
75 SilcServerID *remote_id;
77 /* Decoded remote ID so that the above defined ID would not have
78 to be decoded for every packet. */
79 unsigned char *remote_id_data;
80 uint32 remote_id_data_len;
85 /* Keys and stuff negotiated in the SKE protocol */
87 SilcCipher receive_key;
91 /* Client ID and Channel ID cache. Messages transmitted in SILC network
92 are done using different unique ID's. These are the cache for
93 thoses ID's used in the communication. */
94 SilcIDCache client_cache;
95 SilcIDCache channel_cache;
96 SilcIDCache server_cache;
98 /* Current channel on window. All channels are saved (allocated) into
100 SilcChannelEntry current_channel;
102 /* Socket connection object for this connection (window). This
103 object will have a back-pointer to this window object for fast
104 referencing (sock->user_data). */
105 SilcSocketConnection sock;
107 /* Pending command queue for this connection */
108 SilcDList pending_commands;
110 /* Current command identifier, 0 not used */
113 /* Requested pings. */
114 SilcClientPing *ping;
117 /* Set away message */
118 SilcClientAway *away;
121 SilcClientRekey rekey;
123 /* Pointer back to the SilcClient. This object is passed to the application
124 and the actual client object is accesible through this pointer. */
127 /* User data context. Library does not touch this. */
131 /* Main client structure. */
132 struct SilcClientStruct {
134 * Public data. All the following pointers must be set by the allocator
138 /* Users's username, hostname and realname. */
143 /* Private and public key of the user. */
145 SilcPublicKey public_key;
146 SilcPrivateKey private_key;
148 /* Application specific user data pointer. Client library does not
153 * Private data. Following pointers are used internally by the client
154 * library and should be considered read-only fields.
157 /* All client operations that are implemented in the application. */
158 SilcClientOperations *ops;
160 /* SILC client task queues */
161 SilcTaskQueue io_queue;
162 SilcTaskQueue timeout_queue;
163 SilcTaskQueue generic_queue;
165 /* Table of connections in client. All the connection data is saved here. */
166 SilcClientConnection *conns;
169 /* Table of listenning sockets in client. Client can have listeners
170 (like key agreement protocol server) and those sockets are saved here.
171 This table is checked always if the connection object cannot be found
172 from the `conns' table. */
173 SilcSocketConnection *sockets;
174 uint32 sockets_count;
176 /* Generic cipher and hash objects. These can be used and referenced
177 by the application as well. */
178 SilcCipher none_cipher;
184 /* Random Number Generator. Application should use this as its primary
185 random number generator. */
191 /* Registers generic task for file descriptor for reading from network and
192 writing to network. As being generic task the actual task is allocated
193 only once and after that the same task applies to all registered fd's. */
194 #define SILC_CLIENT_REGISTER_CONNECTION_FOR_IO(fd) \
196 SilcTask tmptask = silc_task_register(client->generic_queue, (fd), \
197 silc_client_packet_process, \
200 SILC_TASK_PRI_NORMAL); \
201 silc_task_set_iotype(tmptask, SILC_TASK_WRITE); \
204 #define SILC_CLIENT_SET_CONNECTION_FOR_INPUT(fd) \
206 silc_schedule_set_listen_fd((fd), (1L << SILC_TASK_READ)); \
209 #define SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT(fd) \
211 silc_schedule_set_listen_fd((fd), ((1L << SILC_TASK_READ) | \
212 (1L << SILC_TASK_WRITE))); \
215 /* Finds socket connection object by file descriptor */
216 #define SILC_CLIENT_GET_SOCK(__x, __fd, __sock) \
220 for (__i = 0; __i < (__x)->conns_count; __i++) \
221 if ((__x)->conns[__i] && \
222 (__x)->conns[__i]->sock->sock == (__fd)) \
225 if (__i >= (__x)->conns_count) { \
227 for (__i = 0; __i < (__x)->sockets_count; __i++) \
228 if ((__x)->sockets[__i] && \
229 (__x)->sockets[__i]->sock == (__fd)) \
230 (__sock) = (__x)->sockets[__i]; \
232 (__sock) = (__x)->conns[__i]->sock; \
235 /* Check whether rekey protocol is active */
236 #define SILC_CLIENT_IS_REKEY(sock) \
237 (sock->protocol && sock->protocol->protocol && \
238 sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY)
240 /* Prototypes (some of the prototypes are defined in the silcapi.h) */
242 void silc_client_packet_send(SilcClient client,
243 SilcSocketConnection sock,
246 SilcIdType dst_id_type,
252 void silc_client_disconnected_by_server(SilcClient client,
253 SilcSocketConnection sock,
255 void silc_client_error_by_server(SilcClient client,
256 SilcSocketConnection sock,
258 void silc_client_receive_new_id(SilcClient client,
259 SilcSocketConnection sock,
261 SilcChannelEntry silc_client_new_channel_id(SilcClient client,
262 SilcSocketConnection sock,
266 void silc_client_save_channel_key(SilcClientConnection conn,
267 SilcBuffer key_payload,
268 SilcChannelEntry channel);
269 void silc_client_receive_channel_key(SilcClient client,
270 SilcSocketConnection sock,
272 void silc_client_channel_message(SilcClient client,
273 SilcSocketConnection sock,
274 SilcPacketContext *packet);
275 void silc_client_remove_from_channels(SilcClient client,
276 SilcClientConnection conn,
277 SilcClientEntry client_entry);
278 void silc_client_replace_from_channels(SilcClient client,
279 SilcClientConnection conn,
281 SilcClientEntry new);
282 char *silc_client_chmode(uint32 mode, SilcChannelEntry channel);
283 char *silc_client_chumode(uint32 mode);
284 char *silc_client_chumode_char(uint32 mode);
285 void silc_client_process_failure(SilcClient client,
286 SilcSocketConnection sock,
287 SilcPacketContext *packet);
288 void silc_client_key_agreement(SilcClient client,
289 SilcSocketConnection sock,
290 SilcPacketContext *packet);
291 void silc_client_notify_by_server(SilcClient client,
292 SilcSocketConnection sock,
293 SilcPacketContext *packet);
294 void silc_client_private_message(SilcClient client,
295 SilcSocketConnection sock,
296 SilcPacketContext *packet);
298 void silc_client_packet_send_flush(SilcClient client,
299 SilcSocketConnection sock,
302 SilcIdType dst_id_type,