#include #include #include #include #include #include #include #include using namespace std; #define DEBUG (0) //#define LOG_NAME (1) #define MAX_READ (8192) #define MAX_PATH (1024) #define OFFSET (10) #define MAX_PROCESS_NUMBER (1024 * 1024) /* a-z A-Z 0-9 */ /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ static bool username_t[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0x00 - 0x0F 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0x10 - 0x1F 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0x20 - 0x2F !"#$%&'()*+,-./ 1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0, // 0x30 - 0x3F 0123456789:;<=>? 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x40 - 0x4F @ABCDEFGHJIKLMNO 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0, // 0x50 - 0x5F PQRSTUVWXYZ[\]^_ 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x60 - 0x6F `abcdefghijklmno 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0 // 0x70 - 0x7F pqrstuvwxyz{|}~ }; /* 0-9 */ /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ static bool number_t[] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0x00 - 0x0F 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0x10 - 0x1F 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0x20 - 0x2F !"#$%&'()*+,-./ 1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0, // 0x30 - 0x3F 0123456789:;<=>? 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0x40 - 0x4F @ABCDEFGHJIKLMNO 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0x50 - 0x5F PQRSTUVWXYZ[\]^_ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0x60 - 0x6F `abcdefghijklmno 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 // 0x70 - 0x7F pqrstuvwxyz{|}~ }; static int monthly_t[] = { 12, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 8, 0, 0, 3, 0, 0, 4, 0, 0,10, 5, 9, 0, 0, 7, 0, 6, 0, 0, 0, 0, 0,11 }; /* ======================================================================= * * ======================================================================= */ class Logbuffer { private: int intr; char *buffer, *user, *date, *path; char *body, *head, *tmp; char sz_buffer[MAX_READ + OFFSET]; char sz_date[MAX_PATH]; char sz_path[MAX_PATH]; char sz_user[MAX_PATH]; bool check_userdir(void); bool check_request_path(void); bool get_path(void); bool get_request_data(void); public: Logbuffer(void); void loop(void); bool string_comp(char *ptr, char *pattern); }; /* ======================================================================= * * ======================================================================= */ Logbuffer::Logbuffer(void) { buffer = sz_buffer; date = sz_date; path = sz_path; user = sz_user; memset(sz_buffer, 0, MAX_READ + OFFSET); memset(sz_date, 0, MAX_PATH); memset(sz_path, 0, MAX_PATH); memset(sz_user, 0, MAX_PATH); } /* ======================================================================= * * ======================================================================= */ void Logbuffer::loop(void) { int i, n; struct stat st; FILE *fp; map files; map::iterator itr; while (true) { for (i = 0; i < MAX_PROCESS_NUMBER; i++) { memset(sz_buffer, 0, MAX_READ + OFFSET); memset(sz_date, 0, MAX_PATH); memset(sz_path, 0, MAX_PATH); memset(sz_user, 0, MAX_PATH); fgets(buffer, MAX_READ, stdin); body = buffer; #if DEBUG cout << "pass: 1" << '\n'; if ( check_userdir() ) continue; cout << "pass: 2" << '\n'; if ( get_path() ) continue; cout << "pass: 3" << '\n'; if ( check_request_path() ) continue; cout << "pass: 4" << '\n'; if ( get_request_data() ) continue; cout << "pass: 5" << '\n'; if ( !(fp = files[path]) || stat(path, &st) ) { cout << "make: " << path << '\n'; if ( !(fp = fopen(path, "a")) ) continue; files[path] = fp; } else { cout << "cache: " << path << '\n'; } cout << "write: " << body; #else if ( check_userdir() ) continue; if ( get_path() ) continue; if ( check_request_path() ) continue; if ( get_request_data() ) continue; if ( !(fp = files[path]) || stat(path, &st) ) { if ( !(fp = fopen(path, "a")) ) continue; files[path] = fp; } #endif fputs(body, fp); fflush(fp); } itr = files.begin(); n = (int)files.size(); for (i = 0; i < n; i++) { fclose(itr->second); itr++; } files.clear(); } } /* ======================================================================= * * ======================================================================= */ bool Logbuffer::check_userdir(void) { char *str; if (*body != '/') return(true); if ( !(tmp = strchr(body, ' ')) ) return(true); *tmp++ = '\x00'; body = tmp; while (*tmp) tmp++; if (*--tmp != '\n') return(true); if ( !(head = strchr(body, '"')) ) return(true); if ( !(tmp = strchr(head, ' ')) ) return(true); head++; tmp++; if (*tmp++ != '/') return(true); if (*tmp == '~') { tmp++; } else if ( *tmp == '%' && tmp[1] == '7' && (tmp[2] == 'E' || tmp[2] == 'e') ) { tmp += 3; } else { return(false); } intr = 16; str = user; while (*tmp && username_t[(int)*tmp] && intr--) { *str++ = *tmp++; } return(false); } /* ======================================================================= * * ======================================================================= */ bool Logbuffer::get_path(void) { if (strlen(buffer) >= 1000) return(true); strcpy(path, buffer); if (*user) { if (!(tmp = strrchr(path, '/'))) return(true); *tmp = '\x00'; strcat(path, user); if (!(tmp = strrchr(buffer, '/'))) return(true); strcat(path, tmp); } return(false); } /* ======================================================================= * * ======================================================================= */ bool Logbuffer::get_request_data(void) { if ( !(tmp = strchr(body, '[')) ) return(true); if (!tmp) return(true); if (*++tmp) date[640] = *tmp; if (*++tmp) date[641] = *tmp; if (*++tmp != '/') return(true); if (*++tmp) intr = *tmp; if (*++tmp) intr += *tmp; if (*++tmp) intr += *tmp; if (*++tmp != '/') return(true); if (*++tmp) date[512] = *tmp; if (*++tmp) date[513] = *tmp; if (*++tmp) date[514] = *tmp; if (*++tmp) date[515] = *tmp; if (*++tmp != ':') return(true); #ifdef LOG_NAME if (*++tmp) date[768] = *tmp; if (*++tmp) date[769] = *tmp; if (*++tmp != ':') return(true); if (number_t[(int)date[768]] == 0) return(true); if (number_t[(int)date[769]] == 0) return(true); #endif if (number_t[(int)date[512]] == 0) return(true); if (number_t[(int)date[513]] == 0) return(true); if (number_t[(int)date[514]] == 0) return(true); if (number_t[(int)date[515]] == 0) return(true); if (number_t[(int)date[640]] == 0) return(true); if (number_t[(int)date[641]] == 0) return(true); intr -= 268; if (monthly_t[intr] == 0) return(true); #ifdef LOG_NAME sprintf(date, "_%s%02d%s%s", date + 512, monthly_t[intr], date + 640, date + 768); #else sprintf(date, "_%s%02d%s", date + 512, monthly_t[intr], date + 640); #endif strcat(path, date); return(false); } /* ======================================================================= * * ======================================================================= */ bool Logbuffer::check_request_path(void) { if (!string_comp(head, "SEARCH")) return(true); if (!string_comp(head, "GET /default.ida")) return(true); if (!string_comp(head, "GET /NULL.IDA")) return(true); if (!string_comp(path, "/var/httpd/")) return(false); if (!string_comp(path, "/home/.logs/")) return(false); #if DEBUG if (!string_comp(path, "/home/")) return(false); if (!string_comp(path, "/tmp/")) return(false); #endif return(true); } /* ======================================================================= * * ======================================================================= */ bool Logbuffer::string_comp(char *ptr, char *pattern) { while (*ptr) { if (*ptr != *pattern) return(true); ptr++, pattern++; if (!*pattern) return(false); } return(true); } /* ======================================================================= * Main * ======================================================================= */ int main(void) { Logbuffer lb; lb.loop(); return(0); }