1 /*
2  * jabberd - Jabber Open Source Server
3  * Copyright (c) 2002 Jeremie Miller, Thomas Muldowney,
4  *                    Ryan Eatmon, Robert Norris
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA
19  */
20 
21 #ifdef HAVE_CONFIG_H
22 # include <config.h>
23 #endif
24 
25 #include "ac-stdint.h"
26 
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <stdarg.h>
30 #include <time.h>
31 #include <errno.h>
32 #include <assert.h>
33 
34 #include <expat.h>
35 
36 #ifdef HAVE_SYS_TYPES_H
37 # include <sys/types.h>
38 #endif
39 
40 #ifdef HAVE_NETINET_IN_H
41 # include <netinet/in.h>
42 #endif
43 
44 #if defined(HAVE_SYS_TIME_H)
45 # include <sys/time.h>
46 #elif defined(HAVE_SYS_TIMEB_H)
47 # include <sys/timeb.h>
48 #endif
49 #ifdef HAVE_SYSLOG_H
50 # include <syslog.h>
51 #endif
52 #ifdef HAVE_UNISTD_H
53 # include <unistd.h>
54 #endif
55 #include <ctype.h>
56 
57 #ifdef HAVE_SYS_SOCKET_H
58 # include <sys/socket.h>
59 #endif
60 #ifdef HAVE_NETINET_IN_H
61 # include <netinet/in.h>
62 #endif
63 #ifdef HAVE_ARPA_INET_H
64 # include <arpa/inet.h>
65 #endif
66 
67 #ifndef PATH_MAX
68 #ifndef MAXPATHLEN
69 # define PATH_MAX 512
70 #else
71 # define PATH_MAX MAXPATHLEN
72 #endif
73 #endif
74 
75 #ifdef USE_LIBSUBST
76 #include "subst/subst.h"
77 #endif
78 
79 #include "util/util_compat.h"
80 
81 #ifndef INCL_UTIL_H
82 #define INCL_UTIL_H
83 
84 /* jabberd2 Windows DLL */
85 #ifndef JABBERD2_API
86 # ifdef _WIN32
87 #  ifdef JABBERD2_EXPORTS
88 #   define JABBERD2_API  __declspec(dllexport)
89 #  else /* JABBERD2_EXPORTS */
90 #   define JABBERD2_API  __declspec(dllimport)
91 #  endif /* JABBERD2_EXPORTS */
92 # else /* _WIN32 */
93 #  define JABBERD2_API extern
94 # endif /* _WIN32 */
95 #endif /* JABBERD2_API */
96 
97 #ifdef __cplusplus
98 extern "C" {
99 #endif
100 
101 /* crypto hashing utils */
102 #include "sha1.h"
103 #include "md5.h"
104 
105 #include <util/nad.h>
106 #include <util/pool.h>
107 #include <util/xhash.h>
108 
109 /* --------------------------------------------------------- */
110 /*                                                           */
111 /* String management routines                                */
112 /*                                                           */
113 /** --------------------------------------------------------- */
114 JABBERD2_API char *j_strdup(const char *str); /* provides NULL safe strdup wrapper */
115 JABBERD2_API char *j_strcat(char *dest, const char *txt); /* strcpy() clone */
116 JABBERD2_API int j_strcmp(const char *a, const char *b); /* provides NULL safe strcmp wrapper */
117 JABBERD2_API int j_strcasecmp(const char *a, const char *b); /* provides NULL safe strcasecmp wrapper */
118 JABBERD2_API int j_strncmp(const char *a, const char *b, int i); /* provides NULL safe strncmp wrapper */
119 JABBERD2_API int j_strncasecmp(const char *a, const char *b, int i); /* provides NULL safe strncasecmp wrapper */
120 JABBERD2_API int j_strlen(const char *a); /* provides NULL safe strlen wrapper */
121 JABBERD2_API int j_atoi(const char *a, int def); /* checks for NULL and uses default instead, convienence */
122 JABBERD2_API char *j_attr(const char** atts, const char *attr); /* decode attr's (from expat) */
123 JABBERD2_API char *j_strnchr(const char *s, int c, int n); /* like strchr, but only searches n chars */
124 
125 /** old convenience function, now in str.c */
126 JABBERD2_API void shahash_r(const char* str, char hashbuf[41]);
127 JABBERD2_API void shahash_raw(const char* str, unsigned char hashval[20]);
128 
129 /* --------------------------------------------------------- */
130 /*                                                           */
131 /* XML escaping utils                                        */
132 /*                                                           */
133 /* --------------------------------------------------------- */
134 JABBERD2_API char *strescape(pool_t p, const char *buf, int len); /* Escape <>&'" chars */
135 JABBERD2_API char *strunescape(pool_t p, char* buf);
136 
137 
138 /* --------------------------------------------------------- */
139 /*                                                           */
140 /* String pools (spool) functions                            */
141 /*                                                           */
142 /* --------------------------------------------------------- */
143 struct spool_node
144 {
145     const char *c;
146     struct spool_node *next;
147 };
148 
149 typedef struct spool_struct
150 {
151     pool_t p;
152     int len;
153     struct spool_node *last;
154     struct spool_node *first;
155 } *spool;
156 
157 JABBERD2_API spool spool_new(pool_t p); /* create a string pool */
158 JABBERD2_API void spooler(spool s, ...); /* append all the char * args to the pool, terminate args with s again */
159 JABBERD2_API const char *spool_print(spool s); /* return a big string */
160 JABBERD2_API void spool_add(spool s, const char *str); /* add a single string to the pool */
161 JABBERD2_API void spool_escape(spool s, const char *raw, int len); /* add and xml escape a single string to the pool */
162 JABBERD2_API const char *spools(pool_t p, ...); /* wrap all the spooler stuff in one function, the happy fun ball! */
163 
164 
165 /* known namespace uri */
166 #include "util/uri.h"
167 
168 /* JID manipulation */
169 #include "util/jid.h"
170 
171 /* logging */
172 
173 typedef enum {
174     log_STDOUT,
175     log_SYSLOG,
176     log_FILE
177 } log_type_t;
178 
179 typedef struct log_st
180 {
181     log_type_t  type;
182     FILE        *file;
183 } *log_t;
184 
185 typedef struct log_facility_st
186 {
187     const char  *facility;
188     int         number;
189 } log_facility_t;
190 
191 JABBERD2_API log_t    log_new(log_type_t type, const char *ident, const char *facility);
192 JABBERD2_API void     log_write(log_t log, int level, const char *msgfmt, ...);
193 JABBERD2_API void     log_free(log_t log);
194 
195 /* config files */
196 typedef struct config_elem_st   *config_elem_t;
197 typedef struct config_st        *config_t;
198 
199 /** holder for the config hash and nad */
200 struct config_st
201 {
202     xht                 hash;
203     nad_t               nad;
204 };
205 
206 /** a single element */
207 struct config_elem_st
208 {
209     const char          **values;
210     int                 nvalues;
211     const char          ***attrs;
212 };
213 
214 JABBERD2_API config_t         config_new(void);
215 JABBERD2_API int              config_load(config_t c, const char *file);
216 JABBERD2_API int              config_load_with_id(config_t c, const char *file, const char *id);
217 JABBERD2_API config_elem_t    config_get(config_t c, const char *key);
218 JABBERD2_API const char      *config_get_one(config_t c, const char *key, int num);
219 JABBERD2_API const char      *config_get_one_default(config_t c, const char *key, int num, const char *default_value);
220 JABBERD2_API int              config_count(config_t c, const char *key);
221 JABBERD2_API char             *config_get_attr(config_t c, const char *key, int num, const char *attr);
222 JABBERD2_API char             *config_expand(config_t c, const char *value); //! Replaces $(some.value) with config_get_one(c, "some.value", 0)
223 JABBERD2_API void             config_free(config_t);
224 
225 
226 /*
227  * IP-based access controls
228  */
229 
230 typedef struct access_rule_st
231 {
232     struct sockaddr_storage ip;
233     int            mask;
234 } *access_rule_t;
235 
236 typedef struct access_st
237 {
238     int             order;      /* 0 = allow,deny  1 = deny,allow */
239 
240     access_rule_t   allow;
241     int             nallow;
242 
243     access_rule_t   deny;
244     int             ndeny;
245 } *access_t;
246 
247 JABBERD2_API access_t    access_new(int order);
248 JABBERD2_API void        access_free(access_t access);
249 JABBERD2_API int         access_allow(access_t access, const char *ip, const char *mask);
250 JABBERD2_API int         access_deny(access_t access, const char *ip, const char *mask);
251 JABBERD2_API int         access_check(access_t access, const char *ip);
252 
253 
254 /*
255  * rate limiting
256  */
257 
258 typedef struct rate_st
259 {
260     int             total;      /* if we exceed this many events */
261     int             seconds;    /* in this many seconds */
262     int             wait;       /* then go bad for this many seconds */
263 
264     time_t          time;       /* time we started counting events */
265     int             count;      /* event count */
266 
267     time_t          bad;        /* time we went bad, or 0 if we're not */
268 } *rate_t;
269 
270 JABBERD2_API rate_t      rate_new(int total, int seconds, int wait);
271 JABBERD2_API void        rate_free(rate_t rt);
272 JABBERD2_API void        rate_reset(rate_t rt);
273 
274 /**
275  * Add a number of events to the counter.  This takes care of moving
276  * the sliding window, if we've moved outside the previous window.
277  */
278 JABBERD2_API void        rate_add(rate_t rt, int count);
279 
280 /**
281  * @return The amount of events we have left before we hit the rate
282  *         limit.  This could be number of bytes, or number of
283  *         connection attempts, etc.
284  */
285 JABBERD2_API int         rate_left(rate_t rt);
286 
287 /**
288  * @return 1 if we're under the rate limit and everything is fine or
289  *         0 if the rate limit has been exceeded and we should throttle
290  *         something.
291  */
292 JABBERD2_API int         rate_check(rate_t rt);
293 
294 /*
295  * helpers for ip addresses
296  */
297 
298 #include "inaddr.h"        /* used in mio as well */
299 
300 /*
301  * serialisation helper functions
302  */
303 
304 JABBERD2_API int         ser_string_get(char **dest, int *source, const char *buf, int len);
305 JABBERD2_API int         ser_int_get(int *dest, int *source, const char *buf, int len);
306 JABBERD2_API void        ser_string_set(const char *source, int *dest, char **buf, int *len);
307 JABBERD2_API void        ser_int_set(int source, int *dest, char **buf, int *len);
308 
309 /*
310  * priority queues
311  */
312 
313 typedef struct _jqueue_node_st  *_jqueue_node_t;
314 struct _jqueue_node_st {
315     void            *data;
316 
317     int             priority;
318 
319     _jqueue_node_t  next;
320     _jqueue_node_t  prev;
321 };
322 
323 typedef struct _jqueue_st {
324     pool_t          p;
325     _jqueue_node_t  cache;
326 
327     _jqueue_node_t  front;
328     _jqueue_node_t  back;
329 
330     int             size;
331     char            *key;
332     time_t          init_time;
333 } *jqueue_t;
334 
335 JABBERD2_API jqueue_t    jqueue_new(void);
336 JABBERD2_API void        jqueue_free(jqueue_t q);
337 JABBERD2_API void        jqueue_push(jqueue_t q, void *data, int pri);
338 JABBERD2_API void        *jqueue_pull(jqueue_t q);
339 JABBERD2_API int         jqueue_size(jqueue_t q);
340 JABBERD2_API time_t      jqueue_age(jqueue_t q);
341 
342 
343 /* ISO 8601 / JEP-0082 date/time manipulation */
344 typedef enum {
345     dt_DATE     = 1,
346     dt_TIME     = 2,
347     dt_DATETIME = 3,
348     dt_LEGACY   = 4
349 } datetime_t;
350 
351 JABBERD2_API time_t  datetime_in(char *date);
352 JABBERD2_API void    datetime_out(time_t t, datetime_t type, char *date, int datelen);
353 
354 
355 /* base64 functions */
356 JABBERD2_API int apr_base64_decode_len(const char *bufcoded, int buflen);
357 JABBERD2_API int apr_base64_decode(char *bufplain, const char *bufcoded, int buflen);
358 JABBERD2_API int apr_base64_encode_len(int len);
359 JABBERD2_API int apr_base64_encode(char *encoded, const char *string, int len);
360 
361 /* convenience, result string must be free()'d by caller */
362 JABBERD2_API char *b64_encode(char *buf, int len);
363 JABBERD2_API char *b64_decode(char *buf);
364 
365 
366 /* stanza manipulation */
367 #define stanza_err_BAD_REQUEST              (100)
368 #define stanza_err_CONFLICT                 (101)
369 #define stanza_err_FEATURE_NOT_IMPLEMENTED  (102)
370 #define stanza_err_FORBIDDEN                (103)
371 #define stanza_err_GONE                     (104)
372 #define stanza_err_INTERNAL_SERVER_ERROR    (105)
373 #define stanza_err_ITEM_NOT_FOUND           (106)
374 #define stanza_err_JID_MALFORMED            (107)
375 #define stanza_err_NOT_ACCEPTABLE           (108)
376 #define stanza_err_NOT_ALLOWED              (109)
377 #define stanza_err_PAYMENT_REQUIRED         (110)
378 #define stanza_err_RECIPIENT_UNAVAILABLE    (111)
379 #define stanza_err_REDIRECT                 (112)
380 #define stanza_err_REGISTRATION_REQUIRED    (113)
381 #define stanza_err_REMOTE_SERVER_NOT_FOUND  (114)
382 #define stanza_err_REMOTE_SERVER_TIMEOUT    (115)
383 #define stanza_err_RESOURCE_CONSTRAINT      (116)
384 #define stanza_err_SERVICE_UNAVAILABLE      (117)
385 #define stanza_err_SUBSCRIPTION_REQUIRED    (118)
386 #define stanza_err_UNDEFINED_CONDITION      (119)
387 #define stanza_err_UNEXPECTED_REQUEST       (120)
388 #define stanza_err_OLD_UNAUTH               (121)
389 #define stanza_err_UNKNOWN_SENDER           (122)
390 #define stanza_err_LAST                     (123)
391 
392 JABBERD2_API nad_t stanza_error(nad_t nad, int elem, int err);
393 JABBERD2_API nad_t stanza_tofrom(nad_t nad, int elem);
394 
395 typedef struct _stanza_error_st {
396     const char  *name;
397     const char  *type;
398     const char  *code;
399 } *stanza_error_t;
400 
401 JABBERD2_API struct _stanza_error_st _stanza_errors[];
402 
403 
404 /* hex conversion utils */
405 JABBERD2_API void hex_from_raw(const unsigned char* in, int inlen, char* out);
406 JABBERD2_API int hex_to_raw(const char *in, int inlen, char *out);
407 
408 
409 /* xdata in a seperate file */
410 #include "xdata.h"
411 
412 
413 /* debug logging */
414 JABBERD2_API int get_debug_flag(void);
415 JABBERD2_API void set_debug_flag(int v);
416 JABBERD2_API void debug_log(const char *file, int line, const char *msgfmt, ...);
417 JABBERD2_API void set_debug_file(const char *filename);
418 
419 JABBERD2_API void set_debug_log_from_config(config_t c);
420 
421 #define ZONE __FILE__,__LINE__
422 #define MAX_DEBUG 8192
423 
424 /* if no debug, basically compile it out */
425 #ifdef DEBUG
426 #define log_debug if(get_debug_flag()) debug_log
427 #else
428 #define log_debug if(0) debug_log
429 #endif
430 
431 /* Portable signal function */
432 typedef void jsighandler_t(int);
433 JABBERD2_API jsighandler_t* jabber_signal(int signo,  jsighandler_t *func);
434 
435 #ifdef _WIN32
436 /* Windows service wrapper function */
437 typedef int (jmainhandler_t)(int argc, char** argv);
438 JABBERD2_API int jabber_wrap_service(int argc, char** argv, jmainhandler_t *wrapper, LPCTSTR name, LPCTSTR display, LPCTSTR description, LPCTSTR depends);
439 #define JABBER_MAIN(name, display, description, depends) jabber_main(int argc, char** argv); \
440                     main(int argc, char** argv) { return jabber_wrap_service(argc, argv, jabber_main, name, display, description, depends); } \
441                     jabber_main(int argc, char** argv)
442 #else /* _WIN32 */
443 #define JABBER_MAIN(name, display, description, depends) int main(int argc, char** argv)
444 #endif /* _WIN32 */
445 
446 #ifdef __cplusplus
447 }
448 #endif
449 
450 #if XML_MAJOR_VERSION > 1
451 /* XML_StopParser is present in expat 2.x */
452 #define HAVE_XML_STOPPARSER
453 #if XML_MINOR_VERSION > 0
454 /* XML_SetHashSalt is present in expat 2.1.x */
455 #define HAVE_XML_SETHASHSALT
456 #endif
457 #endif
458 
459 /* define TRUE and FALSE if not yet defined */
460 #ifndef TRUE
461 #define TRUE 1
462 #endif
463 #ifndef FALSE
464 #define FALSE 0
465 #endif
466 
467 #endif    /* INCL_UTIL_H */
468 
469 
470