jabberd2
2.2.16
|
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