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_send;
89   SilcHmac hmac_receive;
90   SilcHash hash;
91
92   /* Client ID and Channel ID cache. Messages transmitted in SILC network
93      are done using different unique ID's. These are the cache for
94      thoses ID's used in the communication. */
95   SilcIDCache client_cache;
96   SilcIDCache channel_cache;
97   SilcIDCache server_cache;
98
99   /* Current channel on window. All channels are saved (allocated) into
100      the cache entries. */
101   SilcChannelEntry current_channel;
102
103   /* Socket connection object for this connection (window). This
104      object will have a back-pointer to this window object for fast
105      referencing (sock->user_data). */
106   SilcSocketConnection sock;
107
108   /* Pending command queue for this connection */
109   SilcDList pending_commands;
110
111   /* Current command identifier, 0 not used */
112   uint16 cmd_ident;
113
114   /* Requested pings. */
115   SilcClientPing *ping;
116   uint32 ping_count;
117
118   /* Set away message */
119   SilcClientAway *away;
120
121   /* Re-key context */
122   SilcClientRekey rekey;
123
124   /* Pointer back to the SilcClient. This object is passed to the application
125      and the actual client object is accesible through this pointer. */
126   SilcClient client;
127
128   /* User data context. Library does not touch this. */
129   void *context;
130 };
131
132 /* Main client structure. */
133 struct SilcClientStruct {
134   /*
135    * Public data. All the following pointers must be set by the allocator
136    * of this structure.
137    */
138
139   /* Users's username, hostname and realname. */
140   char *username;
141   char *hostname;
142   char *realname;
143
144   /* Private and public key of the user. */
145   SilcPKCS pkcs;
146   SilcPublicKey public_key;
147   SilcPrivateKey private_key;
148
149   /* Application specific user data pointer. Client library does not
150      touch this. */
151   void *application;
152
153   /*
154    * Private data. Following pointers are used internally by the client
155    * library and should be considered read-only fields.
156    */
157
158   /* All client operations that are implemented in the application. */
159   SilcClientOperations *ops;
160
161   /* Client Parameters */
162   SilcClientParams *params;
163
164   /* SILC client scheduler and task queues */
165   SilcSchedule schedule;
166   SilcTaskQueue io_queue;
167   SilcTaskQueue timeout_queue;
168   SilcTaskQueue generic_queue;
169
170   /* Table of connections in client. All the connection data is saved here. */
171   SilcClientConnection *conns;
172   uint32 conns_count;
173
174   /* Table of listenning sockets in client.  Client can have listeners
175      (like key agreement protocol server) and those sockets are saved here.
176      This table is checked always if the connection object cannot be found
177      from the `conns' table. */
178   SilcSocketConnection *sockets;
179   uint32 sockets_count;
180
181   /* Generic cipher and hash objects. These can be used and referenced
182      by the application as well. */
183   SilcCipher none_cipher;
184   SilcHash md5hash;
185   SilcHash sha1hash;
186   SilcHmac md5hmac;
187   SilcHmac sha1hmac;
188
189   /* Random Number Generator. Application should use this as its primary
190      random number generator. */
191   SilcRng rng;
192
193   /* Client version. Used to compare to remote host's version strings. */
194   char *silc_client_version;
195 };
196
197 /* Macros */
198
199 /* Registers generic task for file descriptor for reading from network and
200    writing to network. As being generic task the actual task is allocated 
201    only once and after that the same task applies to all registered fd's. */
202 #define SILC_CLIENT_REGISTER_CONNECTION_FOR_IO(fd)                      \
203 do {                                                                    \
204   SilcTask tmptask = silc_task_register(client->generic_queue, (fd),    \
205                                         silc_client_packet_process,     \
206                                         context, 0, 0,                  \
207                                         SILC_TASK_GENERIC,              \
208                                         SILC_TASK_PRI_NORMAL);          \
209   silc_task_set_iotype(tmptask, SILC_TASK_WRITE);                       \
210 } while(0)
211
212 #define SILC_CLIENT_SET_CONNECTION_FOR_INPUT(s, fd)                     \
213 do {                                                                    \
214   silc_schedule_set_listen_fd((s), (fd), (1L << SILC_TASK_READ));       \
215 } while(0)
216      
217 #define SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT(s, fd)                    \
218 do {                                                                    \
219   silc_schedule_set_listen_fd((s), (fd), ((1L << SILC_TASK_READ) |      \
220                                      (1L << SILC_TASK_WRITE)));         \
221 } while(0)
222
223 /* Finds socket connection object by file descriptor */
224 #define SILC_CLIENT_GET_SOCK(__x, __fd, __sock)         \
225 do {                                                    \
226   int __i;                                              \
227                                                         \
228   for (__i = 0; __i < (__x)->conns_count; __i++)        \
229     if ((__x)->conns[__i] &&                            \
230         (__x)->conns[__i]->sock->sock == (__fd))        \
231       break;                                            \
232                                                         \
233   if (__i >= (__x)->conns_count) {                      \
234     (__sock) = NULL;                                    \
235     for (__i = 0; __i < (__x)->sockets_count; __i++)    \
236       if ((__x)->sockets[__i] &&                        \
237           (__x)->sockets[__i]->sock == (__fd))          \
238         (__sock) = (__x)->sockets[__i];                 \
239   } else                                                \
240     (__sock) = (__x)->conns[__i]->sock;                 \
241 } while(0)
242
243 /* Check whether rekey protocol is active */
244 #define SILC_CLIENT_IS_REKEY(sock)                                      \
245   (sock->protocol && sock->protocol->protocol &&                        \
246    sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY)
247
248 /* Prototypes (some of the prototypes are defined in the silcapi.h) */
249
250 void silc_client_packet_send(SilcClient client, 
251                              SilcSocketConnection sock,
252                              SilcPacketType type, 
253                              void *dst_id,
254                              SilcIdType dst_id_type,
255                              SilcCipher cipher,
256                              SilcHmac hmac,
257                              unsigned char *data, 
258                              uint32 data_len, 
259                              int force_send);
260 void silc_client_disconnected_by_server(SilcClient client,
261                                         SilcSocketConnection sock,
262                                         SilcBuffer message);
263 void silc_client_error_by_server(SilcClient client,
264                                  SilcSocketConnection sock,
265                                  SilcBuffer message);
266 void silc_client_receive_new_id(SilcClient client,
267                                 SilcSocketConnection sock,
268                                 SilcIDPayload idp);
269 SilcChannelEntry silc_client_new_channel_id(SilcClient client,
270                                             SilcSocketConnection sock,
271                                             char *channel_name,
272                                             uint32 mode, 
273                                             SilcIDPayload idp);
274 void silc_client_save_channel_key(SilcClientConnection conn,
275                                   SilcBuffer key_payload, 
276                                   SilcChannelEntry channel);
277 void silc_client_receive_channel_key(SilcClient client,
278                                      SilcSocketConnection sock,
279                                      SilcBuffer packet);
280 void silc_client_channel_message(SilcClient client, 
281                                  SilcSocketConnection sock, 
282                                  SilcPacketContext *packet);
283 void silc_client_remove_from_channels(SilcClient client,
284                                       SilcClientConnection conn,
285                                       SilcClientEntry client_entry);
286 void silc_client_replace_from_channels(SilcClient client, 
287                                        SilcClientConnection conn,
288                                        SilcClientEntry old,
289                                        SilcClientEntry new);
290 void silc_client_process_failure(SilcClient client,
291                                  SilcSocketConnection sock,
292                                  SilcPacketContext *packet);
293 void silc_client_key_agreement(SilcClient client,
294                                SilcSocketConnection sock,
295                                SilcPacketContext *packet);
296 void silc_client_notify_by_server(SilcClient client,
297                                   SilcSocketConnection sock,
298                                   SilcPacketContext *packet);
299 void silc_client_private_message(SilcClient client, 
300                                  SilcSocketConnection sock, 
301                                  SilcPacketContext *packet);
302
303 #endif