static void try_to_backup(const char *filename) { char extension[][5] = { "xml", "ssrf", "" }; int i = 0; int flen = strlen(filename); /* Maybe we might want to make this configurable? */ while (extension[i][0] != '\0') { int elen = strlen(extension[i]); if (strcasecmp(filename + flen - elen, extension[i]) == 0) { if (last_xml_version < VERSION) { int se_len = strlen(extension[i]) + 5; char *special_ext = malloc(se_len); snprintf(special_ext, se_len, "%s.v%d", extension[i], last_xml_version); save_backup(filename, extension[i], special_ext); free(special_ext); } else { save_backup(filename, extension[i], "bak"); } break; } i++; } }
static void try_to_backup(const char *filename) { char extension[][5] = { "xml", "ssrf", "" }; int i = 0; int flen = strlen(filename); /* Maybe we might want to make this configurable? */ while (extension[i][0] != '\0') { int elen = strlen(extension[i]); if (strcasecmp(filename + flen - elen, extension[i]) == 0) { save_backup(filename, extension[i], "bak"); break; } i++; } }
/*! mod_source \brief check if the source IP has already been seen in a prior connection Parameters required: function = hash; backup = /etc/honeybrid/source.tb \param[in] args, struct that contain the node and the data to process \param[in] user_data, not used * \param[out] set result to 0 if attacker ip is found in search table, 1 if not */ mod_result_t mod_source(struct mod_args *args) { printdbg("%s Module called\n", H(args->pkt->conn->id)); mod_result_t result = DEFER; int expiration = 24 * 3600; gchar *backup_file; char *key_src; gchar **info; GKeyFile *backup; GTimeVal t; g_get_current_time(&t); gint now = (t.tv_sec); /*! get the IP address from the packet */ key_src = g_malloc0(snprintf(NULL, 0, "%u", args->pkt->packet.ip->saddr) + 1); sprintf(key_src, "%u", args->pkt->packet.ip->saddr); printdbg("%s source IP is %s\n", H(args->pkt->conn->id), key_src); /*! get the backup file for this module */ if (NULL == (backup = (GKeyFile *) g_hash_table_lookup(args->node->config, "backup"))) { /*! We can't decide */ printdbg("%s mandatory argument 'backup' undefined!\n", H(args->pkt->conn->id)); return result; } /*! get the backup file path for this module */ if (NULL == (backup_file = (gchar *) g_hash_table_lookup(args->node->config, "backup_file"))) { /*! We can't decide */ printdbg("%s error, backup file path missing\n", H(args->pkt->conn->id)); return result; } printdbg("%s searching for this IP in the database...\n", H(args->pkt->conn->id)); if (NULL == (info = g_key_file_get_string_list(backup, "source", /* generic group name \todo: group by port number? */ key_src, NULL, NULL))) { /*! Unknown IP, so we accept the packet */ result = ACCEPT; printdbg("%s IP not found... packet accepted and new entry created\n", H(args->pkt->conn->id)); info = malloc(3 * sizeof(char *)); /*! 20 characters should be enough to hold even very large numbers */ info[0] = malloc(20 * sizeof(gchar)); info[1] = malloc(20 * sizeof(gchar)); info[2] = malloc(20 * sizeof(gchar)); g_snprintf(info[0], 20, "1"); /*! counter */ g_snprintf(info[1], 20, "%d", now); /*! first seen */ g_snprintf(info[2], 20, "0"); /*! duration */ } else { /*! We check if we need to expire this entry */ int age = atoi(info[2]); if (age > expiration) { /*! Known IP but entry expired, so we accept the packet */ result = ACCEPT; printdbg( "%s IP found but expired... packet accepted and entry renewed\n", H(args->pkt->conn->id)); g_snprintf(info[0], 20, "1"); /*! counter */ g_snprintf(info[1], 20, "%d", now); /*! first seen */ g_snprintf(info[2], 20, "0"); /*! duration */ } else { /*! Known IP, so we reject the packet */ result = REJECT; printdbg("%s IP found... packet rejected and entry updated\n", H(args->pkt->conn->id)); g_snprintf(info[0], 20, "%d", atoi(info[0]) + 1); /*! counter */ g_snprintf(info[2], 20, "%d", now - atoi(info[1])); /*! duration */ } } g_key_file_set_string_list(backup, "source", key_src, (const gchar * const *) info, 3); save_backup(backup, backup_file); /*! clean and exit */ free(key_src); return result; }
/*! control \brief calculate the number of packets sent by a same source over a given period of time. If too many packets are sent, following packets are rejected Parameters required: function = hash; backup = /etc/honeybrid/control.tb expiration = 600 max_packet = 1000 \param[in] pkts, struct that contain the packet to control \param[out] set result to 1 if rate limit reached, 0 otherwise */ mod_result_t mod_control(struct mod_args *args) { gchar *backup_file; if (args->pkt == NULL) { printdbg("%s Error, NULL packet\n", H(6)); return REJECT; } printdbg("%s Module called\n", H(args->pkt->conn->id)); mod_result_t result = DEFER; int expiration; int max_packet; gchar *param; gchar **info; GKeyFile *backup; GTimeVal t; g_get_current_time(&t); gint now = (t.tv_sec); char src[INET_ADDRSTRLEN]; inet_ntop(AF_INET, &(args->pkt->packet.ip->saddr), src, INET_ADDRSTRLEN); /*! get the backup file for this module */ if (NULL == (backup = (GKeyFile *) g_hash_table_lookup(args->node->config, "backup"))) { /*! We can't decide */ printdbg("%s mandatory argument 'backup' undefined!\n", H(args->pkt->conn->id)); return result; } /*! get the backup file path for this module */ if (NULL == (backup_file = (gchar *) g_hash_table_lookup(args->node->config, "backup_file"))) { /*! We can't decide */ printdbg("%s error, backup file path missing\n", H(args->pkt->conn->id)); return result; } /*! get control parameters */ if (NULL == (param = (gchar *) g_hash_table_lookup(args->node->config, "expiration"))) { /*! no value set for expiration, we go with the default one */ expiration = 600; } else { expiration = atoi(param); } if (NULL == (param = (gchar *) g_hash_table_lookup(args->node->config, "max_packet"))) { /*! no value set for expiration, we go with the default one */ max_packet = 1000; } else { max_packet = atoi(param); } if (NULL == (info = g_key_file_get_string_list(backup, "source", /* generic group name \todo: group by port number? */ src, NULL, NULL))) { printdbg("%s IP not found... new entry created\n", H(args->pkt->conn->id)); info = malloc(3 * sizeof(char *)); /*! 20 characters should be enough to hold even very large numbers */ info[0] = malloc(20 * sizeof(gchar)); info[1] = malloc(20 * sizeof(gchar)); info[2] = malloc(20 * sizeof(gchar)); g_snprintf(info[0], 20, "1"); /*! counter */ g_snprintf(info[1], 20, "%d", now); /*! first seen */ g_snprintf(info[2], 20, "0"); /*! duration */ } else { /*! We check if we need to expire this entry */ int age = atoi(info[2]); if (age > expiration) { printdbg("%s IP found but expired... entry renewed\n", H(args->pkt->conn->id)); g_snprintf(info[0], 20, "1"); /*! counter */ g_snprintf(info[1], 20, "%d", now); /*! first seen */ g_snprintf(info[2], 20, "0"); /*! duration */ } else { printdbg("%s IP found... entry updated\n", H(args->pkt->conn->id)); g_snprintf(info[0], 20, "%d", atoi(info[0]) + 1); /*! counter */ g_snprintf(info[2], 20, "%d", now - atoi(info[1])); /*! duration */ } } if (atoi(info[0]) > max_packet) { printdbg("%s Rate limit reached! Packet rejected\n", H(args->pkt->conn->id)); result = REJECT; } else { printdbg("%s Rate limit not reached. Packet accepted\n", H(args->pkt->conn->id)); result = ACCEPT; } g_key_file_set_string_list(backup, "source", src, (const gchar * const *) info, 3); save_backup(backup, backup_file); return result; }