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