updates.
[silc.git] / lib / silcclient / client.h
1 /*
2
3   client.h
4
5   Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
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 /* Connection structure used in client to associate all the important
48    connection specific data to this structure. */
49 struct SilcClientConnectionStruct {
50   /*
51    * Local data 
52    */
53   char *nickname;
54
55   /* Local client ID for this connection */
56   SilcClientID *local_id;
57
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;
62
63   /* Own client entry. */
64   SilcClientEntry local_entry;
65
66   /*
67    * Remote data 
68    */
69   char *remote_host;
70   int remote_port;
71   int remote_type;
72   char *remote_info;
73
74   /* Remote server ID for this connection */
75   SilcServerID *remote_id;
76
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;
81
82   /*
83    * Common data 
84    */
85   /* Keys and stuff negotiated in the SKE protocol */
86   SilcCipher send_key;
87   SilcCipher receive_key;
88   SilcHmac hmac;
89   SilcHash hash;
90
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;
97
98   /* Current channel on window. All channels are saved (allocated) into
99      the cache entries. */
100   SilcChannelEntry current_channel;
101
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;
106
107   /* Pending command queue for this connection */
108   SilcDList pending_commands;
109
110   /* Current command identifier, 0 not used */
111   uint16 cmd_ident;
112
113   /* Requested pings. */
114   SilcClientPing *ping;
115   uint32 ping_count;
116
117   /* Set away message */
118   SilcClientAway *away;
119
120   /* Re-key context */
121   SilcClientRekey rekey;
122
123   /* Pointer back to the SilcClient. This object is passed to the application
124      and the actual client object is accesible through this pointer. */
125   SilcClient client;
126
127   /* User data context. Library does not touch this. */
128   void *context;
129 };
130
131 /* Main client structure. */
132 struct SilcClientStruct {
133   /*
134    * Public data. All the following pointers must be set by the allocator
135    * of this structure.
136    */
137
138   /* Users's username, hostname and realname. */
139   char *username;
140   char *hostname;
141   char *realname;
142
143   /* Private and public key of the user. */
144   SilcPKCS pkcs;
145   SilcPublicKey public_key;
146   SilcPrivateKey private_key;
147
148   /* Application specific user data pointer. Client library does not
149      touch this. */
150   void *application;
151
152   /*
153    * Private data. Following pointers are used internally by the client
154    * library and should be considered read-only fields.
155    */
156
157   /* All client operations that are implemented in the application. */
158   SilcClientOperations *ops;
159
160   /* SILC client task queues */
161   SilcTaskQueue io_queue;
162   SilcTaskQueue timeout_queue;
163   SilcTaskQueue generic_queue;
164
165   /* Table of connections in client. All the connection data is saved here. */
166   SilcClientConnection *conns;
167   uint32 conns_count;
168
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;
175
176   /* Generic cipher and hash objects. These can be used and referenced
177      by the application as well. */
178   SilcCipher none_cipher;
179   SilcHash md5hash;
180   SilcHash sha1hash;
181   SilcHmac md5hmac;
182   SilcHmac sha1hmac;
183
184   /* Random Number Generator. Application should use this as its primary
185      random number generator. */
186   SilcRng rng;
187 };
188
189 /* Macros */
190
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)                      \
195 do {                                                                    \
196   SilcTask tmptask = silc_task_register(client->generic_queue, (fd),    \
197                                         silc_client_packet_process,     \
198                                         context, 0, 0,                  \
199                                         SILC_TASK_GENERIC,              \
200                                         SILC_TASK_PRI_NORMAL);          \
201   silc_task_set_iotype(tmptask, SILC_TASK_WRITE);                       \
202 } while(0)
203
204 #define SILC_CLIENT_SET_CONNECTION_FOR_INPUT(fd)                \
205 do {                                                            \
206   silc_schedule_set_listen_fd((fd), (1L << SILC_TASK_READ));    \
207 } while(0)                                                      \
208      
209 #define SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT(fd)               \
210 do {                                                            \
211   silc_schedule_set_listen_fd((fd), ((1L << SILC_TASK_READ) |   \
212                                      (1L << SILC_TASK_WRITE))); \
213 } while(0)
214
215 /* Finds socket connection object by file descriptor */
216 #define SILC_CLIENT_GET_SOCK(__x, __fd, __sock)         \
217 do {                                                    \
218   int __i;                                              \
219                                                         \
220   for (__i = 0; __i < (__x)->conns_count; __i++)        \
221     if ((__x)->conns[__i] &&                            \
222         (__x)->conns[__i]->sock->sock == (__fd))        \
223       break;                                            \
224                                                         \
225   if (__i >= (__x)->conns_count) {                      \
226     (__sock) = NULL;                                    \
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];                 \
231   } else                                                \
232     (__sock) = (__x)->conns[__i]->sock;                 \
233 } while(0)
234
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)
239
240 /* Prototypes (some of the prototypes are defined in the silcapi.h) */
241
242 void silc_client_packet_send(SilcClient client, 
243                              SilcSocketConnection sock,
244                              SilcPacketType type, 
245                              void *dst_id,
246                              SilcIdType dst_id_type,
247                              SilcCipher cipher,
248                              SilcHmac hmac,
249                              unsigned char *data, 
250                              uint32 data_len, 
251                              int force_send);
252 void silc_client_disconnected_by_server(SilcClient client,
253                                         SilcSocketConnection sock,
254                                         SilcBuffer message);
255 void silc_client_error_by_server(SilcClient client,
256                                  SilcSocketConnection sock,
257                                  SilcBuffer message);
258 void silc_client_receive_new_id(SilcClient client,
259                                 SilcSocketConnection sock,
260                                 SilcIDPayload idp);
261 SilcChannelEntry silc_client_new_channel_id(SilcClient client,
262                                             SilcSocketConnection sock,
263                                             char *channel_name,
264                                             uint32 mode, 
265                                             SilcIDPayload idp);
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,
271                                      SilcBuffer packet);
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,
280                                        SilcClientEntry old,
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);
297 #endif