updates.
[silc.git] / lib / silcclient / client.h
1 /*
2
3   client.h
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 1997 - 2001 Pekka Riikonen
8
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.
13   
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.
18
19 */
20
21 #ifndef CLIENT_H
22 #define CLIENT_H
23
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
31 #include "idlist.h"
32 #include "command.h"
33 #include "silcapi.h"
34
35 /* Generic rekey context for connections */
36 typedef struct {
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;
40   uint32 enc_key_len;
41   int ske_group;
42   bool pfs;
43   uint32 timeout;
44   void *context;
45 } *SilcClientRekey;
46
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. */
50 typedef struct {
51   SilcConnectionAuthRequest callback;
52   void *context;
53   SilcTask timeout;
54 } *SilcClientConnAuthRequest;
55
56 /* Connection structure used in client to associate all the important
57    connection specific data to this structure. */
58 struct SilcClientConnectionStruct {
59   /*
60    * Local data 
61    */
62   char *nickname;
63
64   /* Local client ID for this connection */
65   SilcClientID *local_id;
66
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;
71
72   /* Own client entry. */
73   SilcClientEntry local_entry;
74
75   /*
76    * Remote data 
77    */
78   char *remote_host;
79   int remote_port;
80   int remote_type;
81   char *remote_info;
82
83   /* Remote server ID for this connection */
84   SilcServerID *remote_id;
85
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;
90
91   /*
92    * Common data 
93    */
94   /* Keys and stuff negotiated in the SKE protocol */
95   SilcCipher send_key;
96   SilcCipher receive_key;
97   SilcHmac hmac_send;
98   SilcHmac hmac_receive;
99   SilcHash hash;
100
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;
107
108   /* Current channel on window. All channels are saved (allocated) into
109      the cache entries. */
110   SilcChannelEntry current_channel;
111
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;
116
117   /* Pending command queue for this connection */
118   SilcDList pending_commands;
119
120   /* Current command identifier, 0 not used */
121   uint16 cmd_ident;
122
123   /* Requested pings. */
124   SilcClientPing *ping;
125   uint32 ping_count;
126
127   /* Set away message */
128   SilcClientAway *away;
129
130   /* Re-key context */
131   SilcClientRekey rekey;
132
133   /* Authentication request context. */
134   SilcClientConnAuthRequest connauth;
135
136   /* Pointer back to the SilcClient. This object is passed to the application
137      and the actual client object is accesible through this pointer. */
138   SilcClient client;
139
140   /* User data context. Library does not touch this. */
141   void *context;
142 };
143
144 /* Main client structure. */
145 struct SilcClientStruct {
146   /*
147    * Public data. All the following pointers must be set by the allocator
148    * of this structure.
149    */
150
151   /* Users's username, hostname and realname. */
152   char *username;
153   char *hostname;
154   char *realname;
155
156   /* Private and public key of the user. */
157   SilcPKCS pkcs;
158   SilcPublicKey public_key;
159   SilcPrivateKey private_key;
160
161   /* Application specific user data pointer. Client library does not
162      touch this. */
163   void *application;
164
165   /*
166    * Private data. Following pointers are used internally by the client
167    * library and should be considered read-only fields.
168    */
169
170   /* All client operations that are implemented in the application. */
171   SilcClientOperations *ops;
172
173   /* Client Parameters */
174   SilcClientParams *params;
175
176   /* SILC client scheduler */
177   SilcSchedule schedule;
178
179   /* Table of connections in client. All the connection data is saved here. */
180   SilcClientConnection *conns;
181   uint32 conns_count;
182
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;
189
190   /* Generic cipher and hash objects. These can be used and referenced
191      by the application as well. */
192   SilcCipher none_cipher;
193   SilcHash md5hash;
194   SilcHash sha1hash;
195   SilcHmac md5hmac;
196   SilcHmac sha1hmac;
197
198   /* Random Number Generator. Application should use this as its primary
199      random number generator. */
200   SilcRng rng;
201
202   /* Client version. Used to compare to remote host's version strings. */
203   char *silc_client_version;
204 };
205
206 /* Macros */
207
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)      \
212 do {                                                    \
213   silc_schedule_task_add(client->schedule, (fd),        \
214                          silc_client_packet_process,    \
215                          context, 0, 0,                 \
216                          SILC_TASK_GENERIC,             \
217                          SILC_TASK_PRI_NORMAL);         \
218 } while(0)
219
220 #define SILC_CLIENT_SET_CONNECTION_FOR_INPUT(s, fd)             \
221 do {                                                            \
222   silc_schedule_set_listen_fd((s), (fd), SILC_TASK_READ);       \
223 } while(0)
224      
225 #define SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT(s, fd)            \
226 do {                                                            \
227   silc_schedule_set_listen_fd((s), (fd), (SILC_TASK_READ |      \
228                                           SILC_TASK_WRITE));    \
229 } while(0)
230
231 /* Finds socket connection object by file descriptor */
232 #define SILC_CLIENT_GET_SOCK(__x, __fd, __sock)         \
233 do {                                                    \
234   int __i;                                              \
235                                                         \
236   for (__i = 0; __i < (__x)->conns_count; __i++)        \
237     if ((__x)->conns[__i] &&                            \
238         (__x)->conns[__i]->sock->sock == (__fd))        \
239       break;                                            \
240                                                         \
241   if (__i >= (__x)->conns_count) {                      \
242     (__sock) = NULL;                                    \
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];                 \
247   } else                                                \
248     (__sock) = (__x)->conns[__i]->sock;                 \
249 } while(0)
250
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)
255
256 /* Prototypes (some of the prototypes are defined in the silcapi.h) */
257
258 void silc_client_packet_send(SilcClient client, 
259                              SilcSocketConnection sock,
260                              SilcPacketType type, 
261                              void *dst_id,
262                              SilcIdType dst_id_type,
263                              SilcCipher cipher,
264                              SilcHmac hmac,
265                              unsigned char *data, 
266                              uint32 data_len, 
267                              int force_send);
268 void silc_client_disconnected_by_server(SilcClient client,
269                                         SilcSocketConnection sock,
270                                         SilcBuffer message);
271 void silc_client_error_by_server(SilcClient client,
272                                  SilcSocketConnection sock,
273                                  SilcBuffer message);
274 void silc_client_receive_new_id(SilcClient client,
275                                 SilcSocketConnection sock,
276                                 SilcIDPayload idp);
277 SilcChannelEntry silc_client_new_channel_id(SilcClient client,
278                                             SilcSocketConnection sock,
279                                             char *channel_name,
280                                             uint32 mode, 
281                                             SilcIDPayload idp);
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,
287                                      SilcBuffer packet);
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,
296                                        SilcClientEntry old,
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);
313 void silc_client_ftp(SilcClient client,
314                      SilcSocketConnection sock,
315                      SilcPacketContext *packet);
316 #endif