5 Author: Pekka Riikonen <priikone@silcnet.org>
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;
103 /* Client ID and Channel ID cache. Messages transmitted in SILC network
104 are done using different unique ID's. These are the cache for
105 thoses ID's used in the communication. */
106 SilcIDCache client_cache;
107 SilcIDCache channel_cache;
108 SilcIDCache server_cache;
110 /* Current channel on window. All channels are saved (allocated) into
111 the cache entries. */
112 SilcChannelEntry current_channel;
114 /* Socket connection object for this connection (window). This
115 object will have a back-pointer to this window object for fast
116 referencing (sock->user_data). */
117 SilcSocketConnection sock;
119 /* Pending command queue for this connection */
120 SilcDList pending_commands;
122 /* Current command identifier, 0 not used */
125 /* Requested pings. */
126 SilcClientPing *ping;
129 /* Set away message */
130 SilcClientAway *away;
133 SilcClientRekey rekey;
135 /* Authentication request context. */
136 SilcClientConnAuthRequest connauth;
138 /* Pointer back to the SilcClient. This object is passed to the application
139 and the actual client object is accesible through this pointer. */
142 /* User data context. Library does not touch this. */
146 /* Main client structure. */
147 struct SilcClientStruct {
149 * Public data. All the following pointers must be set by the allocator
153 /* Users's username, hostname and realname. */
158 /* Private and public key of the user. */
160 SilcPublicKey public_key;
161 SilcPrivateKey private_key;
163 /* Application specific user data pointer. Client library does not
168 * Private data. Following pointers are used internally by the client
169 * library and should be considered read-only fields.
172 /* All client operations that are implemented in the application. */
173 SilcClientOperations *ops;
175 /* Client Parameters */
176 SilcClientParams *params;
178 /* SILC client scheduler */
179 SilcSchedule schedule;
181 /* Table of connections in client. All the connection data is saved here. */
182 SilcClientConnection *conns;
185 /* Table of listenning sockets in client. Client can have listeners
186 (like key agreement protocol server) and those sockets are saved here.
187 This table is checked always if the connection object cannot be found
188 from the `conns' table. */
189 SilcSocketConnection *sockets;
190 uint32 sockets_count;
192 /* Generic cipher and hash objects. These can be used and referenced
193 by the application as well. */
194 SilcCipher none_cipher;
200 /* Random Number Generator. Application should use this as its primary
201 random number generator. */
204 /* Client version. Used to compare to remote host's version strings. */
205 char *silc_client_version;
210 /* Registers generic task for file descriptor for reading from network and
211 writing to network. As being generic task the actual task is allocated
212 only once and after that the same task applies to all registered fd's. */
213 #define SILC_CLIENT_REGISTER_CONNECTION_FOR_IO(fd) \
215 silc_schedule_task_add(client->schedule, (fd), \
216 silc_client_packet_process, \
219 SILC_TASK_PRI_NORMAL); \
222 #define SILC_CLIENT_SET_CONNECTION_FOR_INPUT(s, fd) \
224 silc_schedule_set_listen_fd((s), (fd), SILC_TASK_READ); \
227 #define SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT(s, fd) \
229 silc_schedule_set_listen_fd((s), (fd), (SILC_TASK_READ | \
233 /* Finds socket connection object by file descriptor */
234 #define SILC_CLIENT_GET_SOCK(__x, __fd, __sock) \
238 for (__i = 0; __i < (__x)->conns_count; __i++) \
239 if ((__x)->conns[__i] && \
240 (__x)->conns[__i]->sock->sock == (__fd)) \
243 if (__i >= (__x)->conns_count) { \
245 for (__i = 0; __i < (__x)->sockets_count; __i++) \
246 if ((__x)->sockets[__i] && \
247 (__x)->sockets[__i]->sock == (__fd)) \
248 (__sock) = (__x)->sockets[__i]; \
250 (__sock) = (__x)->conns[__i]->sock; \
253 /* Check whether rekey protocol is active */
254 #define SILC_CLIENT_IS_REKEY(sock) \
255 (sock->protocol && sock->protocol->protocol && \
256 sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY)
258 /* Prototypes (some of the prototypes are defined in the silcapi.h) */
260 void silc_client_packet_send(SilcClient client,
261 SilcSocketConnection sock,
264 SilcIdType dst_id_type,
270 void silc_client_disconnected_by_server(SilcClient client,
271 SilcSocketConnection sock,
273 void silc_client_error_by_server(SilcClient client,
274 SilcSocketConnection sock,
276 void silc_client_receive_new_id(SilcClient client,
277 SilcSocketConnection sock,
279 SilcChannelEntry silc_client_new_channel_id(SilcClient client,
280 SilcSocketConnection sock,
284 void silc_client_save_channel_key(SilcClientConnection conn,
285 SilcBuffer key_payload,
286 SilcChannelEntry channel);
287 void silc_client_receive_channel_key(SilcClient client,
288 SilcSocketConnection sock,
290 void silc_client_channel_message(SilcClient client,
291 SilcSocketConnection sock,
292 SilcPacketContext *packet);
293 void silc_client_remove_from_channels(SilcClient client,
294 SilcClientConnection conn,
295 SilcClientEntry client_entry);
296 void silc_client_replace_from_channels(SilcClient client,
297 SilcClientConnection conn,
299 SilcClientEntry newclient);
300 void silc_client_process_failure(SilcClient client,
301 SilcSocketConnection sock,
302 SilcPacketContext *packet);
303 void silc_client_key_agreement(SilcClient client,
304 SilcSocketConnection sock,
305 SilcPacketContext *packet);
306 void silc_client_notify_by_server(SilcClient client,
307 SilcSocketConnection sock,
308 SilcPacketContext *packet);
309 void silc_client_private_message(SilcClient client,
310 SilcSocketConnection sock,
311 SilcPacketContext *packet);
312 void silc_client_connection_auth_request(SilcClient client,
313 SilcSocketConnection sock,
314 SilcPacketContext *packet);
315 void silc_client_ftp(SilcClient client,
316 SilcSocketConnection sock,
317 SilcPacketContext *packet);