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;
30 typedef struct SilcClientFtpSessionStruct *SilcClientFtpSession;
36 /* Generic rekey context for connections */
38 /* Current sending encryption key, provided for re-key. The `pfs'
39 is TRUE if the Perfect Forward Secrecy is performed in re-key. */
40 unsigned char *send_enc_key;
48 /* Context to hold the connection authentication request callbacks that
49 will be called when the server has replied back to our request about
50 current authentication method in the session. */
52 SilcConnectionAuthRequest callback;
55 } *SilcClientConnAuthRequest;
57 /* Connection structure used in client to associate all the important
58 connection specific data to this structure. */
59 struct SilcClientConnectionStruct {
65 /* Local client ID for this connection */
66 SilcClientID *local_id;
68 /* Decoded local ID so that the above defined ID would not have
69 to be decoded for every packet. */
70 unsigned char *local_id_data;
71 uint32 local_id_data_len;
73 /* Own client entry. */
74 SilcClientEntry local_entry;
84 /* Remote server ID for this connection */
85 SilcServerID *remote_id;
87 /* Decoded remote ID so that the above defined ID would not have
88 to be decoded for every packet. */
89 unsigned char *remote_id_data;
90 uint32 remote_id_data_len;
95 /* Keys and stuff negotiated in the SKE protocol */
97 SilcCipher receive_key;
99 SilcHmac hmac_receive;
104 /* Client ID and Channel ID cache. Messages transmitted in SILC network
105 are done using different unique ID's. These are the cache for
106 thoses ID's used in the communication. */
107 SilcIDCache client_cache;
108 SilcIDCache channel_cache;
109 SilcIDCache server_cache;
111 /* Current channel on window. All channels are saved (allocated) into
112 the cache entries. */
113 SilcChannelEntry current_channel;
115 /* Socket connection object for this connection (window). This
116 object will have a back-pointer to this window object for fast
117 referencing (sock->user_data). */
118 SilcSocketConnection sock;
120 /* Pending command queue for this connection */
121 SilcDList pending_commands;
123 /* Current command identifier, 0 not used */
126 /* Requested pings. */
127 SilcClientPing *ping;
130 /* Set away message */
131 SilcClientAway *away;
134 SilcClientRekey rekey;
136 /* Authentication request context. */
137 SilcClientConnAuthRequest connauth;
139 /* File transmission sessions */
140 SilcDList ftp_sessions;
141 uint32 next_session_id;
142 SilcClientFtpSession active_session;
144 /* Pointer back to the SilcClient. This object is passed to the application
145 and the actual client object is accesible through this pointer. */
148 /* User data context. Library does not touch this. */
152 /* Main client structure. */
153 struct SilcClientStruct {
155 * Public data. All the following pointers must be set by the allocator
159 /* Users's username, hostname and realname. */
164 /* Private and public key of the user. */
166 SilcPublicKey public_key;
167 SilcPrivateKey private_key;
169 /* Application specific user data pointer. Client library does not
174 * Private data. Following pointers are used internally by the client
175 * library and should be considered read-only fields.
178 /* All client operations that are implemented in the application. */
179 SilcClientOperations *ops;
181 /* Client Parameters */
182 SilcClientParams *params;
184 /* SILC client scheduler */
185 SilcSchedule schedule;
187 /* Table of connections in client. All the connection data is saved here. */
188 SilcClientConnection *conns;
191 /* Table of listenning sockets in client. Client can have listeners
192 (like key agreement protocol server) and those sockets are saved here.
193 This table is checked always if the connection object cannot be found
194 from the `conns' table. */
195 SilcSocketConnection *sockets;
196 uint32 sockets_count;
198 /* Generic cipher and hash objects. These can be used and referenced
199 by the application as well. */
200 SilcCipher none_cipher;
206 /* Random Number Generator. Application should use this as its primary
207 random number generator. */
210 /* Client version. Used to compare to remote host's version strings. */
211 char *silc_client_version;
216 /* Registers generic task for file descriptor for reading from network and
217 writing to network. As being generic task the actual task is allocated
218 only once and after that the same task applies to all registered fd's. */
219 #define SILC_CLIENT_REGISTER_CONNECTION_FOR_IO(fd) \
221 silc_schedule_task_add(client->schedule, (fd), \
222 silc_client_packet_process, \
225 SILC_TASK_PRI_NORMAL); \
228 #define SILC_CLIENT_SET_CONNECTION_FOR_INPUT(s, fd) \
230 silc_schedule_set_listen_fd((s), (fd), SILC_TASK_READ); \
233 #define SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT(s, fd) \
235 silc_schedule_set_listen_fd((s), (fd), (SILC_TASK_READ | \
239 /* Finds socket connection object by file descriptor */
240 #define SILC_CLIENT_GET_SOCK(__x, __fd, __sock) \
244 for (__i = 0; __i < (__x)->conns_count; __i++) \
245 if ((__x)->conns[__i] && \
246 (__x)->conns[__i]->sock->sock == (__fd)) \
249 if (__i >= (__x)->conns_count) { \
251 for (__i = 0; __i < (__x)->sockets_count; __i++) \
252 if ((__x)->sockets[__i] && \
253 (__x)->sockets[__i]->sock == (__fd)) \
254 (__sock) = (__x)->sockets[__i]; \
256 (__sock) = (__x)->conns[__i]->sock; \
259 /* Check whether rekey protocol is active */
260 #define SILC_CLIENT_IS_REKEY(sock) \
261 (sock->protocol && sock->protocol->protocol && \
262 sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY)
264 /* Prototypes (some of the prototypes are defined in the silcapi.h) */
266 void silc_client_packet_send(SilcClient client,
267 SilcSocketConnection sock,
270 SilcIdType dst_id_type,
276 void silc_client_disconnected_by_server(SilcClient client,
277 SilcSocketConnection sock,
279 void silc_client_error_by_server(SilcClient client,
280 SilcSocketConnection sock,
282 void silc_client_receive_new_id(SilcClient client,
283 SilcSocketConnection sock,
285 SilcChannelEntry silc_client_new_channel_id(SilcClient client,
286 SilcSocketConnection sock,
290 void silc_client_save_channel_key(SilcClientConnection conn,
291 SilcBuffer key_payload,
292 SilcChannelEntry channel);
293 void silc_client_receive_channel_key(SilcClient client,
294 SilcSocketConnection sock,
296 void silc_client_channel_message(SilcClient client,
297 SilcSocketConnection sock,
298 SilcPacketContext *packet);
299 void silc_client_remove_from_channels(SilcClient client,
300 SilcClientConnection conn,
301 SilcClientEntry client_entry);
302 void silc_client_replace_from_channels(SilcClient client,
303 SilcClientConnection conn,
305 SilcClientEntry newclient);
306 void silc_client_process_failure(SilcClient client,
307 SilcSocketConnection sock,
308 SilcPacketContext *packet);
309 void silc_client_key_agreement(SilcClient client,
310 SilcSocketConnection sock,
311 SilcPacketContext *packet);
312 void silc_client_notify_by_server(SilcClient client,
313 SilcSocketConnection sock,
314 SilcPacketContext *packet);
315 void silc_client_private_message(SilcClient client,
316 SilcSocketConnection sock,
317 SilcPacketContext *packet);
318 void silc_client_connection_auth_request(SilcClient client,
319 SilcSocketConnection sock,
320 SilcPacketContext *packet);
321 void silc_client_ftp(SilcClient client,
322 SilcSocketConnection sock,
323 SilcPacketContext *packet);