New SILC PKCS API, enabling support for other public keys/certs.
[silc.git] / lib / silcserver / server_internal.h
1 /*
2
3   server_internal.h
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 1997 - 2005 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; version 2 of the License.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18 */
19
20 #ifndef SERVER_INTERNAL_H
21 #define SERVER_INTERNAL_H
22
23 #include "server_st_accept.h"
24 #include "server_st_connect.h"
25 #include "server_st_notify.h"
26 #include "server_st_query.h"
27 #include "server_st_command.h"
28 #include "server_st_command_reply.h"
29 #include "server_st_packet.h"
30
31 /* SILC port */
32 #define SILC_PORT 706
33
34 /* Server type */
35 typedef enum {
36   SILC_SERVER         = 0,
37   SILC_ROUTER         = 1,
38   SILC_BACKUP_ROUTER  = 2
39 } SilcServerType;
40
41 /* Forward declarations */
42 typedef struct SilcServerEntryStruct *SilcServerEntry;
43 typedef struct SilcClientEntryStruct *SilcClientEntry;
44 typedef struct SilcChannelEntryStruct *SilcChannelEntry;
45 typedef struct SilcServerCommandStruct *SilcServerCommand;
46 typedef struct SilcServerThreadStruct *SilcServerThread;
47
48 /* Pending command context */
49 typedef struct {
50   SilcFSMSemaStruct wait_reply;         /* Pending command signaller */
51   SilcServerCommand reply;              /* Command reply context */
52   SilcUInt16 cmd_ident;                 /* Command identifier */
53   SilcInt16 refcnt;                     /* Reference counter */
54 } *SilcServerPending;
55
56 /* Command state context.  This is used with both commands and command
57    replies.  When command or command reply is executed its state is saved
58    here while processing. */
59 struct SilcServerCommandStruct {
60   struct SilcServerCommandStruct *next;
61   SilcServerThread thread;              /* Server thread */
62   SilcPacket packet;                    /* Command packet */
63   SilcCommandPayload payload;           /* Command payload */
64   SilcServerPending pending;            /* Pending command context */
65 };
66
67 /* Entry data header.  Client and server entries has this as their first
68    field. */
69 typedef struct {
70   SilcConnectionType type;           /* Connection type */
71   SilcSKE ske;                       /* Key exchange protocol, for rekey */
72   SilcHash hash;                     /* Hash selected in SKE protocol */
73   SilcPublicKey public_key;          /* Public key */
74   unsigned char fingerprint[20];     /* SHA-1 fingerprint */
75
76   long last_receive;                 /* Time last received data */
77   long last_sent;                    /* Time last sent data */
78
79   unsigned long created;             /* Time when entry was created */
80
81   SilcUInt32 refcnt;                 /* Reference counter */
82
83   /* Flags */
84   unsigned int registered     : 1;   /* Set if registered to network */
85   unsigned int local          : 1;   /* Set if locally connected entry */
86   unsigned int resolving      : 1;   /* Set if entry data being resolved */
87   unsigned int resolved       : 1;   /* Set if entry data resolved */
88   unsigned int disabled       : 1;   /* Set if entry is disabled */
89   unsigned int resumed        : 1;   /* Set if entry resumed */
90   unsigned int resume_res     : 1;   /* Set if resolved while resuming */
91   unsigned int noattr         : 1;   /* Set if entry does not support
92                                         user attributes in WHOIS */
93 } *SilcEntryData, SilcEntryDataStruct;
94
95 /* Server entry */
96 struct SilcServerEntryStruct {
97   SilcEntryDataStruct data;          /* Entry data header */
98   SilcServerID id;                   /* Server ID */
99   char *server_name;                 /* Server name */
100   char *server_info;                 /* Server info */
101   char *motd;                        /* Message of the day */
102   SilcPacketStream stream;           /* Connection to entry/origin of entry */
103   SilcUInt8 server_type;             /* Server type */
104 };
105
106 /* Client's joined channel entry */
107 typedef struct SilcChannelClientEntryStruct {
108   SilcClientEntry client;            /* Client on channel */
109   SilcChannelEntry channel;          /* Joined channel */
110   SilcUInt32 mode;                   /* Client's mode on channel */
111 } *SilcChannelClientEntry;
112
113 /* Client entry */
114 struct SilcClientEntryStruct {
115   SilcEntryDataStruct data;          /* Entry data header */
116   SilcClientID id;                   /* Client ID */
117   unsigned char *nickname;           /* Client's nickname (not normalized) */
118   char *servername;                  /* Client's server's name */
119   char *username;                    /* Client's username */
120   char *userinfo;                    /* Client's user info */
121   SilcUInt32 mode;                   /* Client's mode in the network */
122   unsigned char *attrs;              /* User attributes */
123   SilcUInt16 attrs_len;              /* Attributes data length */
124   SilcHashTable channels;            /* Joined channels */
125   SilcPacketStream stream;           /* Connection to entry/origin of entry */
126
127   long last_command;
128   SilcUInt8 fast_command;
129   unsigned long updated;
130
131   /* data.status is RESOLVING and this includes the resolving command
132      reply identifier. */
133   SilcUInt16 resolve_cmd_ident;
134
135   /* we need this so nobody can resume more than once at the same time -
136    * server crashes, really odd behaviour, ... */
137   SilcClientEntry resuming_client;
138 };
139
140 /* Channel entry */
141 struct SilcChannelEntryStruct {
142   SilcChannelID id;                  /* Channel ID */
143   char *channel_name;                /* Channel name */
144   SilcUInt32 mode;                   /* Channel's mode */
145   SilcPacketStream router;           /* Channel's owner */
146
147   unsigned char *passphrase;         /* Channel's passphrase */
148   SilcHashTable channel_pubkeys;     /* Channel authentication public keys */
149   SilcPublicKey founder_key;         /* Channel founder's public key */
150
151   char *topic;                       /* Current topic */
152   char *cipher;                      /* User set cipher */
153   char *hmac_name;                   /* User set HMAC */
154   SilcUInt32 user_limit;             /* Maximum user limit */
155   SilcHashTable invite_list;         /* Invited list */
156   SilcHashTable ban_list;            /* Ban list */
157   SilcHashTable user_list;           /* Joined users */
158
159   SilcCipher channel_key;            /* Current channel key */
160   unsigned char *key;                /* Current channel key data */
161   SilcUInt32 key_len;                /* Channel key data length */
162   SilcHmac hmac;                     /* Current HMAC */
163   SilcUInt32 refcnt;                 /* Reference counter */
164
165   //  SilcServerChannelRekey rekey;
166   unsigned long created;
167   unsigned long updated;
168
169   /* Flags */
170   unsigned int global_users : 1;
171   unsigned int disabled : 1;
172   unsigned int users_resolved : 1;
173 };
174
175 /* Internal context for accepting new connection */
176 typedef struct SilcServerAcceptStruct {
177   SilcEntryDataStruct data;
178   SilcServerThread thread;
179   SilcFSMThread t;                   /* Thread for accepting connection */
180   SilcStream stream;                 /* Remote connection */
181   SilcPacketStream packet_stream;    /* Remote connection */
182   SilcConnAuth connauth;             /* Connection authentication context */
183   SilcFSMSemaStruct wait_register;   /* Signaller when registering received */
184   SilcPacket register_packet;        /* NEW_CLIENT/NEW_SERVER packet */
185
186   SilcServerParamClient cconfig;
187   SilcServerParamServer sconfig;
188   SilcServerParamRouter rconfig;
189   SilcSKEStatus status;
190   SilcSKESecurityProperties prop;
191   SilcSKEKeyMaterial keymat;
192   SilcSKERekeyMaterial rekey;
193   SilcAsyncOperation op;
194   const char *hostname;
195   const char *ip;
196   SilcUInt16 port;
197   SilcStatus error;
198   char *error_string;
199   SilcBool auth_success;
200   SilcConnectionType conn_type;
201   SilcHash hash;
202   struct SilcServerAcceptStruct *next;
203 } *SilcServerAccept;
204
205 /* Server statistics structure. */
206 typedef struct {
207   /* Local stats (server and router) */
208   SilcUInt32 my_clients;                  /* Locally connected clients */
209   SilcUInt32 my_servers;                  /* Locally connected servers */
210   SilcUInt32 my_routers;                  /* Locally connected routers */
211   SilcUInt32 my_channels;                 /* Locally created channels */
212   SilcUInt32 my_chanclients;              /* Local clients on local channels */
213   SilcUInt32 my_aways;                    /* Local clients away (gone) */
214   SilcUInt32 my_detached;                 /* Local clients detached */
215   SilcUInt32 my_server_ops;               /* Local server operators */
216   SilcUInt32 my_router_ops;               /* Local router operators */
217
218   /* Global stats (mainly for router) */
219   SilcUInt32 cell_clients;                /* All clients in cell */
220   SilcUInt32 cell_servers;                /* All servers in cell */
221   SilcUInt32 cell_channels;               /* All channels in cell */
222   SilcUInt32 cell_chanclients;            /* All clients on cell's channels */
223   SilcUInt32 clients;                     /* All clients */
224   SilcUInt32 servers;                     /* All servers */
225   SilcUInt32 routers;                     /* All routers */
226   SilcUInt32 channels;                    /* All channels */
227   SilcUInt32 chanclients;                 /* All clients on channels */
228   SilcUInt32 aways;                       /* All clients away (gone) */
229   SilcUInt32 detached;                    /* All clients detached */
230   SilcUInt32 server_ops;                  /* All server operators */
231   SilcUInt32 router_ops;                  /* All router operators */
232   /* More to add
233   SilcUInt32 secret_channels;
234   SilcUInt32 private_channels;
235   */
236
237   /* General */
238   SilcUInt32 conn_attempts;               /* Connection attempts */
239   SilcUInt32 conn_failures;               /* Connection failure */
240   SilcUInt32 auth_attempts;               /* Authentication attempts */
241   SilcUInt32 auth_failures;               /* Authentication failures */
242   SilcUInt32 packets_sent;                /* Sent SILC packets */
243   SilcUInt32 packets_received;            /* Received SILC packets */
244   SilcUInt32 conn_num;                    /* Number of connections */
245   SilcUInt32 commands_sent;               /* Commands/replies sent */
246   SilcUInt32 commands_received;           /* Commands/replies received */
247 } SilcServerStatistics;
248
249 /* Server thread context */
250 struct SilcServerThreadStruct {
251   struct SilcServerThreadStruct *next;
252   SilcServer server;                 /* Pointer to server */
253   SilcStack stack;                   /* Data stack for fast allocations */
254   SilcPacketEngine packet_engine;    /* Packet engine */
255   SilcFSMThreadStruct thread;        /* FSM thread */
256   SilcFSMStruct fsm;                 /* Thread's FSM */
257   SilcFSMSemaStruct wait_event;      /* Thread's event signaller */
258   SilcUInt32 num_conns;              /* Number of connections in the thread */
259   SilcList new_conns;                /* New network connections */
260   SilcList packet_queue;             /* Incoming packet queue */
261
262   /* Events */
263   unsigned int new_connection  : 1;  /* New connection received */
264   unsigned int new_packet      : 1;  /* New packet in packet queue */
265 };
266
267 /* Server context. */
268 struct SilcServerStruct {
269   char *server_name;                 /* Server name */
270   SilcServerEntry server_entry;      /* Server entry */
271   SilcServerID id;                   /* Server ID */
272   SilcUInt32 starttime;
273
274   SilcFSMStruct fsm;                 /* Server FSM */
275   SilcSchedule schedule;             /* Scheduler */
276   SilcMutex lock;                    /* Server lock */
277   SilcRng rng;                       /* Random number generator */
278   SilcServerParams params;           /* Server parameters */
279   SilcDList listeners;               /* Network listeners */
280   SilcList threads;                  /* Server worker threads */
281   SilcList new_conns;                /* New network connections */
282   SilcList command_pool;             /* Command context freelist */
283   SilcHashTable pending_commands;    /* Pending commands */
284
285   SilcFSMSemaStruct wait_event;      /* Main state signaller */
286   SilcFSMSemaStruct thread_up;       /* Signaller when thread is up */
287
288   SilcIDCache clients;               /* Client entry cache */
289   SilcIDCache servers;               /* Server entry cache */
290   SilcIDCache channels;              /* Channel entry cache */
291
292   SilcSKR repository;                /* Public key/certificate repository */
293   SilcHashTable watcher_list;        /* Watcher list, nickname */
294   SilcHashTable watcher_list_pk;     /* Watcher list, public keys */
295
296   void *app_context;                 /* Application specific context */
297
298   char *config_file;
299
300   /* Events */
301   unsigned int new_connection  : 1;  /* New connection received */
302   unsigned int connect_router  : 1;  /* Connect to configured routers */
303   unsigned int get_statistics  : 1;  /* Get statistics */
304   unsigned int reconfigure     : 1;  /* Reconfigure server */
305   unsigned int server_shutdown : 1;  /* Shutdown server */
306   unsigned int run_callback    : 1;  /* Call running callback */
307
308   /* Flags */
309   unsigned int server_type    : 2;   /* Server type (server.h) */
310   unsigned int standalone     : 1;   /* Set if server is standalone, and
311                                         does not have connection to network. */
312   unsigned int listenning     : 1;   /* Set if server is listenning for
313                                         incoming connections. */
314   unsigned int background     : 1;   /* Set when server is on background */
315   unsigned int backup_router  : 1;   /* Set if this is backup router */
316   unsigned int backup_primary : 1;   /* Set if we've switched our primary
317                                         router to a backup router. */
318   unsigned int backup_noswitch: 1;   /* Set if we've won't switch to
319                                         become primary (we are backup) */
320   unsigned int backup_closed  : 1;   /* Set if backup closed connection.
321                                         Do not allow resuming in this case. */
322   unsigned int wait_backup    : 1;   /* Set if we are waiting for backup
323                                         router to connect to us. */
324   unsigned int no_reconnect   : 1;   /* If set, server won't reconnect to
325                                         router after disconnection. */
326
327   SilcPacketStream router;           /* Pointer to the primary router */
328
329   /* Current command identifier, 0 not used */
330   SilcUInt16 cmd_ident;
331
332   /* Server public key */
333   SilcPublicKey public_key;
334   SilcPrivateKey private_key;
335
336   /* Hash objects for general hashing */
337   SilcHash md5hash;
338   SilcHash sha1hash;
339
340   /* Server statistics */
341   SilcServerStatistics stat;
342
343 #ifdef SILC_SIM
344   /* SIM (SILC Module) list */
345   SilcDList sim;
346 #endif
347
348   /* Application callbacks */
349   SilcServerRunning running;         /* Called to indicate server is up */
350   SilcServerStop stopped;            /* Called to indicate server is down */
351   void *running_context;
352   void *stop_context;
353 };
354
355 /* Rekey must be performed at the lastest when this many packets is sent */
356 #define SILC_SERVER_REKEY_THRESHOLD 0xfffffe00
357
358 /* Macros */
359
360 /* Return pointer to the primary router connection */
361 #define SILC_PRIMARY_ROUTE(server) server->router
362
363 /* Return TRUE if a packet must be broadcasted (router broadcasts) */
364 #define SILC_BROADCAST(server) (server->server_type == SILC_ROUTER)
365
366 /* Return TRUE if entry is locally connected or local to us */
367 #define SILC_IS_LOCAL(entry) \
368   (((SilcIDListData)entry)->status & SILC_IDLIST_STATUS_LOCAL)
369
370 /* Registers generic task for file descriptor for reading from network and
371    writing to network. As being generic task the actual task is allocated
372    only once and after that the same task applies to all registered fd's. */
373 #define SILC_REGISTER_CONNECTION_FOR_IO(fd)             \
374 do {                                                    \
375   silc_schedule_task_add(server->schedule, (fd),        \
376                          silc_server_packet_process,    \
377                          context, 0, 0,                 \
378                          SILC_TASK_GENERIC,             \
379                          SILC_TASK_PRI_NORMAL);         \
380 } while(0)
381
382 #define SILC_SET_CONNECTION_FOR_INPUT(s, fd)                            \
383 do {                                                                    \
384   silc_schedule_set_listen_fd((s), (fd), SILC_TASK_READ, FALSE);        \
385 } while(0)
386
387 #define SILC_SET_CONNECTION_FOR_OUTPUT(s, fd)                                \
388 do {                                                                         \
389   silc_schedule_set_listen_fd((s), (fd), (SILC_TASK_READ | SILC_TASK_WRITE), \
390                               FALSE);                                        \
391 } while(0)
392
393 #define SILC_OPER_STATS_UPDATE(c, type, mod)    \
394 do {                                            \
395   if ((c)->mode & (mod)) {                      \
396     if (SILC_IS_LOCAL((c)))                     \
397       server->stat.my_ ## type ## _ops--;       \
398     if (server->server_type == SILC_ROUTER)     \
399       server->stat. type ## _ops--;             \
400     (c)->mode &= ~(mod);                        \
401   }                                             \
402 } while(0)
403
404 #define SILC_UMODE_STATS_UPDATE(oper, mod)      \
405 do {                                            \
406     if (client->mode & (mod)) {                 \
407       if (!(mode & (mod))) {                    \
408         if (SILC_IS_LOCAL(client))              \
409           server->stat.my_ ## oper ## _ops--;   \
410         if (server->server_type == SILC_ROUTER) \
411           server->stat. oper ## _ops--;         \
412       }                                         \
413     } else {                                    \
414       if (mode & (mod)) {                       \
415         if (SILC_IS_LOCAL(client))              \
416           server->stat.my_ ## oper ## _ops++;   \
417         if (server->server_type == SILC_ROUTER) \
418           server->stat. oper ## _ops++;         \
419       }                                         \
420     }                                           \
421 } while(0)
422
423 #define SILC_GET_SKE_FLAGS(x, p)                        \
424   if ((x)) {                                            \
425     if ((x)->param && (x)->param->key_exchange_pfs)     \
426       (p) |= SILC_SKE_SP_FLAG_PFS;              \
427     if (!(x)->publickeys)                               \
428       (p) |= SILC_SKE_SP_FLAG_MUTUAL;           \
429   }
430
431 #define SILC_CONNTYPE_STRING(ctype) \
432  (ctype == SILC_CONN_CLIENT ? "Client" : \
433   ctype == SILC_CONN_SERVER ? "Server" : "Router")
434
435 /* This macro is used to send notify messages with formatted string. The
436    string is formatted with arguments and the formatted string is sent as
437    argument. */
438 #define SILC_SERVER_SEND_NOTIFY(server, stream, type, fmt)      \
439 do {                                                            \
440   char *__fmt__ = silc_format fmt;                              \
441   if (__fmt__)                                                  \
442     silc_server_send_notify(server, stream, FALSE,              \
443                             type, 1, __fmt__, strlen(__fmt__)); \
444   silc_free(__fmt__);                                           \
445 } while(0)
446
447 /* Send notify to operators */
448 #define SILC_SERVER_SEND_OPERS(server, route, local, type, fmt)         \
449 do {                                                                    \
450   char *__fmt__ = silc_format fmt;                                      \
451   silc_server_send_opers_notify(server, route, local,                   \
452                                 type, 1, __fmt__, strlen(__fmt__));     \
453   silc_free(__fmt__);                                                   \
454 } while(0)
455
456 /* Connection retry timeout. We implement exponential backoff algorithm
457    in connection retry. The interval of timeout grows when retry count
458    grows. */
459 #define SILC_SERVER_RETRY_COUNT        7         /* Max retry count */
460 #define SILC_SERVER_RETRY_MULTIPLIER   2         /* Interval growth */
461 #define SILC_SERVER_RETRY_RANDOMIZER   2         /* timeout += rnd % 2 */
462 #define SILC_SERVER_RETRY_INTERVAL_MIN 10        /* Min retry timeout */
463 #define SILC_SERVER_RETRY_INTERVAL_MAX 600       /* Max generated timeout */
464
465 #define SILC_SERVER_KEEPALIVE          300       /* Heartbeat interval */
466 #define SILC_SERVER_REKEY              3600      /* Session rekey interval */
467 #define SILC_SERVER_MAX_CONNECTIONS    1000      /* Max connections */
468 #define SILC_SERVER_MAX_CONNECTIONS_SINGLE 1000  /* Max connections per host */
469 #define SILC_SERVER_LOG_FLUSH_DELAY    300       /* Default log flush delay */
470
471 /* Macros */
472
473 /* Check whether rekey protocol is active */
474 #define SILC_SERVER_IS_REKEY(sock)                                      \
475   (sock->protocol && sock->protocol->protocol &&                        \
476    sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_REKEY)
477
478 /* Check whether backup resuming protocol is active */
479 #define SILC_SERVER_IS_BACKUP(sock)                                     \
480   (sock->protocol && sock->protocol->protocol &&                        \
481    sock->protocol->protocol->type == SILC_PROTOCOL_SERVER_BACKUP)
482
483 /* Output a message to stderr or to the appropriate log facility wether
484    we are in the background or not. */
485 #define SILC_SERVER_LOG_INFO(fmt)                                       \
486   silc_server_stderr(SILC_LOG_INFO, silc_format fmt)
487 #define SILC_SERVER_LOG_WARNING(fmt)                                    \
488   silc_server_stderr(SILC_LOG_WARNING, silc_format fmt)
489 #define SILC_SERVER_LOG_ERROR(fmt)                                      \
490   silc_server_stderr(SILC_LOG_ERROR, silc_format fmt)
491 #define SILC_SERVER_LOG_FATAL(fmt)                                      \
492   silc_server_stderr(SILC_LOG_WARNING, silc_format fmt)
493
494 /* Server's states */
495 SILC_FSM_STATE(silc_server_st_run);
496 SILC_FSM_STATE(silc_server_st_new_connection);
497 SILC_FSM_STATE(silc_server_st_wait_new_thread);
498 SILC_FSM_STATE(silc_server_st_stop);
499 SILC_FSM_STATE(silc_server_st_reconfigure);
500 SILC_FSM_STATE(silc_server_st_get_stats);
501 SILC_FSM_STATE(silc_server_st_connect_router);
502
503 /* Server's thread's states */
504 SILC_FSM_STATE(silc_server_thread_st_start);
505 SILC_FSM_STATE(silc_server_thread_st_run);
506
507 /* Prototypes */
508 void silc_server_watcher_list_destroy(void *key, void *context,
509                                       void *user_context);
510
511 #include "server_entry.h"
512
513 #endif /* SERVER_INTERNAL_H */