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 /* Prototypes (some of the prototypes are defined in the silcapi.h) */
236
237 void silc_client_packet_send(SilcClient client, 
238                              SilcSocketConnection sock,
239                              SilcPacketType type, 
240                              void *dst_id,
241                              SilcIdType dst_id_type,
242                              SilcCipher cipher,
243                              SilcHmac hmac,
244                              unsigned char *data, 
245                              uint32 data_len, 
246                              int force_send);
247 void silc_client_disconnected_by_server(SilcClient client,
248                                         SilcSocketConnection sock,
249                                         SilcBuffer message);
250 void silc_client_error_by_server(SilcClient client,
251                                  SilcSocketConnection sock,
252                                  SilcBuffer message);
253 void silc_client_receive_new_id(SilcClient client,
254                                 SilcSocketConnection sock,
255                                 SilcIDPayload idp);
256 SilcChannelEntry silc_client_new_channel_id(SilcClient client,
257                                             SilcSocketConnection sock,
258                                             char *channel_name,
259                                             uint32 mode, 
260                                             SilcIDPayload idp);
261 void silc_client_save_channel_key(SilcClientConnection conn,
262                                   SilcBuffer key_payload, 
263                                   SilcChannelEntry channel);
264 void silc_client_receive_channel_key(SilcClient client,
265                                      SilcSocketConnection sock,
266                                      SilcBuffer packet);
267 void silc_client_channel_message(SilcClient client, 
268                                  SilcSocketConnection sock, 
269                                  SilcPacketContext *packet);
270 void silc_client_remove_from_channels(SilcClient client,
271                                       SilcClientConnection conn,
272                                       SilcClientEntry client_entry);
273 void silc_client_replace_from_channels(SilcClient client, 
274                                        SilcClientConnection conn,
275                                        SilcClientEntry old,
276                                        SilcClientEntry new);
277 char *silc_client_chmode(uint32 mode, SilcChannelEntry channel);
278 char *silc_client_chumode(uint32 mode);
279 char *silc_client_chumode_char(uint32 mode);
280 void silc_client_process_failure(SilcClient client,
281                                  SilcSocketConnection sock,
282                                  SilcPacketContext *packet);
283 void silc_client_key_agreement(SilcClient client,
284                                SilcSocketConnection sock,
285                                SilcPacketContext *packet);
286 void silc_client_notify_by_server(SilcClient client,
287                                   SilcSocketConnection sock,
288                                   SilcPacketContext *packet);
289 void silc_client_private_message(SilcClient client, 
290                                  SilcSocketConnection sock, 
291                                  SilcPacketContext *packet);
292 #endif