[265] | 1 | #include "config_xor.h"
|
---|
| 2 |
|
---|
| 3 | #ifdef USE_LOGFILE_MONITOR
|
---|
| 4 |
|
---|
| 5 | #include <string.h>
|
---|
| 6 | #include <ctype.h>
|
---|
| 7 |
|
---|
| 8 | #undef FIL__
|
---|
| 9 | #define FIL__ _("sh_log_repeat.c")
|
---|
| 10 |
|
---|
| 11 | #include "samhain.h"
|
---|
| 12 | #include "sh_pthread.h"
|
---|
| 13 | #include "sh_utils.h"
|
---|
| 14 | #include "sh_string.h"
|
---|
| 15 | #include "sh_log_check.h"
|
---|
| 16 | #include "sh_log_evalrule.h"
|
---|
| 17 |
|
---|
| 18 | #define SH_NHIST 12
|
---|
| 19 | #define SH_NFINT 5
|
---|
| 20 | #define SH_NFIELDS 5*sizeof(SINT32) /* 16 */
|
---|
| 21 | #define SH_NBLOCK 63
|
---|
| 22 |
|
---|
| 23 | typedef enum
|
---|
| 24 | {
|
---|
| 25 | SH_GFLAG_EMAIL = 1 << 0,
|
---|
| 26 | SH_GFLAG_PATH = 1 << 1,
|
---|
| 27 | SH_GFLAG_IP = 1 << 2,
|
---|
| 28 | SH_GFLAG_FQDN = 1 << 3,
|
---|
| 29 | SH_GFLAG_NUM = 1 << 4,
|
---|
| 30 | SH_GFLAG_ELSE = 1 << 5,
|
---|
| 31 |
|
---|
| 32 | SH_GFLAG_XNUM = 1 << 6,
|
---|
| 33 | SH_GFLAG_CHAR = 1 << 7,
|
---|
| 34 | SH_GFLAG_USC = 1 << 8
|
---|
| 35 | } SH_GFlags;
|
---|
| 36 |
|
---|
| 37 |
|
---|
| 38 | /* 64 bytes
|
---|
| 39 | */
|
---|
| 40 | struct gestalt {
|
---|
| 41 | unsigned char hist[SH_NHIST]; /* time histogram 12 minutes */
|
---|
| 42 | union {
|
---|
| 43 | unsigned char flags[SH_NFIELDS]; /* flags indicating field type */
|
---|
| 44 | SINT32 flint[SH_NFINT];
|
---|
| 45 | } f;
|
---|
| 46 | UINT16 sum[SH_NFIELDS]; /* checksum of field */
|
---|
| 47 | UINT16 ltime; /* last time, in minutes */
|
---|
| 48 | UINT16 total; /* seen how often? */
|
---|
| 49 | };
|
---|
| 50 |
|
---|
| 51 | static unsigned int nrec = 0; /* size of array */
|
---|
| 52 | static unsigned int urec = 0; /* in use thereof */
|
---|
| 53 | static struct gestalt * arec = NULL; /* array */
|
---|
| 54 |
|
---|
| 55 | static int repeat_count = 24; /* triggers report */
|
---|
| 56 | static int clean_counter = 0; /* cleanup after N inserts */
|
---|
| 57 | static int free_slots = 0; /* free slots available */
|
---|
| 58 |
|
---|
| 59 | #define SH_CLEANUP 256
|
---|
| 60 |
|
---|
| 61 | static struct gestalt * add_entry (unsigned char * flags, UINT16 * sum,
|
---|
| 62 | time_t ltime)
|
---|
| 63 | {
|
---|
| 64 | struct gestalt * array = NULL;
|
---|
| 65 |
|
---|
| 66 | start:
|
---|
| 67 | if (urec < nrec)
|
---|
| 68 | {
|
---|
| 69 | if (free_slots)
|
---|
| 70 | {
|
---|
| 71 | unsigned int i;
|
---|
| 72 | for (i = 0; i < urec; ++i)
|
---|
| 73 | {
|
---|
| 74 | if (arec[i].total == 0)
|
---|
| 75 | {
|
---|
| 76 | array = &arec[i];
|
---|
| 77 | --free_slots;
|
---|
| 78 | break;
|
---|
| 79 | }
|
---|
| 80 | }
|
---|
| 81 | }
|
---|
| 82 |
|
---|
| 83 | if (!array)
|
---|
| 84 | {
|
---|
| 85 | array = &arec[urec];
|
---|
| 86 | ++urec;
|
---|
| 87 | }
|
---|
| 88 |
|
---|
| 89 | memcpy(array->sum, sum, sizeof(UINT16) * SH_NFIELDS);
|
---|
| 90 | memcpy(array->f.flags, flags, sizeof(unsigned char) * SH_NFIELDS);
|
---|
| 91 | memset(array->hist, 0, sizeof(unsigned char) * SH_NHIST);
|
---|
| 92 |
|
---|
| 93 | array->ltime = (UINT16)(ltime % 60);
|
---|
| 94 | array->hist[SH_NHIST-1] = 1;
|
---|
| 95 | array->total = 1;
|
---|
| 96 |
|
---|
| 97 | ++clean_counter;
|
---|
| 98 | return array;
|
---|
| 99 | }
|
---|
| 100 |
|
---|
| 101 | array = SH_ALLOC(sizeof(struct gestalt) * (nrec + SH_NBLOCK + 1));
|
---|
| 102 | memset(array, 0, sizeof(struct gestalt) * (nrec + SH_NBLOCK + 1));
|
---|
| 103 | memcpy(array, arec, sizeof(struct gestalt) * (nrec));
|
---|
| 104 |
|
---|
| 105 | nrec += (SH_NBLOCK + 1);
|
---|
| 106 | goto start;
|
---|
| 107 | }
|
---|
| 108 |
|
---|
| 109 | static UINT16 shift_history(unsigned char * hist, unsigned int shift,
|
---|
| 110 | UINT16 total)
|
---|
| 111 | {
|
---|
| 112 | unsigned int i, j = 0;
|
---|
| 113 |
|
---|
| 114 | if (shift >= SH_NHIST)
|
---|
| 115 | {
|
---|
| 116 | memset(hist, 0, sizeof(unsigned char) * SH_NHIST);
|
---|
| 117 | return 0;
|
---|
| 118 | }
|
---|
| 119 |
|
---|
| 120 | for (i = shift; i < SH_NHIST; ++i)
|
---|
| 121 | {
|
---|
| 122 | if (j < shift)
|
---|
| 123 | total -= hist[j];
|
---|
| 124 | hist[j] = hist[i];
|
---|
| 125 | ++j;
|
---|
| 126 | }
|
---|
| 127 | for (i = (SH_NHIST-shift); i < SH_NHIST; ++i)
|
---|
| 128 | {
|
---|
| 129 | hist[i] = 0;
|
---|
| 130 | }
|
---|
| 131 | return total;
|
---|
| 132 | }
|
---|
| 133 |
|
---|
| 134 | static void update_entry (struct gestalt * array, time_t ltime)
|
---|
| 135 | {
|
---|
| 136 | UINT16 ntime = (UINT16)(ltime % 60);
|
---|
| 137 |
|
---|
| 138 | if (array->ltime == ntime)
|
---|
| 139 | {
|
---|
| 140 | if (array->hist[SH_NHIST-1] < 255)
|
---|
| 141 | {
|
---|
| 142 | ++(array->hist[SH_NHIST-1]);
|
---|
| 143 | ++(array->total);
|
---|
| 144 | }
|
---|
| 145 | }
|
---|
| 146 | else if (array->ltime < ntime)
|
---|
| 147 | {
|
---|
| 148 | unsigned int shift = ntime - array->ltime;
|
---|
| 149 | array->total = shift_history(array->hist, shift, array->total);
|
---|
| 150 | array->hist[SH_NHIST-1] = 1;
|
---|
| 151 | array->ltime = ntime;
|
---|
| 152 | ++(array->total);
|
---|
| 153 | }
|
---|
| 154 | }
|
---|
| 155 |
|
---|
| 156 | static struct gestalt * update_or_add (unsigned char * flags, UINT16 * sum,
|
---|
| 157 | time_t ltime)
|
---|
| 158 | {
|
---|
| 159 | SINT32 flint[SH_NFINT];
|
---|
| 160 | start:
|
---|
| 161 |
|
---|
| 162 | if (arec)
|
---|
| 163 | {
|
---|
| 164 | unsigned int i;
|
---|
| 165 | struct gestalt * array = arec;
|
---|
| 166 |
|
---|
| 167 | memcpy(flint, flags, SH_NFIELDS);
|
---|
| 168 |
|
---|
| 169 | for (i = 0; i < urec; ++i)
|
---|
| 170 | {
|
---|
| 171 | /* Check whether field types match. Integer
|
---|
| 172 | * comparison is much faster than memcmp() [tested].
|
---|
| 173 | */
|
---|
| 174 | if (flint[0] == array->f.flint[0] &&
|
---|
| 175 | flint[1] == array->f.flint[1] &&
|
---|
| 176 | flint[2] == array->f.flint[2] &&
|
---|
| 177 | flint[3] == array->f.flint[3] &&
|
---|
| 178 | flint[4] == array->f.flint[4])
|
---|
| 179 | {
|
---|
| 180 | unsigned int j;
|
---|
| 181 | int c1 = 0, c2 = 0;
|
---|
| 182 | UINT16 * asum = array->sum;
|
---|
| 183 |
|
---|
| 184 | for (j = 0; j < SH_NFIELDS; ++j)
|
---|
| 185 | {
|
---|
| 186 | if (flags[j] == SH_GFLAG_ELSE)
|
---|
| 187 | {
|
---|
| 188 | ++c1;
|
---|
| 189 | if (asum[j] == sum[j])
|
---|
| 190 | ++c2;
|
---|
| 191 | }
|
---|
| 192 | }
|
---|
| 193 |
|
---|
| 194 | if (c1 == c2)
|
---|
| 195 | {
|
---|
| 196 | /* Found a matching entry, update time histogram
|
---|
| 197 | */
|
---|
| 198 | update_entry (array, ltime);
|
---|
| 199 | return array;
|
---|
| 200 | }
|
---|
| 201 | }
|
---|
| 202 | ++array;
|
---|
| 203 | }
|
---|
| 204 |
|
---|
| 205 | /* No match found, create a new entry
|
---|
| 206 | */
|
---|
| 207 | array = add_entry (flags, sum, ltime);
|
---|
| 208 | return array;
|
---|
| 209 | }
|
---|
| 210 |
|
---|
| 211 | arec = SH_ALLOC(sizeof(struct gestalt) * SH_NBLOCK);
|
---|
| 212 | nrec = SH_NBLOCK;
|
---|
| 213 | urec = 0;
|
---|
| 214 |
|
---|
| 215 | goto start;
|
---|
| 216 | }
|
---|
| 217 |
|
---|
| 218 | /* --------------------------------------------------------------------
|
---|
| 219 | *
|
---|
| 220 | * crc16 checksum from the linux kernel.
|
---|
| 221 | * This source code is licensed under the GNU General Public License,
|
---|
| 222 | * Version 2.
|
---|
| 223 | */
|
---|
| 224 |
|
---|
| 225 | /** CRC table for the CRC-16. The poly is 0x8005 (x^16 + x^15 + x^2 + 1) */
|
---|
| 226 | UINT16 const crc16_table[256] = {
|
---|
| 227 | 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
|
---|
| 228 | 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
|
---|
| 229 | 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
|
---|
| 230 | 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
|
---|
| 231 | 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
|
---|
| 232 | 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
|
---|
| 233 | 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
|
---|
| 234 | 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
|
---|
| 235 | 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
|
---|
| 236 | 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
|
---|
| 237 | 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
|
---|
| 238 | 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
|
---|
| 239 | 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
|
---|
| 240 | 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
|
---|
| 241 | 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
|
---|
| 242 | 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
|
---|
| 243 | 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
|
---|
| 244 | 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
|
---|
| 245 | 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
|
---|
| 246 | 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
|
---|
| 247 | 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
|
---|
| 248 | 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
|
---|
| 249 | 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
|
---|
| 250 | 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
|
---|
| 251 | 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
|
---|
| 252 | 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
|
---|
| 253 | 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
|
---|
| 254 | 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
|
---|
| 255 | 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
|
---|
| 256 | 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
|
---|
| 257 | 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
|
---|
| 258 | 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
|
---|
| 259 | };
|
---|
| 260 |
|
---|
| 261 | static inline UINT16 crc16_byte(UINT16 crc, const unsigned char data)
|
---|
| 262 | {
|
---|
| 263 | return (crc >> 8) ^ crc16_table[(crc ^ data) & 0xff];
|
---|
| 264 | }
|
---|
| 265 |
|
---|
| 266 | /**
|
---|
| 267 | * crc16 - compute the CRC-16 for the data buffer
|
---|
| 268 | * @crc: previous CRC value
|
---|
| 269 | * @buffer: data pointer
|
---|
| 270 | * @len: number of bytes in the buffer
|
---|
| 271 | *
|
---|
| 272 | * Returns the updated CRC value.
|
---|
| 273 | */
|
---|
| 274 | static inline UINT16 crc16(UINT16 crc, const unsigned char * buffer,
|
---|
| 275 | size_t len)
|
---|
| 276 | {
|
---|
| 277 | while (len--)
|
---|
| 278 | crc = crc16_byte(crc, *buffer++);
|
---|
| 279 | return crc;
|
---|
| 280 | }
|
---|
| 281 |
|
---|
| 282 |
|
---|
| 283 | /* end crc16 code
|
---|
| 284 | *
|
---|
| 285 | * -------------------------------------------------------------------- */
|
---|
| 286 |
|
---|
| 287 | static void classify(char ** splits, size_t * lengths, unsigned int nfields,
|
---|
| 288 | unsigned char * flags, UINT16 * sums)
|
---|
| 289 | {
|
---|
| 290 | unsigned int i;
|
---|
| 291 | unsigned int flag;
|
---|
| 292 |
|
---|
| 293 | /* flags we don't want to see in XYZ
|
---|
| 294 | */
|
---|
| 295 | static int m_ip = SH_GFLAG_PATH|SH_GFLAG_EMAIL|SH_GFLAG_USC|SH_GFLAG_ELSE|SH_GFLAG_CHAR|SH_GFLAG_XNUM;
|
---|
| 296 | static int m_num = SH_GFLAG_PATH|SH_GFLAG_EMAIL|SH_GFLAG_USC|SH_GFLAG_ELSE|SH_GFLAG_CHAR;
|
---|
| 297 | static int m_fqdn = SH_GFLAG_PATH|SH_GFLAG_EMAIL|SH_GFLAG_USC|SH_GFLAG_ELSE;
|
---|
| 298 | static int m_email = SH_GFLAG_PATH;
|
---|
| 299 |
|
---|
| 300 | nfields = (nfields > SH_NFIELDS) ? SH_NFIELDS : nfields;
|
---|
| 301 |
|
---|
| 302 | for (i = 0; i < nfields; ++i)
|
---|
| 303 | {
|
---|
| 304 | char *p = splits[i];
|
---|
| 305 | unsigned int np = 0;
|
---|
| 306 | unsigned int fqdn = 0;
|
---|
| 307 |
|
---|
| 308 | flag = 0;
|
---|
| 309 |
|
---|
| 310 | while (*p)
|
---|
| 311 | {
|
---|
| 312 | if (isxdigit((unsigned int)*p))
|
---|
| 313 | {
|
---|
| 314 | if (isdigit((unsigned int)*p))
|
---|
| 315 | {
|
---|
| 316 | flag |= SH_GFLAG_NUM;
|
---|
| 317 | }
|
---|
| 318 | else
|
---|
| 319 | {
|
---|
| 320 | flag |= SH_GFLAG_XNUM;
|
---|
| 321 | }
|
---|
| 322 | }
|
---|
| 323 | else if (*p == '.')
|
---|
| 324 | {
|
---|
| 325 | flag |= SH_GFLAG_IP;
|
---|
| 326 | ++np;
|
---|
| 327 | }
|
---|
| 328 | else if (*p == '/')
|
---|
| 329 | {
|
---|
| 330 | flag |= SH_GFLAG_PATH;
|
---|
| 331 | }
|
---|
| 332 | else if (*p == '@')
|
---|
| 333 | {
|
---|
| 334 | flag |= SH_GFLAG_EMAIL;
|
---|
| 335 | }
|
---|
| 336 | else if (*p == '-')
|
---|
| 337 | {
|
---|
| 338 | flag |= SH_GFLAG_FQDN;
|
---|
| 339 | }
|
---|
| 340 | else if (*p == '_')
|
---|
| 341 | {
|
---|
| 342 | flag |= SH_GFLAG_USC;
|
---|
| 343 | }
|
---|
| 344 | else if (isalpha((unsigned int)*p))
|
---|
| 345 | {
|
---|
| 346 | if (flag & SH_GFLAG_IP)
|
---|
| 347 | ++fqdn;
|
---|
| 348 | flag |= SH_GFLAG_CHAR;
|
---|
| 349 | }
|
---|
| 350 | else if (!isascii((unsigned int)*p))
|
---|
| 351 | {
|
---|
| 352 | flags[i] = SH_GFLAG_ELSE;
|
---|
| 353 | break;
|
---|
| 354 | }
|
---|
| 355 | else
|
---|
| 356 | {
|
---|
| 357 | flag |= SH_GFLAG_ELSE;
|
---|
| 358 | }
|
---|
| 359 | ++p;
|
---|
| 360 | }
|
---|
| 361 |
|
---|
| 362 | if (flags[i] == 0)
|
---|
| 363 | {
|
---|
| 364 | if (0 == (flag & m_ip) &&
|
---|
| 365 | 0 != (flag & SH_GFLAG_IP) &&
|
---|
| 366 | 0 != (flag & SH_GFLAG_NUM) &&
|
---|
| 367 | np > 2)
|
---|
| 368 | {
|
---|
| 369 | flags[i] = SH_GFLAG_IP;
|
---|
| 370 | }
|
---|
| 371 | else if (0 == (flag & m_num) &&
|
---|
| 372 | (0 != (flag & SH_GFLAG_NUM) || 0 != (flag & SH_GFLAG_XNUM)))
|
---|
| 373 | {
|
---|
| 374 | flags[i] = SH_GFLAG_NUM;
|
---|
| 375 | }
|
---|
| 376 | else if (0 == (flag & m_fqdn) &&
|
---|
| 377 | 0 != (flag & SH_GFLAG_IP) &&
|
---|
| 378 | 0 != (flag & SH_GFLAG_CHAR) &&
|
---|
| 379 | fqdn)
|
---|
| 380 | {
|
---|
| 381 | flags[i] = SH_GFLAG_FQDN;
|
---|
| 382 | }
|
---|
| 383 | else if ('/' == splits[i][0])
|
---|
| 384 | {
|
---|
| 385 | flags[i] = SH_GFLAG_PATH;
|
---|
| 386 | }
|
---|
| 387 | else if (0 == (flag & m_email) &&
|
---|
| 388 | 0 != (flag & SH_GFLAG_EMAIL) &&
|
---|
| 389 | 0 != (flag & SH_GFLAG_CHAR))
|
---|
| 390 | {
|
---|
| 391 | flags[i] = SH_GFLAG_EMAIL;
|
---|
| 392 | }
|
---|
| 393 | else
|
---|
| 394 | {
|
---|
| 395 | flags[i] = SH_GFLAG_ELSE;
|
---|
| 396 | }
|
---|
| 397 | }
|
---|
| 398 |
|
---|
| 399 | /* CRC-16 checksum
|
---|
| 400 | */
|
---|
| 401 | sums[i] = crc16(0, (unsigned char *) splits[i], lengths[i]);
|
---|
| 402 | }
|
---|
| 403 |
|
---|
| 404 | return;
|
---|
| 405 | }
|
---|
| 406 |
|
---|
| 407 | static void cleanup_array (time_t ltime)
|
---|
| 408 | {
|
---|
| 409 | UINT16 ntime = (UINT16)(ltime % 60);
|
---|
| 410 |
|
---|
| 411 | if (ntime > 12) ntime -= 12;
|
---|
| 412 |
|
---|
| 413 | if (arec && urec > 0)
|
---|
| 414 | {
|
---|
| 415 | struct gestalt * array;
|
---|
| 416 | unsigned int i, last, urec_orig = urec;
|
---|
| 417 |
|
---|
| 418 | last = urec-1;
|
---|
| 419 | array = &arec[0];
|
---|
| 420 |
|
---|
| 421 | for (i = 0; i < urec_orig; ++i)
|
---|
| 422 | {
|
---|
| 423 | if (array->ltime < ntime)
|
---|
| 424 | {
|
---|
| 425 | memset(array, 0, sizeof(struct gestalt));
|
---|
| 426 | if (i != last)
|
---|
| 427 | ++free_slots;
|
---|
| 428 | else
|
---|
| 429 | --urec;
|
---|
| 430 | }
|
---|
| 431 | }
|
---|
| 432 | ++array;
|
---|
| 433 | }
|
---|
| 434 | clean_counter = 0;
|
---|
| 435 | return;
|
---|
| 436 | }
|
---|
| 437 |
|
---|
| 438 | /* ----------------------------------------------------------------------
|
---|
| 439 | *
|
---|
| 440 | * Public functions
|
---|
| 441 | */
|
---|
| 442 |
|
---|
| 443 | int sh_repeat_set_trigger (const char * str)
|
---|
| 444 | {
|
---|
| 445 | unsigned long value;
|
---|
| 446 | char * foo;
|
---|
| 447 |
|
---|
| 448 | value = (size_t) strtoul(str, &foo, 0);
|
---|
| 449 |
|
---|
| 450 | if (*foo == '\0' && value < 65535) {
|
---|
| 451 | repeat_count = value;
|
---|
| 452 | return 0;
|
---|
| 453 | }
|
---|
| 454 | return -1;
|
---|
| 455 | }
|
---|
| 456 |
|
---|
| 457 | static char * sh_repeat_queue = NULL;
|
---|
| 458 |
|
---|
| 459 | int sh_repeat_set_queue (const char * str)
|
---|
| 460 | {
|
---|
| 461 | if (!str)
|
---|
| 462 | return -1;
|
---|
| 463 | if (sh_repeat_queue)
|
---|
| 464 | SH_FREE(sh_repeat_queue);
|
---|
| 465 | sh_repeat_queue = sh_util_strdup(str);
|
---|
| 466 | return 0;
|
---|
| 467 | }
|
---|
| 468 |
|
---|
| 469 | static int sh_repeat_cron = S_FALSE;
|
---|
| 470 |
|
---|
| 471 | int sh_repeat_set_cron (const char * str)
|
---|
| 472 | {
|
---|
| 473 | return sh_util_flagval(str, &sh_repeat_cron);
|
---|
| 474 | }
|
---|
| 475 |
|
---|
| 476 | int sh_repeat_message_check (const sh_string * host,
|
---|
| 477 | const sh_string * msg,
|
---|
| 478 | time_t ltime)
|
---|
| 479 | {
|
---|
| 480 | struct gestalt * array;
|
---|
| 481 |
|
---|
| 482 | UINT16 sums[SH_NFIELDS] = { 0 };
|
---|
| 483 | unsigned char flags[SH_NFIELDS] = { 0 };
|
---|
| 484 |
|
---|
| 485 | /* split message into SH_NFIELDS+1, discard last */
|
---|
| 486 |
|
---|
| 487 | unsigned int nfields = SH_NFIELDS+1;
|
---|
| 488 | size_t lengths[SH_NFIELDS+1];
|
---|
| 489 | char * new;
|
---|
| 490 | char ** splits;
|
---|
| 491 |
|
---|
| 492 | if (repeat_count == 0)
|
---|
| 493 | return 0;
|
---|
| 494 |
|
---|
| 495 | if (sh_repeat_cron == S_FALSE)
|
---|
| 496 | {
|
---|
| 497 | char * s = sh_string_str(msg);
|
---|
| 498 |
|
---|
| 499 | if (0 == strcmp(s, _("cron")) || 0 == strcmp(s, _("CRON")))
|
---|
| 500 | return 0;
|
---|
| 501 | }
|
---|
| 502 |
|
---|
| 503 | new = sh_util_strdup_l(sh_string_str(msg), sh_string_len(msg));
|
---|
| 504 |
|
---|
| 505 | splits = split_array_token (new, &nfields, lengths,
|
---|
| 506 | " :,()='[]<>\t\n");
|
---|
| 507 |
|
---|
| 508 | /* classify fields */
|
---|
| 509 |
|
---|
| 510 | classify (splits, lengths, nfields, flags, sums);
|
---|
| 511 |
|
---|
| 512 | /* compare */
|
---|
| 513 |
|
---|
| 514 | array = update_or_add (flags, sums, ltime);
|
---|
| 515 |
|
---|
| 516 | /* report */
|
---|
| 517 |
|
---|
| 518 | if (array->total > repeat_count)
|
---|
| 519 | {
|
---|
| 520 | volatile int repeat = array->total;
|
---|
| 521 | char * tmpmsg;
|
---|
| 522 | char * tmphost;
|
---|
| 523 |
|
---|
| 524 | /* issue report */
|
---|
| 525 |
|
---|
| 526 | SH_MUTEX_LOCK(mutex_thread_nolog);
|
---|
| 527 | tmphost = sh_util_safe_name (sh_string_str(host));
|
---|
| 528 | tmpmsg = sh_util_safe_name_keepspace (sh_string_str(msg));
|
---|
| 529 | sh_error_handle (sh_log_lookup_severity(sh_repeat_queue),
|
---|
| 530 | FIL__, __LINE__, 0, MSG_LOGMON_BURST,
|
---|
| 531 | repeat, tmpmsg, tmphost);
|
---|
| 532 | SH_FREE(tmpmsg);
|
---|
| 533 | SH_FREE(tmphost);
|
---|
| 534 | SH_MUTEX_UNLOCK(mutex_thread_nolog);
|
---|
| 535 |
|
---|
| 536 | /* mark slot as free */
|
---|
| 537 |
|
---|
| 538 | memset(array, 0, sizeof(struct gestalt));
|
---|
| 539 | if (array != &arec[urec-1])
|
---|
| 540 | ++free_slots;
|
---|
| 541 | else
|
---|
| 542 | urec -= 1;
|
---|
| 543 | }
|
---|
| 544 |
|
---|
| 545 | SH_FREE(new);
|
---|
| 546 |
|
---|
| 547 | /* run cleanup routine */
|
---|
| 548 |
|
---|
| 549 | if (clean_counter >= SH_CLEANUP)
|
---|
| 550 | {
|
---|
| 551 | cleanup_array(ltime);
|
---|
| 552 | }
|
---|
| 553 |
|
---|
| 554 | return 0;
|
---|
| 555 | }
|
---|
| 556 |
|
---|
| 557 | #endif
|
---|