d8bee7ad186bcf52747812ae46bb0382767be9d6
[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 typedef struct SilcClientFtpSessionStruct *SilcClientFtpSession;
31
32 #include "idlist.h"
33 #include "command.h"
34 #include "silcapi.h"
35
36 /* Generic rekey context for connections */
37 typedef struct {
38   /* Current sending encryption key, provided for re-key. The `pfs'
39      is TRUE if the Perfect Forward Secrecy is performed in re-key. */
40   unsigned char *send_enc_key;
41   uint32 enc_key_len;
42   int ske_group;
43   bool pfs;
44   uint32 timeout;
45   void *context;
46 } *SilcClientRekey;
47
48 /* Context to hold the connection authentication request callbacks that
49    will be called when the server has replied back to our request about
50    current authentication method in the session. */
51 typedef struct {
52   SilcConnectionAuthRequest callback;
53   void *context;
54   SilcTask timeout;
55 } *SilcClientConnAuthRequest;
56
57 /* Connection structure used in client to associate all the important
58    connection specific data to this structure. */
59 struct SilcClientConnectionStruct {
60   /*
61    * Local data 
62    */
63   char *nickname;
64
65   /* Local client ID for this connection */
66   SilcClientID *local_id;
67
68   /* Decoded local ID so that the above defined ID would not have
69      to be decoded for every packet. */
70   unsigned char *local_id_data;
71   uint32 local_id_data_len;
72
73   /* Own client entry. */
74   SilcClientEntry local_entry;
75
76   /*
77    * Remote data 
78    */
79   char *remote_host;
80   int remote_port;
81   int remote_type;
82   char *remote_info;
83
84   /* Remote server ID for this connection */
85   SilcServerID *remote_id;
86
87   /* Decoded remote ID so that the above defined ID would not have
88      to be decoded for every packet. */
89   unsigned char *remote_id_data;
90   uint32 remote_id_data_len;
91
92   /*
93    * Common data 
94    */
95   /* Keys and stuff negotiated in the SKE protocol */
96   SilcCipher send_key;
97   SilcCipher receive_key;
98   SilcHmac hmac_send;
99   SilcHmac hmac_receive;
100   SilcHash hash;
101   uint32 psn_send;
102   uint32 psn_receive;
103
104   /* Client ID and Channel ID cache. Messages transmitted in SILC network
105      are done using different unique ID's. These are the cache for
106      thoses ID's used in the communication. */
107   SilcIDCache client_cache;
108   SilcIDCache channel_cache;
109   SilcIDCache server_cache;
110
111   /* Current channel on window. All channels are saved (allocated) into
112      the cache entries. */
113   SilcChannelEntry current_channel;
114
115   /* Socket connection object for this connection (window). This
116      object will have a back-pointer to this window object for fast
117      referencing (sock->user_data). */
118   SilcSocketConnection sock;
119
120   /* Pending command queue for this connection */
121   SilcDList pending_commands;
122
123   /* Current command identifier, 0 not used */
124   uint16 cmd_ident;
125
126   /* Requested pings. */
127   SilcClientPing *ping;
128   uint32 ping_count;
129
130   /* Set away message */
131   SilcClientAway *away;
132
133   /* Re-key context */
134   SilcClientRekey rekey;
135
136   /* Authentication request context. */
137   SilcClientConnAuthRequest connauth;
138
139   /* File transmission sessions */
140   SilcDList ftp_sessions;
141   uint32 next_session_id;
142   SilcClientFtpSession active_session;
143
144   /* Pointer back to the SilcClient. This object is passed to the application
145      and the actual client object is accesible through this pointer. */
146   SilcClient client;
147
148   /* User data context. Library does not touch this. */
149   void *context;
150 };
151
152 /* Main client structure. */
153 struct SilcClientStruct {
154   /*
155    * Public data. All the following pointers must be set by the allocator
156    * of this structure.
157    */
158
159   /* Users's username, hostname and realname. */
160   char *username;
161   char *hostname;
162   char *realname;
163
164   /* Private and public key of the user. */
165   SilcPKCS pkcs;
166   SilcPublicKey public_key;
167   SilcPrivateKey private_key;
168
169   /* Application specific user data pointer. Client library does not
170      touch this. */
171   void *application;
172
173   /*
174    * Private data. Following pointers are used internally by the client
175    * library and should be considered read-only fields.
176    */
177
178   /* All client operations that are implemented in the application. */
179   SilcClientOperations *ops;
180
181   /* Client Parameters */
182   SilcClientParams *params;
183
184   /* SILC client scheduler */
185   SilcSchedule schedule;
186
187   /* Table of connections in client. All the connection data is saved here. */
188   SilcClientConnection *conns;
189   uint32 conns_count;
190
191   /* Table of listenning sockets in client.  Client can have listeners
192      (like key agreement protocol server) and those sockets are saved here.
193      This table is checked always if the connection object cannot be found
194      from the `conns' table. */
195   SilcSocketConnection *sockets;
196   uint32 sockets_count;
197
198   /* Generic cipher and hash objects. These can be used and referenced
199      by the application as well. */
200   SilcCipher none_cipher;
201   SilcHash md5hash;
202   SilcHash sha1hash;
203   SilcHmac md5hmac;
204   SilcHmac sha1hmac;
205
206   /* Random Number Generator. Application should use this as its primary
207      random number generator. */
208   SilcRng rng;
209
210   /* Client version. Used to compare to remote host's version strings. */
211   char *silc_client_version;
212 };
213
214 /* Macros */
215
216 /* Registers generic task for file descriptor for reading from network and
217    writing to network. As being generic task the actual task is allocated 
218    only once and after that the same task applies to all registered fd's. */
219 #define SILC_CLIENT_REGISTER_CONNECTION_FOR_IO(fd)      \
220 do {                                                    \
221   silc_schedule_task_add(client->schedule, (fd),        \
222                          silc_client_packet_process,    \
223                          context, 0, 0,                 \
224                          SILC_TASK_GENERIC,             \
225                          SILC_TASK_PRI_NORMAL);         \
226 } while(0)
227
228 #define SILC_CLIENT_SET_CONNECTION_FOR_INPUT(s, fd)             \
229 do {                                                            \
230   silc_schedule_set_listen_fd((s), (fd), SILC_TASK_READ);       \
231 } while(0)
232      
233 #define SILC_CLIENT_SET_CONNECTION_FOR_OUTPUT(s, fd)            \
234 do {                                                            \
235   silc_schedule_set_listen_fd((s), (fd), (SILC_TASK_READ |      \
236                                           SILC_TASK_WRITE));    \
237 } while(0)
238
239 /* Finds socket connection object by file descriptor */
240 #define SILC_CLIENT_GET_SOCK(__x, __fd, __sock)         \
241 do {                                                    \
242   int __i;                                              \
243                                                         \
244   for (__i = 0; __i < (__x)->conns_count; __i++)        \
245     if ((__x)->conns[__i] &&                            \
246         (__x)->conns[__i]->sock->sock == (__fd))        \
247       break;                                            \
248                                                         \
249   if (__i >= (__x)->conns_count) {                      \
250     (__sock) = NULL;                                    \
251     for (__i = 0; __i < (__x)->sockets_count; __i++)    \
252       if ((__x)->sockets[__i] &&                        \
253           (__x)->sockets[__i]->sock == (__fd))          \
254         (__sock) = (__x)->sockets[__i];                 \
255   } else                                                \
256     (__sock) = (__x)->conns[__i]->sock;                 \
257 } while(0)
258
259 /* Check whether rekey protocol is active */
260 #define SILC_CLIENT_IS_REKEY(sock)                                      \
261   (sock->protocol && sock->protocol->protocol &&                        \
262    sock->protocol->protocol->type == SILC_PROTOCOL_CLIENT_REKEY)
263
264 /* Prototypes (some of the prototypes are defined in the silcapi.h) */
265
266 void silc_client_packet_send(SilcClient client, 
267                              SilcSocketConnection sock,
268                              SilcPacketType type, 
269                              void *dst_id,
270                              SilcIdType dst_id_type,
271                              SilcCipher cipher,
272                              SilcHmac hmac,
273                              unsigned char *data, 
274                              uint32 data_len, 
275                              int force_send);
276 void silc_client_disconnected_by_server(SilcClient client,
277                                         SilcSocketConnection sock,
278                                         SilcBuffer message);
279 void silc_client_error_by_server(SilcClient client,
280                                  SilcSocketConnection sock,
281                                  SilcBuffer message);
282 void silc_client_receive_new_id(SilcClient client,
283                                 SilcSocketConnection sock,
284                                 SilcIDPayload idp);
285 SilcChannelEntry silc_client_new_channel_id(SilcClient client,
286                                             SilcSocketConnection sock,
287                                             char *channel_name,
288                                             uint32 mode, 
289                                             SilcIDPayload idp);
290 void silc_client_save_channel_key(SilcClientConnection conn,
291                                   SilcBuffer key_payload, 
292                                   SilcChannelEntry channel);
293 void silc_client_receive_channel_key(SilcClient client,
294                                      SilcSocketConnection sock,
295                                      SilcBuffer packet);
296 void silc_client_channel_message(SilcClient client, 
297                                  SilcSocketConnection sock, 
298                                  SilcPacketContext *packet);
299 void silc_client_remove_from_channels(SilcClient client,
300                                       SilcClientConnection conn,
301                                       SilcClientEntry client_entry);
302 void silc_client_replace_from_channels(SilcClient client, 
303                                        SilcClientConnection conn,
304                                        SilcClientEntry old,
305                                        SilcClientEntry newclient);
306 void silc_client_process_failure(SilcClient client,
307                                  SilcSocketConnection sock,
308                                  SilcPacketContext *packet);
309 void silc_client_key_agreement(SilcClient client,
310                                SilcSocketConnection sock,
311                                SilcPacketContext *packet);
312 void silc_client_notify_by_server(SilcClient client,
313                                   SilcSocketConnection sock,
314                                   SilcPacketContext *packet);
315 void silc_client_private_message(SilcClient client, 
316                                  SilcSocketConnection sock, 
317                                  SilcPacketContext *packet);
318 void silc_client_connection_auth_request(SilcClient client,
319                                          SilcSocketConnection sock,
320                                          SilcPacketContext *packet);
321 void silc_client_ftp(SilcClient client,
322                      SilcSocketConnection sock,
323                      SilcPacketContext *packet);
324 #endif