62
64
# include <arpa/inet.h>
71
# define PATH_MAX MAXPATHLEN
65
76
#include "subst/subst.h"
67
79
#include "util/util_compat.h"
69
81
#ifndef INCL_UTIL_H
70
82
#define INCL_UTIL_H
84
/* jabberd2 Windows DLL */
87
# ifdef JABBERD2_EXPORTS
88
# define JABBERD2_API __declspec(dllexport)
89
# else /* JABBERD2_EXPORTS */
90
# define JABBERD2_API __declspec(dllimport)
91
# endif /* JABBERD2_EXPORTS */
93
# define JABBERD2_API extern
95
#endif /* JABBERD2_API */
76
/* expat is available */
80
101
/* crypto hashing utils */
85
/* --------------------------------------------------------- */
87
/* Pool-based memory management routines */
89
/* --------------------------------------------------------- */
92
/* prime number for top # of pools debugging */
93
#define POOL_NUM 40009
96
/** pheap - singular allocation of memory */
103
/** pool_cleaner - callback type which is associated
104
with a pool entry; invoked when the pool entry is
106
typedef void (*pool_cleaner)(void *arg);
108
/** pfree - a linked list node which stores an
109
allocation chunk, plus a callback */
118
/** pool - base node for a pool. Maintains a linked list
119
of pool entries (pfree) */
120
typedef struct pool_struct
123
struct pfree *cleanup;
124
struct pfree *cleanup_tail;
127
char name[8], zone[32];
130
#define pool_new() _pool_new(ZONE)
131
#define pool_heap(i) _pool_new_heap(i,ZONE)
134
#define pool_heap(i) _pool_new_heap(i,NULL,0)
135
#define pool_new() _pool_new(NULL,0)
138
pool _pool_new(char *zone, int line); /* new pool :) */
139
pool _pool_new_heap(int size, char *zone, int line); /* creates a new memory pool with an initial heap size */
140
void *pmalloc(pool p, int size); /* wrapper around malloc, takes from the pool, cleaned up automatically */
141
void *pmalloc_x(pool p, int size, char c); /* Wrapper around pmalloc which prefils buffer with c */
142
void *pmalloco(pool p, int size); /* YAPW for zeroing the block */
143
char *pstrdup(pool p, const char *src); /* wrapper around strdup, gains mem from pool */
144
void pool_stat(int full); /* print to stderr the changed pools and reset */
145
char *pstrdupx(pool p, const char *src, int len); /* use given len */
146
void pool_cleanup(pool p, pool_cleaner f, void *arg); /* calls f(arg) before the pool is freed during cleanup */
147
void pool_free(pool p); /* calls the cleanup functions, frees all the data on the pool, and deletes the pool itself */
148
int pool_size(pool p); /* returns total bytes allocated in this pool */
105
#include <util/nad.h>
106
#include <util/pool.h>
107
#include <util/xhash.h>
153
109
/* --------------------------------------------------------- */
155
111
/* String management routines */
157
113
/** --------------------------------------------------------- */
158
char *j_strdup(const char *str); /* provides NULL safe strdup wrapper */
159
char *j_strcat(char *dest, char *txt); /* strcpy() clone */
160
int j_strcmp(const char *a, const char *b); /* provides NULL safe strcmp wrapper */
161
int j_strcasecmp(const char *a, const char *b); /* provides NULL safe strcasecmp wrapper */
162
int j_strncmp(const char *a, const char *b, int i); /* provides NULL safe strncmp wrapper */
163
int j_strncasecmp(const char *a, const char *b, int i); /* provides NULL safe strncasecmp wrapper */
164
int j_strlen(const char *a); /* provides NULL safe strlen wrapper */
165
int j_atoi(const char *a, int def); /* checks for NULL and uses default instead, convienence */
166
char *j_attr(const char** atts, char *attr); /* decode attr's (from expat) */
167
char *j_strnchr(const char *s, int c, int n); /* like strchr, but only searches n chars */
114
JABBERD2_API char *j_strdup(const char *str); /* provides NULL safe strdup wrapper */
115
JABBERD2_API char *j_strcat(char *dest, 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 */
169
125
/** old convenience function, now in str.c */
170
void shahash_r(const char* str, char hashbuf[41]);
172
/* --------------------------------------------------------- */
174
/* Hashtable functions */
176
/* --------------------------------------------------------- */
177
typedef struct xhn_struct
179
struct xhn_struct *next;
184
typedef struct xht_struct
190
struct xhn_struct *zen;
195
xht xhash_new(int prime);
196
void xhash_put(xht h, const char *key, void *val);
197
void xhash_putx(xht h, const char *key, int len, void *val);
198
void *xhash_get(xht h, const char *key);
199
void *xhash_getx(xht h, const char *key, int len);
200
void xhash_zap(xht h, const char *key);
201
void xhash_zapx(xht h, const char *key, int len);
202
void xhash_free(xht h);
203
typedef void (*xhash_walker)(xht h, const char *key, void *val, void *arg);
204
void xhash_walk(xht h, xhash_walker w, void *arg);
205
int xhash_dirty(xht h);
206
int xhash_count(xht h);
207
pool xhash_pool(xht h);
209
/* iteration functions */
210
int xhash_iter_first(xht h);
211
int xhash_iter_next(xht h);
212
void xhash_iter_zap(xht h);
213
int xhash_iter_get(xht h, const char **key, void **val);
126
JABBERD2_API void shahash_r(const char* str, char hashbuf[41]);
215
128
/* --------------------------------------------------------- */
217
130
/* XML escaping utils */
219
132
/* --------------------------------------------------------- */
220
char *strescape(pool p, char *buf, int len); /* Escape <>&'" chars */
221
char *strunescape(pool p, char *buf);
133
JABBERD2_API char *strescape(pool_t p, char *buf, int len); /* Escape <>&'" chars */
134
JABBERD2_API char *strunescape(pool_t p, char *buf);
224
137
/* --------------------------------------------------------- */
235
148
typedef struct spool_struct
239
152
struct spool_node *last;
240
153
struct spool_node *first;
243
spool spool_new(pool p); /* create a string pool */
244
void spooler(spool s, ...); /* append all the char * args to the pool, terminate args with s again */
245
char *spool_print(spool s); /* return a big string */
246
void spool_add(spool s, char *str); /* add a single string to the pool */
247
void spool_escape(spool s, char *raw, int len); /* add and xml escape a single string to the pool */
248
char *spools(pool p, ...); /* wrap all the spooler stuff in one function, the happy fun ball! */
156
JABBERD2_API spool spool_new(pool_t p); /* create a string pool */
157
JABBERD2_API void spooler(spool s, ...); /* append all the char * args to the pool, terminate args with s again */
158
JABBERD2_API char *spool_print(spool s); /* return a big string */
159
JABBERD2_API void spool_add(spool s, char *str); /* add a single string to the pool */
160
JABBERD2_API void spool_escape(spool s, char *raw, int len); /* add and xml escape a single string to the pool */
161
JABBERD2_API char *spools(pool_t p, ...); /* wrap all the spooler stuff in one function, the happy fun ball! */
251
164
/* known namespace uri */
252
#define uri_STREAMS "http://etherx.jabber.org/streams"
253
#define uri_CLIENT "jabber:client"
254
#define uri_SERVER "jabber:server"
255
#define uri_DIALBACK "jabber:server:dialback"
256
#define uri_TLS "urn:ietf:params:xml:ns:xmpp-tls"
257
#define uri_SASL "urn:ietf:params:xml:ns:xmpp-sasl"
258
#define uri_BIND "urn:ietf:params:xml:ns:xmpp-bind"
259
#define uri_XSESSION "urn:ietf:params:xml:ns:xmpp-session"
260
#define uri_STREAM_ERR "urn:ietf:params:xml:ns:xmpp-streams"
261
#define uri_STANZA_ERR "urn:ietf:params:xml:ns:xmpp-stanzas"
262
#define uri_COMPONENT "http://jabberd.jabberstudio.org/ns/component/1.0"
263
#define uri_SESSION "http://jabberd.jabberstudio.org/ns/session/1.0"
264
#define uri_RESOLVER "http://jabberd.jabberstudio.org/ns/resolver/1.0"
265
#define uri_XDATA "jabber:x:data"
266
#define uri_XML "http://www.w3.org/XML/1998/namespace"
270
* JID manipulation. Validity is checked via stringprep, using the "nodeprep",
271
* "nameprep" and "resourceprep" profiles (see xmpp-core section 3).
273
* The provided functions are mainly for convenience. The application should
274
* fill out node, domain and resource directly. When they modify these, they
275
* should either call jid_expand(), or set the dirty flag.
278
/** preparation cache, for speed */
279
typedef struct prep_cache_st {
285
prep_cache_t prep_cache_new(void);
286
void prep_cache_free(prep_cache_t pc);
287
char *prep_cache_node_get(prep_cache_t pc, char *from);
288
void prep_cache_node_set(prep_cache_t pc, char *from, char *to);
289
char *prep_cache_domain_get(prep_cache_t pc, char *from);
290
void prep_cache_domain_set(prep_cache_t pc, char *from, char *to);
291
char *prep_cache_resource_get(prep_cache_t pc, char *from);
292
void prep_cache_resource_set(prep_cache_t pc, char *from, char *to);
294
/** these sizings come from xmpp-core */
295
#define MAXLEN_JID_COMP 1023 /* XMPP (RFC3920) 3.1 */
296
#define MAXLEN_JID 3071 /* nodename (1023) + '@' + domain (1023) + '/' + resource (1023) = 3071 */
298
typedef struct jid_st {
299
/* cache for prep, if any */
302
/* basic components of the jid */
304
unsigned char *domain;
305
unsigned char *resource;
307
/* Points to jid broken with \0s into componets. node/domain/resource point
308
* into this string (or to statically allocated empty string, if they are
310
unsigned char *jid_data;
311
/* Valid only when jid_data != NULL. When = 0, jid_data is statically
312
* allocated. Otherwise it tells length of the allocated data. Used to
313
* implement jid_dup() */
316
/* the "user" part of the jid (sans resource) */
317
unsigned char *_user;
319
/* the complete jid */
320
unsigned char *_full;
322
/* application should set to 1 if user/full need regenerating */
325
/* for lists of jids */
335
/** JID static buffer **/
336
typedef char jid_static_buf[3*1024];
338
/** make a new jid, and call jid_reset() to populate it */
339
jid_t jid_new(prep_cache_t pc, const unsigned char *id, int len);
341
/** Make jid to use static buffer (jid data won't be allocated dynamically, but
342
* given buffer will be always used. */
343
void jid_static(jid_t jid, jid_static_buf *buf);
345
/** clear and populate the jid with the given id. if id == NULL, just clears the jid to 0 */
346
jid_t jid_reset(jid_t jid, const unsigned char *id, int len);
347
jid_t jid_reset_components(jid_t jid, const unsigned char *node, const unsigned char *domain, const unsigned char *resource);
350
void jid_free(jid_t jid);
352
/** do string preparation on a jid */
353
int jid_prep(jid_t jid);
355
/** fill jid's resource with a random string **/
356
void jid_random_part(jid_t jid, jid_part_t part);
358
/** expands user and full if the dirty flag is set */
359
void jid_expand(jid_t jid);
361
/** return the user or full jid. these call jid_expand to make sure the user and
362
* full jid are up to date */
363
const unsigned char *jid_user(jid_t jid);
364
const unsigned char *jid_full(jid_t jid);
366
/** compare two user or full jids. these call jid_expand, then strcmp. returns
367
* 0 if they're the same, < 0 if a < b, > 0 if a > b */
368
int jid_compare_user(jid_t a, jid_t b);
369
int jid_compare_full(jid_t a, jid_t b);
371
/** duplicate a jid */
372
jid_t jid_dup(jid_t jid);
376
/** see if a jid is present in a list */
377
int jid_search(jid_t list, jid_t jid);
379
/** remove a jid from a list, and return the new list */
380
jid_t jid_zap(jid_t list, jid_t jid);
382
/** insert of a copy of jid into list, avoiding dups */
383
jid_t jid_append(jid_t list, jid_t jid);
165
#include "util/uri.h"
167
/* JID manipulation */
168
#include "util/jid.h"
400
184
typedef struct log_facility_st
186
const char *facility;
404
188
} log_facility_t;
406
extern log_t log_new(log_type_t type, char *ident, char *facility);
407
extern void log_write(log_t log, int level, const char *msgfmt, ...);
408
extern void log_free(log_t log);
415
* nad is very simplistic, and requires all string handling to use a length.
416
* Apps using this must be aware of the structure and access it directly for
417
* most information. nads can only be built by successively using the _append_
418
* functions correctly. After built, they can be modified using other functions,
419
* or by direct access. To access cdata on an elem or attr, use nad->cdata +
420
* nad->xxx[index].ixxx for the start, and .lxxx for len.
422
* Namespace support seems to work, but hasn't been thoroughly tested. in
423
* particular, editing the nad after its creation might have quirks. use at
424
* your own risk! Note that nad_add_namespace() brings a namespace into scope
425
* for the next element added with nad_append_elem(), nad_insert_elem() or
426
* nad_wrap_elem() (and by extension, any of its subelements). This is the same
427
* way that Expat does things, so nad_add_namespace() can be driven from the
428
* Expat's StartNamespaceDeclHandler.
431
typedef struct nad_st **nad_cache_t;
437
int icdata, lcdata; /* cdata within this elem (up to first child) */
438
int itail, ltail; /* cdata after this elem */
456
int iprefix, lprefix;
460
typedef struct nad_st
462
nad_cache_t cache; /* he who gave us life */
463
struct nad_elem_st *elems;
464
struct nad_attr_st *attrs;
465
struct nad_ns_st *nss;
467
int *depths; /* for tracking the last elem at a depth */
468
int elen, alen, nlen, clen, dlen;
469
int ecur, acur, ncur, ccur;
470
int scope; /* currently scoped namespaces, get attached to the next element */
471
struct nad_st *next; /* for keeping a list of nads */
474
/** create a new cache for nads */
475
nad_cache_t nad_cache_new(void);
477
/** free the cache */
478
void nad_cache_free(nad_cache_t cache);
480
/** create a new nad */
481
nad_t nad_new(nad_cache_t cache);
484
nad_t nad_copy(nad_t nad);
487
void nad_free(nad_t nad);
489
/** find the next element with this name/depth */
490
/** 0 for siblings, 1 for children and so on */
491
int nad_find_elem(nad_t nad, int elem, int ns, const char *name, int depth);
493
/** find the first matching attribute (and optionally value) */
494
int nad_find_attr(nad_t nad, int elem, int ns, const char *name, const char *val);
496
/** find the first matching namespace (and optionally prefix) */
497
int nad_find_namespace(nad_t nad, int elem, const char *uri, const char *prefix);
499
/** find a namespace in scope (and optionally prefix) */
500
int nad_find_scoped_namespace(nad_t nad, const char *uri, const char *prefix);
502
/** reset or store the given attribute */
503
void nad_set_attr(nad_t nad, int elem, int ns, const char *name, const char *val, int vallen);
505
/** insert and return a new element as a child of this one */
506
int nad_insert_elem(nad_t nad, int elem, int ns, const char *name, const char *cdata);
508
/** wrap an element with another element */
509
void nad_wrap_elem(nad_t nad, int elem, int ns, const char *name);
511
/** append and return a new element */
512
int nad_append_elem(nad_t nad, int ns, const char *name, int depth);
514
/** append attribs to the last element */
515
int nad_append_attr(nad_t nad, int ns, const char *name, const char *val);
517
/** append more cdata to the last element */
518
void nad_append_cdata(nad_t nad, const char *cdata, int len, int depth);
520
/** add a namespace to the next element (ie, called when the namespace comes into scope) */
521
int nad_add_namespace(nad_t nad, const char *uri, const char *prefix);
523
/** declare a namespace on an already existing element */
524
int nad_append_namespace(nad_t nad, int elem, const char *uri, const char *prefix);
526
/** create a string representation of the given element (and children), point references to it */
527
void nad_print(nad_t nad, int elem, char **xml, int *len);
529
/** serialize and deserialize a nad */
530
void nad_serialize(nad_t nad, char **buf, int *len);
531
nad_t nad_deserialize(nad_cache_t cache, const char *buf);
534
/** create a nad from raw xml */
535
nad_t nad_parse(nad_cache_t cache, const char *buf, int len);
538
/* these are some helpful macros */
539
#define NAD_ENAME(N,E) (N->cdata + N->elems[E].iname)
540
#define NAD_ENAME_L(N,E) (N->elems[E].lname)
541
#define NAD_CDATA(N,E) (N->cdata + N->elems[E].icdata)
542
#define NAD_CDATA_L(N,E) (N->elems[E].lcdata)
543
#define NAD_ANAME(N,A) (N->cdata + N->attrs[A].iname)
544
#define NAD_ANAME_L(N,A) (N->attrs[A].lname)
545
#define NAD_AVAL(N,A) (N->cdata + N->attrs[A].ival)
546
#define NAD_AVAL_L(N,A) (N->attrs[A].lval)
547
#define NAD_NURI(N,NS) (N->cdata + N->nss[NS].iuri)
548
#define NAD_NURI_L(N,NS) (N->nss[NS].luri)
549
#define NAD_NPREFIX(N,NS) (N->cdata + N->nss[NS].iprefix)
550
#define NAD_NPREFIX_L(N,NS) (N->nss[NS].lprefix)
552
#define NAD_ENS(N,E) (N->elems[E].my_ns)
553
#define NAD_ANS(N,A) (N->attrs[A].my_ns)
190
JABBERD2_API log_t log_new(log_type_t type, const char *ident, const char *facility);
191
JABBERD2_API void log_write(log_t log, int level, const char *msgfmt, ...);
192
JABBERD2_API void log_free(log_t log);
556
194
/* config files */
557
195
typedef struct config_elem_st *config_elem_t;
626
264
time_t bad; /* time we went bad, or 0 if we're not */
629
rate_t rate_new(int total, int seconds, int wait);
630
void rate_free(rate_t rt);
631
void rate_reset(rate_t rt);
632
void rate_add(rate_t rt, int count);
633
int rate_left(rate_t rt);
634
int rate_check(rate_t rt); /* 1 == good, 0 == bad */
267
JABBERD2_API rate_t rate_new(int total, int seconds, int wait);
268
JABBERD2_API void rate_free(rate_t rt);
269
JABBERD2_API void rate_reset(rate_t rt);
272
* Add a number of events to the counter. This takes care of moving
273
* the sliding window, if we've moved outside the previous window.
275
JABBERD2_API void rate_add(rate_t rt, int count);
278
* @return The amount of events we have left before we hit the rate
279
* limit. This could be number of bytes, or number of
280
* connection attempts, etc.
282
JABBERD2_API int rate_left(rate_t rt);
285
* @return 1 if we're under the rate limit and everything is fine or
286
* 0 if the rate limit has been exceeded and we should throttle
289
JABBERD2_API int rate_check(rate_t rt);
637
292
* helpers for ip addresses
690
time_t datetime_in(char *date);
691
void datetime_out(time_t t, datetime_t type, char *date, int datelen);
348
JABBERD2_API time_t datetime_in(char *date);
349
JABBERD2_API void datetime_out(time_t t, datetime_t type, char *date, int datelen);
694
352
/* base64 functions */
695
extern int ap_base64decode_len(const char *bufcoded, int buflen);
696
extern int ap_base64decode(char *bufplain, const char *bufcoded, int buflen);
697
extern int ap_base64decode_binary(unsigned char *bufplain, const char *bufcoded, int buflen);
698
extern int ap_base64encode_len(int len);
699
extern int ap_base64encode(char *encoded, const char *string, int len);
700
extern int ap_base64encode_binary(char *encoded, const unsigned char *string, int len);
353
JABBERD2_API int apr_base64_decode_len(const char *bufcoded, int buflen);
354
JABBERD2_API int apr_base64_decode(char *bufplain, const char *bufcoded, int buflen);
355
JABBERD2_API int apr_base64_encode_len(int len);
356
JABBERD2_API int apr_base64_encode(char *encoded, const char *string, int len);
702
358
/* convenience, result string must be free()'d by caller */
703
extern char *b64_encode(char *buf, int len);
704
extern char *b64_decode(char *buf);
359
JABBERD2_API char *b64_encode(char *buf, int len);
360
JABBERD2_API char *b64_decode(char *buf);
707
363
/* stanza manipulation */
727
383
#define stanza_err_UNDEFINED_CONDITION (119)
728
384
#define stanza_err_UNEXPECTED_REQUEST (120)
729
385
#define stanza_err_OLD_UNAUTH (121)
730
#define stanza_err_LAST (122)
732
extern nad_t stanza_error(nad_t nad, int elem, int err);
733
extern nad_t stanza_tofrom(nad_t nad, int elem);
386
#define stanza_err_UNKNOWN_SENDER (122)
387
#define stanza_err_LAST (123)
389
JABBERD2_API nad_t stanza_error(nad_t nad, int elem, int err);
390
JABBERD2_API nad_t stanza_tofrom(nad_t nad, int elem);
392
typedef struct _stanza_error_st {
398
JABBERD2_API struct _stanza_error_st _stanza_errors[];
736
401
/* hex conversion utils */
737
void hex_from_raw(char *in, int inlen, char *out);
738
int hex_to_raw(char *in, int inlen, char *out);
402
JABBERD2_API void hex_from_raw(char *in, int inlen, char *out);
403
JABBERD2_API int hex_to_raw(char *in, int inlen, char *out);
741
406
/* xdata in a seperate file */
759
424
/* Portable signal function */
760
425
typedef void jsighandler_t(int);
761
jsighandler_t* jabber_signal(int signo, jsighandler_t *func);
426
JABBERD2_API jsighandler_t* jabber_signal(int signo, jsighandler_t *func);
429
/* Windows service wrapper function */
430
typedef int (jmainhandler_t)(int argc, char** argv);
431
JABBERD2_API int jabber_wrap_service(int argc, char** argv, jmainhandler_t *wrapper, LPCTSTR name, LPCTSTR display, LPCTSTR description, LPCTSTR depends);
432
#define JABBER_MAIN(name, display, description, depends) jabber_main(int argc, char** argv); \
433
main(int argc, char** argv) { return jabber_wrap_service(argc, argv, jabber_main, name, display, description, depends); } \
434
jabber_main(int argc, char** argv)
436
#define JABBER_MAIN(name, display, description, depends) int main(int argc, char** argv)
763
439
#ifdef __cplusplus