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