void wise_load_fields() { char key[500]; int key_len; memset(fieldsMap, -1, sizeof(fieldsMap)); key_len = snprintf(key, sizeof(key), "/fields"); size_t data_len; unsigned char *data = moloch_http_send_sync(wiseService, "GET", key, key_len, NULL, 0, NULL, &data_len);; BSB bsb; BSB_INIT(bsb, data, data_len); int ver, cnt = 0; BSB_IMPORT_u32(bsb, fieldsTS); BSB_IMPORT_u32(bsb, ver); BSB_IMPORT_u08(bsb, cnt); int i; for (i = 0; i < cnt; i++) { int len = 0; BSB_IMPORT_u16(bsb, len); // len includes NULL terminated fieldsMap[i] = moloch_field_define_text((char*)BSB_WORK_PTR(bsb), NULL); if (fieldsMap[i] == -1) fieldsTS = 0; if (config.debug) LOG("%d %d %s", i, fieldsMap[i], BSB_WORK_PTR(bsb)); BSB_IMPORT_skip(bsb, len); } }
// SSH Parsing currently assumes the parts we want from a SSH Packet will be // in a single TCP packet. Kind of sucks. int ssh_parser(MolochSession_t *session, void *uw, const unsigned char *data, int remaining, int which) { SSHInfo_t *ssh = uw; if (memcmp("SSH", data, 3) == 0) { unsigned char *n = memchr(data, 0x0a, remaining); if (n && *(n-1) == 0x0d) n--; if (n) { int len = (n - data); char *str = g_ascii_strdown((char *)data, len); if (!moloch_field_string_add(verField, session, str, len, FALSE)) { g_free(str); } } return 0; } if (which != 1) return 0; BSB bsb; BSB_INIT(bsb, data, remaining); while (BSB_REMAINING(bsb) > 6) { uint32_t loopRemaining = BSB_REMAINING(bsb); // If 0 looking for a ssh packet, otherwise in the middle of ssh packet if (ssh->sshLen == 0) { BSB_IMPORT_u32(bsb, ssh->sshLen); // Can't have a ssh packet > 35000 bytes. if (ssh->sshLen >= 35000) { moloch_parsers_unregister(session, uw); return 0; } ssh->sshLen += 4; uint8_t sshCode = 0; BSB_IMPORT_skip(bsb, 1); // padding length BSB_IMPORT_u08(bsb, sshCode); if (sshCode == 33) { moloch_parsers_unregister(session, uw); uint32_t keyLen = 0; BSB_IMPORT_u32(bsb, keyLen); if (!BSB_IS_ERROR(bsb) && BSB_REMAINING(bsb) >= keyLen) { char *str = g_base64_encode(BSB_WORK_PTR(bsb), keyLen); if (!moloch_field_string_add(keyField, session, str, (keyLen/3+1)*4, FALSE)) { g_free(str); } } break; } } if (loopRemaining > ssh->sshLen) { // Processed all, looking for another packet BSB_IMPORT_skip(bsb, loopRemaining); ssh->sshLen = 0; continue; } else { // Waiting on more data then in this callback ssh->sshLen -= loopRemaining; break; } } return 0; }
void wise_cb(unsigned char *data, int data_len, gpointer uw) { BSB bsb; WiseRequest_t *request = uw; int i; inflight -= request->numItems; BSB_INIT(bsb, data, data_len); uint32_t fts = 0, ver = 0; BSB_IMPORT_u32(bsb, fts); BSB_IMPORT_u32(bsb, ver); if (BSB_IS_ERROR(bsb) || ver != 0) { for (i = 0; i < request->numItems; i++) { wise_free_item(request->items[i]); } MOLOCH_TYPE_FREE(WiseRequest_t, request); return; } if (fts != fieldsTS) wise_load_fields(); struct timeval currentTime; gettimeofday(¤tTime, NULL); for (i = 0; i < request->numItems; i++) { WiseItem_t *wi = request->items[i]; BSB_IMPORT_u08(bsb, wi->numOps); if (wi->numOps > 0) { wi->ops = malloc(wi->numOps * sizeof(WiseOp_t)); int i; for (i = 0; i < wi->numOps; i++) { WiseOp_t *op = &(wi->ops[i]); int rfield = 0; BSB_IMPORT_u08(bsb, rfield); op->fieldPos = fieldsMap[rfield]; int len = 0; BSB_IMPORT_u08(bsb, len); char *str = (char*)BSB_WORK_PTR(bsb); BSB_IMPORT_skip(bsb, len); switch (config.fields[op->fieldPos]->type) { case MOLOCH_FIELD_TYPE_INT_HASH: if (op->fieldPos == tagsField) { moloch_db_get_tag(NULL, tagsField, str, NULL); // Preload the tagname -> tag mapping op->str = g_strdup(str); op->strLenOrInt = len - 1; continue; } // Fall thru case MOLOCH_FIELD_TYPE_INT: case MOLOCH_FIELD_TYPE_INT_ARRAY: op->str = 0; op->strLenOrInt = atoi(str); break; case MOLOCH_FIELD_TYPE_STR: case MOLOCH_FIELD_TYPE_STR_ARRAY: case MOLOCH_FIELD_TYPE_STR_HASH: op->str = g_strdup(str); op->strLenOrInt = len - 1; break; case MOLOCH_FIELD_TYPE_IP: case MOLOCH_FIELD_TYPE_IP_HASH: op->str = 0; op->strLenOrInt = inet_addr(str); break; default: LOG("WARNING - Unsupported expression type for %s", str); continue; } } } wi->loadTime = currentTime.tv_sec; int s; for (s = 0; s < wi->numSessions; s++) { wise_process_ops(wi->sessions[s], wi); moloch_nids_decr_outstanding(wi->sessions[s]); } g_free(wi->sessions); wi->sessions = 0; wi->numSessions = 0; DLL_PUSH_HEAD(wil_, &itemList[(int)wi->type], wi); // Cache needs to be reduced if (itemList[(int)wi->type].wil_count > maxCache) { DLL_POP_TAIL(wil_, &itemList[(int)wi->type], wi); wise_free_item(wi); } } MOLOCH_TYPE_FREE(WiseRequest_t, request); }