jabberd2  2.2.16
util/util.h
Go to the documentation of this file.
00001 /*
00002  * jabberd - Jabber Open Source Server
00003  * Copyright (c) 2002 Jeremie Miller, Thomas Muldowney,
00004  *                    Ryan Eatmon, Robert Norris
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA
00019  */
00020 
00021 #ifdef HAVE_CONFIG_H
00022 # include <config.h>
00023 #endif
00024 
00025 #include "ac-stdint.h"
00026 
00027 #include <stdio.h>
00028 #include <stdlib.h>
00029 #include <stdarg.h>
00030 #include <time.h>
00031 #include <errno.h>
00032 #include <assert.h>
00033 
00034 #include <expat.h>
00035 
00036 #ifdef HAVE_SYS_TYPES_H
00037 # include <sys/types.h>
00038 #endif
00039 
00040 #ifdef HAVE_NETINET_IN_H
00041 # include <netinet/in.h>
00042 #endif
00043 
00044 #if defined(HAVE_SYS_TIME_H)
00045 # include <sys/time.h>
00046 #elif defined(HAVE_SYS_TIMEB_H)
00047 # include <sys/timeb.h>
00048 #endif
00049 #ifdef HAVE_SYSLOG_H
00050 # include <syslog.h>
00051 #endif
00052 #ifdef HAVE_UNISTD_H
00053 # include <unistd.h>
00054 #endif
00055 #include <ctype.h>
00056 
00057 #ifdef HAVE_SYS_SOCKET_H
00058 # include <sys/socket.h>
00059 #endif
00060 #ifdef HAVE_NETINET_IN_H
00061 # include <netinet/in.h>
00062 #endif
00063 #ifdef HAVE_ARPA_INET_H
00064 # include <arpa/inet.h>
00065 #endif
00066 
00067 #ifndef PATH_MAX
00068 #ifndef MAXPATHLEN
00069 # define PATH_MAX 512
00070 #else
00071 # define PATH_MAX MAXPATHLEN
00072 #endif
00073 #endif
00074 
00075 #ifdef USE_LIBSUBST
00076 #include "subst/subst.h"
00077 #endif
00078 
00079 #include "util/util_compat.h"
00080 
00081 #ifndef INCL_UTIL_H
00082 #define INCL_UTIL_H
00083 
00084 /* jabberd2 Windows DLL */
00085 #ifndef JABBERD2_API
00086 # ifdef _WIN32
00087 #  ifdef JABBERD2_EXPORTS
00088 #   define JABBERD2_API  __declspec(dllexport)
00089 #  else /* JABBERD2_EXPORTS */
00090 #   define JABBERD2_API  __declspec(dllimport)
00091 #  endif /* JABBERD2_EXPORTS */
00092 # else /* _WIN32 */
00093 #  define JABBERD2_API extern
00094 # endif /* _WIN32 */
00095 #endif /* JABBERD2_API */
00096 
00097 #ifdef __cplusplus
00098 extern "C" {
00099 #endif
00100 
00101 /* crypto hashing utils */
00102 #include "sha1.h"
00103 #include "md5.h"
00104 
00105 #include <util/nad.h>
00106 #include <util/pool.h>
00107 #include <util/xhash.h>
00108 
00109 /* --------------------------------------------------------- */
00110 /*                                                           */
00111 /* String management routines                                */
00112 /*                                                           */
00114 JABBERD2_API char *j_strdup(const char *str); /* provides NULL safe strdup wrapper */
00115 JABBERD2_API char *j_strcat(char *dest, char *txt); /* strcpy() clone */
00116 JABBERD2_API int j_strcmp(const char *a, const char *b); /* provides NULL safe strcmp wrapper */
00117 JABBERD2_API int j_strcasecmp(const char *a, const char *b); /* provides NULL safe strcasecmp wrapper */
00118 JABBERD2_API int j_strncmp(const char *a, const char *b, int i); /* provides NULL safe strncmp wrapper */
00119 JABBERD2_API int j_strncasecmp(const char *a, const char *b, int i); /* provides NULL safe strncasecmp wrapper */
00120 JABBERD2_API int j_strlen(const char *a); /* provides NULL safe strlen wrapper */
00121 JABBERD2_API int j_atoi(const char *a, int def); /* checks for NULL and uses default instead, convienence */
00122 JABBERD2_API char *j_attr(const char** atts, const char *attr); /* decode attr's (from expat) */
00123 JABBERD2_API char *j_strnchr(const char *s, int c, int n); /* like strchr, but only searches n chars */
00124 
00126 JABBERD2_API void shahash_r(const char* str, char hashbuf[41]);
00127 JABBERD2_API void shahash_raw(const char* str, unsigned char hashval[20]);
00128 
00129 /* --------------------------------------------------------- */
00130 /*                                                           */
00131 /* XML escaping utils                                        */
00132 /*                                                           */
00133 /* --------------------------------------------------------- */
00134 JABBERD2_API char *strescape(pool_t p, char *buf, int len); /* Escape <>&'" chars */
00135 JABBERD2_API char *strunescape(pool_t p, char *buf);
00136 
00137 
00138 /* --------------------------------------------------------- */
00139 /*                                                           */
00140 /* String pools (spool) functions                            */
00141 /*                                                           */
00142 /* --------------------------------------------------------- */
00143 struct spool_node
00144 {
00145     char *c;
00146     struct spool_node *next;
00147 };
00148 
00149 typedef struct spool_struct
00150 {
00151     pool_t p;
00152     int len;
00153     struct spool_node *last;
00154     struct spool_node *first;
00155 } *spool;
00156 
00157 JABBERD2_API spool spool_new(pool_t p); /* create a string pool */
00158 JABBERD2_API void spooler(spool s, ...); /* append all the char * args to the pool, terminate args with s again */
00159 JABBERD2_API char *spool_print(spool s); /* return a big string */
00160 JABBERD2_API void spool_add(spool s, char *str); /* add a single string to the pool */
00161 JABBERD2_API void spool_escape(spool s, char *raw, int len); /* add and xml escape a single string to the pool */
00162 JABBERD2_API char *spools(pool_t p, ...); /* wrap all the spooler stuff in one function, the happy fun ball! */
00163 
00164 
00165 /* known namespace uri */
00166 #include "util/uri.h"
00167 
00168 /* JID manipulation */
00169 #include "util/jid.h"
00170 
00171 /* logging */
00172 
00173 typedef enum {
00174     log_STDOUT,
00175     log_SYSLOG,
00176     log_FILE
00177 } log_type_t;
00178 
00179 typedef struct log_st
00180 {
00181     log_type_t  type;
00182     FILE        *file;
00183 } *log_t;
00184 
00185 typedef struct log_facility_st
00186 {
00187     const char  *facility;
00188     int         number;
00189 } log_facility_t;
00190 
00191 JABBERD2_API log_t    log_new(log_type_t type, const char *ident, const char *facility);
00192 JABBERD2_API void     log_write(log_t log, int level, const char *msgfmt, ...);
00193 JABBERD2_API void     log_free(log_t log);
00194 
00195 /* config files */
00196 typedef struct config_elem_st   *config_elem_t;
00197 typedef struct config_st        *config_t;
00198 
00200 struct config_st
00201 {
00202     xht                 hash;
00203     nad_t               nad;
00204 };
00205 
00207 struct config_elem_st
00208 {
00209     char                **values;
00210     int                 nvalues;
00211     char                ***attrs;
00212 };
00213 
00214 JABBERD2_API config_t         config_new(void);
00215 JABBERD2_API int              config_load(config_t c, const char *file);
00216 JABBERD2_API int              config_load_with_id(config_t c, const char *file, const char *id);
00217 JABBERD2_API config_elem_t    config_get(config_t c, const char *key);
00218 JABBERD2_API const char      *config_get_one(config_t c, const char *key, int num);
00219 JABBERD2_API const char      *config_get_one_default(config_t c, const char *key, int num, const char *default_value);
00220 JABBERD2_API int              config_count(config_t c, const char *key);
00221 JABBERD2_API char             *config_get_attr(config_t c, const char *key, int num, const char *attr);
00222 JABBERD2_API char             *config_expand(config_t c, const char *value); 
00223 JABBERD2_API void             config_free(config_t);
00224 
00225 
00226 /*
00227  * IP-based access controls
00228  */
00229 
00230 typedef struct access_rule_st
00231 {
00232     struct sockaddr_storage ip;
00233     int            mask;
00234 } *access_rule_t;
00235 
00236 typedef struct access_st
00237 {
00238     int             order;      /* 0 = allow,deny  1 = deny,allow */
00239 
00240     access_rule_t   allow;
00241     int             nallow;
00242 
00243     access_rule_t   deny;
00244     int             ndeny;
00245 } *access_t;
00246 
00247 JABBERD2_API access_t    access_new(int order);
00248 JABBERD2_API void        access_free(access_t access);
00249 JABBERD2_API int         access_allow(access_t access, char *ip, char *mask);
00250 JABBERD2_API int         access_deny(access_t access, char *ip, char *mask);
00251 JABBERD2_API int         access_check(access_t access, char *ip);
00252 
00253 
00254 /*
00255  * rate limiting
00256  */
00257 
00258 typedef struct rate_st
00259 {
00260     int             total;      /* if we exceed this many events */
00261     int             seconds;    /* in this many seconds */
00262     int             wait;       /* then go bad for this many seconds */
00263 
00264     time_t          time;       /* time we started counting events */
00265     int             count;      /* event count */
00266 
00267     time_t          bad;        /* time we went bad, or 0 if we're not */
00268 } *rate_t;
00269 
00270 JABBERD2_API rate_t      rate_new(int total, int seconds, int wait);
00271 JABBERD2_API void        rate_free(rate_t rt);
00272 JABBERD2_API void        rate_reset(rate_t rt);
00273 
00278 JABBERD2_API void        rate_add(rate_t rt, int count);
00279 
00285 JABBERD2_API int         rate_left(rate_t rt);
00286 
00292 JABBERD2_API int         rate_check(rate_t rt);
00293 
00294 /*
00295  * helpers for ip addresses
00296  */
00297 
00298 #include "inaddr.h"        /* used in mio as well */
00299 
00300 /*
00301  * serialisation helper functions
00302  */
00303 
00304 JABBERD2_API int         ser_string_get(char **dest, int *source, const char *buf, int len);
00305 JABBERD2_API int         ser_int_get(int *dest, int *source, const char *buf, int len);
00306 JABBERD2_API void        ser_string_set(char *source, int *dest, char **buf, int *len);
00307 JABBERD2_API void        ser_int_set(int source, int *dest, char **buf, int *len);
00308 
00309 /*
00310  * priority queues
00311  */
00312 
00313 typedef struct _jqueue_node_st  *_jqueue_node_t;
00314 struct _jqueue_node_st {
00315     void            *data;
00316 
00317     int             priority;
00318 
00319     _jqueue_node_t  next;
00320     _jqueue_node_t  prev;
00321 };
00322 
00323 typedef struct _jqueue_st {
00324     pool_t          p;
00325     _jqueue_node_t  cache;
00326 
00327     _jqueue_node_t  front;
00328     _jqueue_node_t  back;
00329 
00330     int             size;
00331     char            *key;
00332     time_t          init_time;
00333 } *jqueue_t;
00334 
00335 JABBERD2_API jqueue_t    jqueue_new(void);
00336 JABBERD2_API void        jqueue_free(jqueue_t q);
00337 JABBERD2_API void        jqueue_push(jqueue_t q, void *data, int pri);
00338 JABBERD2_API void        *jqueue_pull(jqueue_t q);
00339 JABBERD2_API int         jqueue_size(jqueue_t q);
00340 JABBERD2_API time_t      jqueue_age(jqueue_t q);
00341 
00342 
00343 /* ISO 8601 / JEP-0082 date/time manipulation */
00344 typedef enum {
00345     dt_DATE     = 1,
00346     dt_TIME     = 2,
00347     dt_DATETIME = 3,
00348     dt_LEGACY   = 4
00349 } datetime_t;
00350 
00351 JABBERD2_API time_t  datetime_in(char *date);
00352 JABBERD2_API void    datetime_out(time_t t, datetime_t type, char *date, int datelen);
00353 
00354 
00355 /* base64 functions */
00356 JABBERD2_API int apr_base64_decode_len(const char *bufcoded, int buflen);
00357 JABBERD2_API int apr_base64_decode(char *bufplain, const char *bufcoded, int buflen);
00358 JABBERD2_API int apr_base64_encode_len(int len);
00359 JABBERD2_API int apr_base64_encode(char *encoded, const char *string, int len);
00360 
00361 /* convenience, result string must be free()'d by caller */
00362 JABBERD2_API char *b64_encode(char *buf, int len);
00363 JABBERD2_API char *b64_decode(char *buf);
00364 
00365 
00366 /* stanza manipulation */
00367 #define stanza_err_BAD_REQUEST              (100)
00368 #define stanza_err_CONFLICT                 (101)
00369 #define stanza_err_FEATURE_NOT_IMPLEMENTED  (102)
00370 #define stanza_err_FORBIDDEN                (103)
00371 #define stanza_err_GONE                     (104)
00372 #define stanza_err_INTERNAL_SERVER_ERROR    (105)
00373 #define stanza_err_ITEM_NOT_FOUND           (106)
00374 #define stanza_err_JID_MALFORMED            (107)
00375 #define stanza_err_NOT_ACCEPTABLE           (108)
00376 #define stanza_err_NOT_ALLOWED              (109)
00377 #define stanza_err_PAYMENT_REQUIRED         (110)
00378 #define stanza_err_RECIPIENT_UNAVAILABLE    (111)
00379 #define stanza_err_REDIRECT                 (112)
00380 #define stanza_err_REGISTRATION_REQUIRED    (113)
00381 #define stanza_err_REMOTE_SERVER_NOT_FOUND  (114)
00382 #define stanza_err_REMOTE_SERVER_TIMEOUT    (115)
00383 #define stanza_err_RESOURCE_CONSTRAINT      (116)
00384 #define stanza_err_SERVICE_UNAVAILABLE      (117)
00385 #define stanza_err_SUBSCRIPTION_REQUIRED    (118)
00386 #define stanza_err_UNDEFINED_CONDITION      (119)
00387 #define stanza_err_UNEXPECTED_REQUEST       (120)
00388 #define stanza_err_OLD_UNAUTH               (121)
00389 #define stanza_err_UNKNOWN_SENDER           (122)
00390 #define stanza_err_LAST                     (123)
00391 
00392 JABBERD2_API nad_t stanza_error(nad_t nad, int elem, int err);
00393 JABBERD2_API nad_t stanza_tofrom(nad_t nad, int elem);
00394 
00395 typedef struct _stanza_error_st {
00396     const char  *name;
00397     const char  *type;
00398     const char  *code;
00399 } *stanza_error_t;
00400 
00401 JABBERD2_API struct _stanza_error_st _stanza_errors[];
00402 
00403 
00404 /* hex conversion utils */
00405 JABBERD2_API void hex_from_raw(char *in, int inlen, char *out);
00406 JABBERD2_API int hex_to_raw(char *in, int inlen, char *out);
00407 
00408 
00409 /* xdata in a seperate file */
00410 #include "xdata.h"
00411 
00412 
00413 /* debug logging */
00414 JABBERD2_API int get_debug_flag(void);
00415 JABBERD2_API void set_debug_flag(int v);
00416 JABBERD2_API void debug_log(const char *file, int line, const char *msgfmt, ...);
00417 JABBERD2_API int set_debug_file(const char *filename);
00418 
00419 JABBERD2_API int set_debug_log_from_config(config_t c);
00420 
00421 #define ZONE __FILE__,__LINE__
00422 #define MAX_DEBUG 8192
00423 
00424 /* if no debug, basically compile it out */
00425 #ifdef DEBUG
00426 #define log_debug if(get_debug_flag()) debug_log
00427 #else
00428 #define log_debug if(0) debug_log
00429 #endif
00430 
00431 /* Portable signal function */
00432 typedef void jsighandler_t(int);
00433 JABBERD2_API jsighandler_t* jabber_signal(int signo,  jsighandler_t *func);
00434 
00435 #ifdef _WIN32
00436 /* Windows service wrapper function */
00437 typedef int (jmainhandler_t)(int argc, char** argv);
00438 JABBERD2_API int jabber_wrap_service(int argc, char** argv, jmainhandler_t *wrapper, LPCTSTR name, LPCTSTR display, LPCTSTR description, LPCTSTR depends);
00439 #define JABBER_MAIN(name, display, description, depends) jabber_main(int argc, char** argv); \
00440                     main(int argc, char** argv) { return jabber_wrap_service(argc, argv, jabber_main, name, display, description, depends); } \
00441                     jabber_main(int argc, char** argv)
00442 #else /* _WIN32 */
00443 #define JABBER_MAIN(name, display, description, depends) int main(int argc, char** argv)
00444 #endif /* _WIN32 */
00445 
00446 #ifdef __cplusplus
00447 }
00448 #endif
00449 
00450 #if XML_MAJOR_VERSION > 1
00451 /* XML_StopParser is present in expat 2.x */
00452 #define HAVE_XML_STOPPARSER
00453 #endif
00454 
00455 /* define TRUE and FALSE if not yet defined */
00456 #ifndef TRUE
00457 #define TRUE 1
00458 #endif
00459 #ifndef FALSE
00460 #define FALSE 0
00461 #endif
00462 
00463 #endif    /* INCL_UTIL_H */
00464 
00465