Exemplo n.º 1
0
int swd::database::save_parameter(const int& request_id, const std::string& path,
 const std::string& value, const int& total_whitelist_rules,
 const int& critical_impact, const int& threat) {
    ensure_connection();

    boost::unique_lock<boost::mutex> scoped_lock(dbi_mutex_);

    char *path_esc = strdup(path.c_str());
    dbi_conn_quote_string(conn_, &path_esc);

    char *value_esc = strdup(value.c_str());
    dbi_conn_quote_string(conn_, &value_esc);

    dbi_result res = dbi_conn_queryf(conn_, "INSERT INTO parameters "
     "(request_id, path, value, total_whitelist_rules, critical_impact, threat) "
     "VALUES (%i, %s, %s, %i, %i, %i)", request_id, path_esc, value_esc,
     total_whitelist_rules, critical_impact, threat);

    free(path_esc);
    free(value_esc);

    if (!res) {
        throw swd::exceptions::database_exception("Can't execute parameter query");
    }

    int id = dbi_conn_sequence_last(conn_, "parameters_id_seq");

    dbi_result_free(res);

    return id;
}
Exemplo n.º 2
0
int swd::database::save_hash(const int& request_id, const std::string& algorithm,
 const std::string& digest) {
    ensure_connection();

    boost::unique_lock<boost::mutex> scoped_lock(dbi_mutex_);

    char *algorithm_esc = strdup(algorithm.c_str());
    dbi_conn_quote_string(conn_, &algorithm_esc);

    char *digest_esc = strdup(digest.c_str());
    dbi_conn_quote_string(conn_, &digest_esc);

    dbi_result res = dbi_conn_queryf(conn_, "INSERT INTO hashes (request_id, "
     "algorithm, digest) VALUES (%i, %s, %s)", request_id, algorithm_esc, digest_esc);

    free(algorithm_esc);
    free(digest_esc);

    if (!res) {
        throw swd::exceptions::database_exception("Can't execute hash query");
    }

    int id = dbi_conn_sequence_last(conn_, "hashes_id_seq");

    dbi_result_free(res);

    return id;
}
Exemplo n.º 3
0
swd::whitelist_rules swd::database::get_whitelist_rules(const int& profile_id,
 const std::string& caller, const std::string& path) {
    swd::log::i()->send(swd::notice, "Get whitelist rules from db");

    ensure_connection();

    boost::unique_lock<boost::mutex> scoped_lock(dbi_mutex_);

    char *caller_esc = strdup(caller.c_str());
    dbi_conn_quote_string(conn_, &caller_esc);

    char *path_esc = strdup(path.c_str());
    dbi_conn_quote_string(conn_, &path_esc);

    /**
     * Remove LIKE single character wildcard, because it could result easily in security
     * problems if a user forgets to escape an underscore. And instead of a percentage sign
     * it is nicer to use an asterisk, because it is more common.
     */
    dbi_result res = dbi_conn_queryf(conn_, "SELECT r.id, r.path, f.id as filter_id, "
     "f.rule, f.impact, r.min_length, r.max_length FROM whitelist_rules AS r, "
     "whitelist_filters AS f WHERE r.filter_id = f.id AND r.profile_id = %i AND %s LIKE "
     "prepare_wildcard(r.caller) AND %s LIKE prepare_wildcard(r.path) AND r.status = %i",
     profile_id, caller_esc, path_esc, STATUS_ACTIVATED);

    free(caller_esc);
    free(path_esc);

    if (!res) {
        throw swd::exceptions::database_exception("Can't execute whitelist_rules query");
    }

    swd::whitelist_rules rules;

    while (dbi_result_next_row(res)) {
        swd::whitelist_filter_ptr filter(new swd::whitelist_filter());
        filter->set_id(dbi_result_get_uint(res, "filter_id"));
        filter->set_regex(dbi_result_get_string(res, "rule"));

        swd::whitelist_rule_ptr rule(new swd::whitelist_rule());
        rule->set_id(dbi_result_get_uint(res, "id"));
        rule->set_filter(filter);
        rule->set_min_length(dbi_result_get_uint(res, "min_length"));
        rule->set_max_length(dbi_result_get_uint(res, "max_length"));

        rules.push_back(rule);
    }

    dbi_result_free(res);

    return rules;
}
Exemplo n.º 4
0
bool swd::database::is_flooding(const std::string& client_ip,
 const int& profile_id) {
    ensure_connection();

    boost::unique_lock<boost::mutex> scoped_lock(dbi_mutex_);

    char *client_ip_esc = strdup(client_ip.c_str());
    dbi_conn_quote_string(conn_, &client_ip_esc);

    dbi_result res = dbi_conn_queryf(conn_, "SELECT is_flooding(%i, %s) AS result",
     profile_id, client_ip_esc);

    free(client_ip_esc);

    if (!res) {
        throw swd::exceptions::database_exception("Can't execute request count query");
    }

    bool flooding = false;

    if (dbi_result_get_numrows(res) == 1) {
        if (!dbi_result_next_row(res)) {
            throw swd::exceptions::database_exception("No flooding?");
        }

        flooding = (dbi_result_get_uint(res, "result") == 1);
    }

    dbi_result_free(res);

    return flooding;
}
Exemplo n.º 5
0
swd::profile_ptr swd::database::get_profile(const std::string& server_ip,
 const int& profile_id) {
    std::stringstream log_message;
    log_message << "Get profile from db -> server_ip: " << server_ip
     << "; profile_id: " << profile_id;

    swd::log::i()->send(swd::notice, log_message.str());

    /* Test the database connection status. Tries to reconnect if disconnected. */
    ensure_connection();

    /* Mutex to avoid race conditions. */
    boost::unique_lock<boost::mutex> scoped_lock(dbi_mutex_);

    /**
     * First we escape server_ip. It comes from a trusted source, but better safe
     * than sorry. This does not work with std::string though.
     */
    char *server_ip_esc = strdup(server_ip.c_str());
    dbi_conn_quote_string(conn_, &server_ip_esc);

    /* Insert the ip and execute the query. */
    dbi_result res = dbi_conn_queryf(conn_, "SELECT id, hmac_key, mode, "
     "whitelist_enabled, blacklist_enabled, integrity_enabled, flooding_enabled, "
     "blacklist_threshold, cache_outdated FROM profiles WHERE %s LIKE "
     "prepare_wildcard(server_ip) AND id = %i", server_ip_esc, profile_id);

    /* Don't forget to free server_ip_esc to avoid a memory leak. */
    free(server_ip_esc);

    if (!res) {
        throw swd::exceptions::database_exception("Can't execute profile query");
    }

    if (dbi_result_get_numrows(res) != 1) {
        throw swd::exceptions::database_exception("Can't get profile");
    }

    if (!dbi_result_next_row(res)) {
        throw swd::exceptions::database_exception("No profile?");
    }

    swd::profile_ptr profile(new swd::profile());
    profile->set_server_ip(server_ip),
    profile->set_id(dbi_result_get_uint(res, "id"));
    profile->set_mode(dbi_result_get_uint(res, "mode"));
    profile->set_whitelist_enabled(dbi_result_get_uint(res, "whitelist_enabled") == 1);
    profile->set_blacklist_enabled(dbi_result_get_uint(res, "blacklist_enabled") == 1);
    profile->set_integrity_enabled(dbi_result_get_uint(res, "integrity_enabled") == 1);
    profile->set_flooding_enabled(dbi_result_get_uint(res, "flooding_enabled") == 1);
    profile->set_key(dbi_result_get_string(res, "hmac_key"));
    profile->set_blacklist_threshold(dbi_result_get_uint(res, "blacklist_threshold"));
    profile->set_cache_outdated(dbi_result_get_uint(res, "cache_outdated") == 1);

    dbi_result_free(res);

    return profile;
}
Exemplo n.º 6
0
int swd::database::save_request(const int& profile_id, const std::string& caller,
 const std::string& resource, const int& mode, const std::string& client_ip,
 const int& total_integrity_rules) {
    std::stringstream log_message;
    log_message << "Save request -> profile: " << profile_id
     << "; caller: " << caller << "; resource: " << resource
     << "; mode: " << mode << "; client_ip: " << client_ip;

    swd::log::i()->send(swd::notice, log_message.str());

    ensure_connection();

    boost::unique_lock<boost::mutex> scoped_lock(dbi_mutex_);

    char *caller_esc = strdup(caller.c_str());
    dbi_conn_quote_string(conn_, &caller_esc);

    char *resource_esc = strdup(resource.c_str());
    dbi_conn_quote_string(conn_, &resource_esc);

    char *client_ip_esc = strdup(client_ip.c_str());
    dbi_conn_quote_string(conn_, &client_ip_esc);

    dbi_result res = dbi_conn_queryf(conn_, "INSERT INTO requests (profile_id, "
     "caller, resource, mode, client_ip, total_integrity_rules) VALUES (%i, %s, "
     "%s, %i, %s, %i)", profile_id, caller_esc, resource_esc, mode, client_ip_esc,
     total_integrity_rules);

    free(caller_esc);
    free(resource_esc);
    free(client_ip_esc);

    if (!res) {
        throw swd::exceptions::database_exception("Can't execute request query");
    }

    int id = dbi_conn_sequence_last(conn_, "requests_id_seq");

    dbi_result_free(res);

    return id;
}
Exemplo n.º 7
0
size_t dbi_conn_escape_string(dbi_conn Conn, char **orig) {
	size_t newlen;

	newlen = dbi_conn_quote_string(Conn, orig);

	if (newlen) {
	  (*orig)[newlen-1] = '\0';
	  memmove(*orig, (*orig)+1, newlen-1);
	}
	return newlen-2;
}
Exemplo n.º 8
0
swd::blacklist_rules swd::database::get_blacklist_rules(const int& profile_id,
 const std::string& caller, const std::string& path) {
    swd::log::i()->send(swd::notice, "Get blacklist rules from db");

    ensure_connection();

    boost::unique_lock<boost::mutex> scoped_lock(dbi_mutex_);

    char *caller_esc = strdup(caller.c_str());
    dbi_conn_quote_string(conn_, &caller_esc);

    char *path_esc = strdup(path.c_str());
    dbi_conn_quote_string(conn_, &path_esc);

    dbi_result res = dbi_conn_queryf(conn_, "SELECT r.id, r.path, r.threshold "
     "FROM blacklist_rules AS r WHERE r.profile_id = %i AND %s LIKE "
     "prepare_wildcard(r.caller) AND %s LIKE prepare_wildcard(r.path) AND "
     "r.status = %i", profile_id, caller_esc, path_esc, STATUS_ACTIVATED);

    free(caller_esc);
    free(path_esc);

    if (!res) {
        throw swd::exceptions::database_exception("Can't execute blacklist_rules query");
    }

    swd::blacklist_rules rules;

    while (dbi_result_next_row(res)) {
        swd::blacklist_rule_ptr rule(new swd::blacklist_rule());
        rule->set_id(dbi_result_get_uint(res, "id"));
        rule->set_threshold(dbi_result_get_uint(res, "threshold"));

        rules.push_back(rule);
    }

    dbi_result_free(res);

    return rules;
}
Exemplo n.º 9
0
//*******************************************************************
// UPDATE PR_STATUS
//*******************************************************************
static dbi_result update_pr_status(trx *t, struct probe_result *prv)
{
  dbi_result result;
  char *qry;

  qry = g_malloc(512 + (t->res->message ? strlen(t->res->message)*2 : 0));

  sprintf(qry, "update pr_status "
               "set    stattime = '%u', expires = '%u', hide = '%s', " 
               "       contact = '%u', server = '%u'", 
               t->res->stattime, t->res->expires, t->def->hide, 
               t->def->contact, t->def->server);

  if (t->probe->fuse) {
    if (t->res->color > prv->color || prv->color == STAT_PURPLE) {
    // if this probe acts like a fuse, only update color if new color is higher then old color
    // because colors must be set to green (= fuse replaced) by a human
      sprintf(&qry[strlen(qry)], ", color = '%u'", t->res->color);
    } 
  } else {
    sprintf(&qry[strlen(qry)], ", color = '%u'", t->res->color);
  }

  if (t->res->message) {
    char *escmsg;

    escmsg = strdup(t->res->message);
    dbi_conn_quote_string(t->probe->db, &escmsg);

    if (t->res->color != prv->color) {
      sprintf(&qry[strlen(qry)], ", message = %s", escmsg);
    } else if (t->probe->fuse) {
      sprintf(&qry[strlen(qry)], ", message = concat(message,%s)", escmsg);
    }
    free(escmsg);
  }
  else {
    sprintf(&qry[strlen(qry)],", message = ''");
  }

  sprintf(&qry[strlen(qry)], " where probe = '%u' and class = '%u'", t->def->probeid, t->probe->class);
  result = db_rawquery(t->probe->db, 0, qry);
  g_free(qry);
  return(result);
}
Exemplo n.º 10
0
//*******************************************************************
// CREATE PR_STATUS RECORD
//*******************************************************************
static void insert_pr_status(trx *t)
{
  dbi_result result;
  char *escmsg;

  if (t->res->message) {
    escmsg = strdup(t->res->message);
    dbi_conn_quote_string(t->probe->db, &escmsg);
  } else {
    escmsg = strdup("''");
  }

  result = db_query(t->probe->db, 0,
                    "insert into pr_status "
                    "set    class =  '%u', probe = '%u', stattime = '%u', expires = '%u', "
                    "       color = '%u', server = '%u', message = %s, "
                    "       contact = '%u', hide = '%s'",
                    t->probe->class, t->def->probeid, t->res->stattime, t->res->expires, 
                    t->def->color, t->def->server, escmsg, t->def->contact, t->def->hide);
  dbi_result_free(result);
  g_free(escmsg);
}
Exemplo n.º 11
0
//*******************************************************************
// CREATE PR_HIST
//*******************************************************************
static void create_pr_hist(trx *t, struct probe_result *prv)
{
  dbi_result result;
  char *escmsg;

  if (t->res->message) {
    escmsg = strdup(t->res->message);
    dbi_conn_quote_string(t->probe->db, &escmsg);
  } else {
    escmsg = strdup("''");
  }

  result = db_query(t->probe->db, 0,
                    "insert into pr_hist "
                    "set    server = '%u', class = '%u', probe = '%u', stattime = '%u', "
                    "       prv_color = '%d', color = '%d', message = %s, contact = '%u', "
                    "       hide = '%s', pgroup = '%u'",
                    t->def->server, t->probe->class, t->def->probeid, t->res->stattime,
                    /* (t->res->received > t->res->expires) ? STAT_PURPLE : */ prv->color, 
                    t->res->color, escmsg, t->def->contact, t->def->hide, t->def->pgroup);
  dbi_result_free(result);
  g_free(escmsg);
}
Exemplo n.º 12
0
swd::integrity_rules swd::database::get_integrity_rules(const int& profile_id,
 const std::string& caller) {
    swd::log::i()->send(swd::notice, "Get integrity rules from db");

    ensure_connection();

    boost::unique_lock<boost::mutex> scoped_lock(dbi_mutex_);

    char *caller_esc = strdup(caller.c_str());
    dbi_conn_quote_string(conn_, &caller_esc);

    dbi_result res = dbi_conn_queryf(conn_, "SELECT r.id, r.algorithm, r.digest FROM "
     "integrity_rules AS r WHERE r.profile_id = %i AND %s LIKE prepare_wildcard(r.caller) "
     "AND r.status = %i", profile_id, caller_esc, STATUS_ACTIVATED);

    free(caller_esc);

    if (!res) {
        throw swd::exceptions::database_exception("Can't execute whitelist_rules query");
    }

    swd::integrity_rules rules;

    while (dbi_result_next_row(res)) {
        swd::integrity_rule_ptr rule(new swd::integrity_rule());
        rule->set_id(dbi_result_get_uint(res, "id"));
        rule->set_algorithm(dbi_result_get_string(res, "algorithm"));
        rule->set_digest(dbi_result_get_string(res, "digest"));

        rules.push_back(rule);
    }

    dbi_result_free(res);

    return rules;
}