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 /* Context to hold the connection authentication request callbacks that
48 will be called when the server has replied back to our request about
49 current authentication method in the session. */
51 SilcConnectionAuthRequest callback;
54 } *SilcClientConnAuthRequest;
56 /* Connection structure used in client to associate all the important
57 connection specific data to this structure. */
58 struct SilcClientConnectionStruct {
64 /* Local client ID for this connection */
65 SilcClientID *local_id;
67 /* Decoded local ID so that the above defined ID would not have
68 to be decoded for every packet. */
69 unsigned char *local_id_data;
70 uint32 local_id_data_len;
72 /* Own client entry. */
73 SilcClientEntry local_entry;
83 /* Remote server ID for this connection */
84 SilcServerID *remote_id;
86 /* Decoded remote ID so that the above defined ID would not have
87 to be decoded for every packet. */
88 unsigned char *remote_id_data;
89 uint32 remote_id_data_len;
94 /* Keys and stuff negotiated in the SKE protocol */
96 SilcCipher receive_key;
98 SilcHmac hmac_receive;
101 /* Client ID and Channel ID cache. Messages transmitted in SILC network
102 are done using different unique ID's. These are the cache for
103 thoses ID's used in the communication. */
104 SilcIDCache client_cache;
105 SilcIDCache channel_cache;
106 SilcIDCache server_cache;
108 /* Current channel on window. All channels are saved (allocated) into
109 the cache entries. */
110 SilcChannelEntry current_channel;
112 /* Socket connection object for this connection (window). This
113 object will have a back-pointer to this window object for fast
114 referencing (sock->user_data). */
115 SilcSocketConnection sock;
117 /* Pending command queue for this connection */
118 SilcDList pending_commands;
120 /* Current command identifier, 0 not used */
123 /* Requested pings. */
124 SilcClientPing *ping;
127 /* Set away message */
128 SilcClientAway *away;
131 SilcClientRekey rekey;
133 /* Authentication request context. */
134 SilcClientConnAuthRequest connauth;
136 /* Pointer back to the SilcClient. This object is passed to the application
137 and the actual client object is accesible through this pointer. */
140 /* User data context. Library does not touch this. */
144 /* Main client structure. */
145 struct SilcClientStruct {
147 * Public data. All the following pointers must be set by the allocator
151 /* Users's username, hostname and realname. */
156 /* Private and public key of the user. */
158 SilcPublicKey public_key;
159 SilcPrivateKey private_key;
161 /* Application specific user data pointer. Client library does not
166 * Private data. Following pointers are used internally by the client
167 * library and should be considered read-only fields.
170 /* All client operations that are implemented in the application. */
171 SilcClientOperations *ops;
173 /* Client Parameters */
174 SilcClientParams *params;
176 /* SILC client scheduler */
177 SilcSchedule schedule;
179 /* Table of connections in client. All the connection data is saved here. */
180 SilcClientConnection *conns;
183 /* Table of listenning sockets in client. Client can have listeners
184 (like key agreement protocol server) and those sockets are saved here.
185 This table is checked always if the connection object cannot be found
186 from the `conns' table. */
187 SilcSocketConnection *sockets;
188 uint32 sockets_count;
190 /* Generic cipher and hash objects. These can be used and referenced
191 by the application as well. */
192 SilcCipher none_cipher;
198 /* Random Number Generator. Application should use this as its primary
199 random number generator. */
202 /* Client version. Used to compare to remote host's version strings. */
203 char *silc_client_version;
208 /* Registers generic task for file descriptor for reading from network and
209 writing to network. As being generic task the actual task is allocated
210 only once and after that the same task applies to all registered fd's. */
211 #define SILC_CLIENT_REGISTER_CONNECTION_FOR_IO(fd) \
213 silc_schedule_task_add(client->schedule, (fd), \
214 silc_client_packet_process, \
217 SILC_TASK_PRI_NORMAL); \
220 #define SILC_CLIENT_SET_CONNECTION_FOR_INPUT(s, fd) \
222 silc_schedule_set_listen_fd((s), (fd), SILC_TASK_READ); \
225 #define SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT(s, fd) \
227 silc_schedule_set_listen_fd((s), (fd), (SILC_TASK_READ | \
231 /* Finds socket connection object by file descriptor */
232 #define SILC_CLIENT_GET_SOCK(__x, __fd, __sock) \
236 for (__i = 0; __i < (__x)->conns_count; __i++) \
237 if ((__x)->conns[__i] && \
238 (__x)->conns[__i]->sock->sock == (__fd)) \
241 if (__i >= (__x)->conns_count) { \
243 for (__i = 0; __i < (__x)->sockets_count; __i++) \
244 if ((__x)->sockets[__i] && \
245 (__x)->sockets[__i]->sock == (__fd)) \
246 (__sock) = (__x)->sockets[__i]; \
248 (__sock) = (__x)->conns[__i]->sock; \
251 /* Check whether rekey protocol is active */
252 #define SILC_CLIENT_IS_REKEY(sock) \
253 (sock->protocol && sock->protocol->protocol && \
254 sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY)
256 /* Prototypes (some of the prototypes are defined in the silcapi.h) */
258 void silc_client_packet_send(SilcClient client,
259 SilcSocketConnection sock,
262 SilcIdType dst_id_type,
268 void silc_client_disconnected_by_server(SilcClient client,
269 SilcSocketConnection sock,
271 void silc_client_error_by_server(SilcClient client,
272 SilcSocketConnection sock,
274 void silc_client_receive_new_id(SilcClient client,
275 SilcSocketConnection sock,
277 SilcChannelEntry silc_client_new_channel_id(SilcClient client,
278 SilcSocketConnection sock,
282 void silc_client_save_channel_key(SilcClientConnection conn,
283 SilcBuffer key_payload,
284 SilcChannelEntry channel);
285 void silc_client_receive_channel_key(SilcClient client,
286 SilcSocketConnection sock,
288 void silc_client_channel_message(SilcClient client,
289 SilcSocketConnection sock,
290 SilcPacketContext *packet);
291 void silc_client_remove_from_channels(SilcClient client,
292 SilcClientConnection conn,
293 SilcClientEntry client_entry);
294 void silc_client_replace_from_channels(SilcClient client,
295 SilcClientConnection conn,
297 SilcClientEntry newclient);
298 void silc_client_process_failure(SilcClient client,
299 SilcSocketConnection sock,
300 SilcPacketContext *packet);
301 void silc_client_key_agreement(SilcClient client,
302 SilcSocketConnection sock,
303 SilcPacketContext *packet);
304 void silc_client_notify_by_server(SilcClient client,
305 SilcSocketConnection sock,
306 SilcPacketContext *packet);
307 void silc_client_private_message(SilcClient client,
308 SilcSocketConnection sock,
309 SilcPacketContext *packet);
310 void silc_client_connection_auth_request(SilcClient client,
311 SilcSocketConnection sock,
312 SilcPacketContext *packet);