Spider::Spider() : db_name_(), db_server_(), db_user_(), db_password_() { openlog("spider", LOG_CONS | LOG_ODELAY, LOG_USER); mime_type_attr_ = NULL; pserver_manager_ = NULL; result_ = NULL; if (smbc_init(libsmbmm_guest_auth_smbc_get_data, 0) < 0) { DetectError(); MSS_FATAL("smbc_init", error_); return; } // Create a directory to store file headers. if (mkdir(TMPDIR, 00744 /* rwxr--r-- */) && errno != EEXIST) { DetectError(); MSS_ERROR("mkdir", error_); return; } // Prepare to work with libmagic if ((cookie_ = magic_open(MAGIC_MIME_TYPE | MAGIC_ERROR)) == NULL) { error_ = magic_errno(cookie_); MSS_ERROR("magic_open", error_); return; } if (magic_load(cookie_, NULL) == -1) { error_ = magic_errno(cookie_); MSS_ERROR("magic_open", error_); return; } // Allocate memory to the result vector. result_ = new(std::nothrow) std::vector<std::string>(VECTOR_SIZE); if (result_ == NULL) { error_ = ENOMEM; MSS_FATAL("result_", error_); return; } last_ = result_->begin(); error_ = 0; }
int Spider::ReadConfig(const std::string &config) { Config conf; if (read_config(conf, config.c_str()) == -1) { DetectError(); MSS_ERROR_MESSAGE("spider can't read configuration file"); return -1; } for (auto i = conf.begin(); i != conf.end(); i++) if (i->first == "scheduler") { scheduler_ = i->second; } else { /* Unknown option, skip. */ } return 0; }
void QuickVerifyTask::Update(DCNotifier *notifier, DWORD event_code, void *param) { switch (event_code) { case DM::DM_Event::kNewDiskDetected: NewDiskDetected( param ); break; case DM::DM_Event::kTaskInProgress: TaskInProgress( param ); break; case DM::DM_Event::kBadBlock: BadSector( param ); break; case DM::DM_Event::kTaskComplete: TaskComplete( param ); break; case DM::DM_Event::kTaskBreak: TaskBreak( param ); break; case DM::DM_Event::kTaskError: TaskError( param ); break; case DM::DM_Event::kDetectError: DetectError( param ); break; case DM::DM_Event::kDiskRemoved: DiskRemoved( param ); break; } }
const char *Spider::DetectMimeType(const std::string &path) { int smb_fd = smbc_open(path.c_str(), O_RDONLY, 0); if (UNLIKELY(smb_fd < 0)) { if (LIKELY(errno == EISDIR)) return "inode/directory"; DetectError(); MSS_ERROR(("smbc_open " + path).c_str(), error_); return "unknown"; } // Extract name of the file // Don't detele '/' symbol it need to form path. std::string name(path, path.rfind("/")); // Create a storage for file header in TMPDIR and open it int fd = open((TMPDIR + name).c_str(), O_CREAT | O_RDWR | O_EXCL, 00744 /* rwxr--r-- */); if (UNLIKELY(fd == -1)) { if (LIKELY(errno = ENOTDIR)) { // TODO(yulyugin): Check if TMPDIR doesn't exists create it. } DetectError(); MSS_ERROR("open", error_); if (UNLIKELY(smbc_close(smb_fd))) { DetectError(); MSS_ERROR("smbc_close", error_); } return "unknown"; } void *buf = malloc(HEADERSIZE); // Buffer to store header. // Copy file header to TMPDIR if (UNLIKELY(smbc_read(smb_fd, buf, HEADERSIZE) < 0)) { DetectError(); MSS_ERROR("smbc_read", error_); if (UNLIKELY(smbc_close(smb_fd))) { DetectError(); MSS_ERROR("smbc_close", error_); } if (UNLIKELY(close(fd))) { DetectError(); MSS_ERROR("close", error_); } free(buf); return "unknown"; } if (UNLIKELY(write(fd, buf, HEADERSIZE) < 0)) { DetectError(); MSS_ERROR("write", error_); if (UNLIKELY(smbc_close(smb_fd))) { DetectError(); MSS_ERROR("smbc_close", error_); } if (UNLIKELY(close(fd))) { DetectError(); MSS_ERROR("close", error_); } free(buf); return "unknown"; } // Move to the begining of the file if (UNLIKELY(lseek(fd, 0, SEEK_SET) != 0)) { DetectError(); MSS_ERROR("lseek", error_); if (UNLIKELY(smbc_close(smb_fd))) { DetectError(); MSS_ERROR("smbc_close", error_); } if (UNLIKELY(close(fd))) { DetectError(); MSS_ERROR("close", error_); } free(buf); return "unknown"; } const char *mime_type = magic_descriptor(cookie_, fd); if (UNLIKELY(mime_type == NULL)) { error_ = magic_errno(cookie_); MSS_ERROR("magic_descriptor", error_); if (UNLIKELY(smbc_close(smb_fd))) { DetectError(); MSS_ERROR("smbc_close", error_); } if (UNLIKELY(close(fd))) { DetectError(); MSS_ERROR("close", error_); } free(buf); return "unknown"; } if (UNLIKELY(smbc_close(smb_fd))) { DetectError(); MSS_ERROR("smbc_close", error_); } free(buf); // Remove temporary file. if (UNLIKELY(unlink((TMPDIR + name).c_str()))) { DetectError(); MSS_ERROR("unlink", error_); } return mime_type; }
int Spider::ScanSMBDir(const std::string &dir) { int directory_handler = 0, dirc = 0, dsize = 0; char *dirp = NULL; struct smbc_dirent *entry = NULL; char buf[BUF_SIZE]; // Open given smb directory. if (UNLIKELY((directory_handler = smbc_opendir(dir.c_str())) < 0)) { DetectError(); MSS_ERROR(("smbc_opendir " + dir).c_str(), error_); return -1; } // Getting content of the directory. // smbc_getdents() returns the readen size. // When no more content in the directory smbc_getdents() returns 0. // Use smbc_getdents() while returned value not equal 0. while (true) { dirp = static_cast<char *>(buf); // Get dir content which can placed in buf. if (UNLIKELY((dirc = smbc_getdents( static_cast<unsigned int>(directory_handler), reinterpret_cast<struct smbc_dirent *>(dirp), sizeof(buf)))) < 0) { DetectError(); MSS_ERROR("smbc_getdents", error_); return -1; } // Break the cycle if no more content in this directory. if (dirc == 0) break; // Put readen content in list while (dirc > 0) { entry = reinterpret_cast<struct smbc_dirent *>(dirp); dsize = static_cast<int>(entry->dirlen); // Ignoring "." and ".." if ((strcmp(entry->name, ".") == 0) || (strcmp(entry->name, "..") == 0)) { dirp += dsize; // Use char * to promote pointer exactly on dsize dirc -= dsize; // Decrease size continue; } switch (reinterpret_cast<struct smbc_dirent *>(dirp)->smbc_type) { case SMBC_WORKGROUP: case SMBC_SERVER: case SMBC_FILE_SHARE: case SMBC_DIR: ScanSMBDir(dir + "/" + entry->name); break; case SMBC_FILE: AddSMBFile(dir + "/" + entry->name); break; case SMBC_PRINTER_SHARE: case SMBC_COMMS_SHARE: case SMBC_IPC_SHARE: case SMBC_LINK: // Do nothing break; default: MSS_FATAL_MESSAGE("Unknown smb entry type"); assert(0); // This can't happen } dirp += dsize; // Use char * to promote pointer exactly on dsize dirc -= dsize; // Decrease size } } // Close given smb directory if (UNLIKELY(smbc_closedir(directory_handler) < 0)) { DetectError(); MSS_ERROR(("smbc_closedir " + dir).c_str(), error_); } return 0; }