Greenbone Vulnerability Management Libraries  22.8.0
kb.c File Reference

Knowledge base management API - Redis backend. More...

#include "kb.h"
#include <errno.h>
#include <glib.h>
#include <hiredis/hiredis.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Include dependency graph for kb.c:

Go to the source code of this file.

Data Structures

struct  kb_redis
 Subclass of struct kb, it contains the redis-specific fields, such as the redis context, current DB (namespace) id and the server socket path. More...
 

Macros

#define _GNU_SOURCE
 
#define G_LOG_DOMAIN   "libgvm util"
 GLib logging domain. More...
 
#define memdup   g_memdup
 
#define GLOBAL_DBINDEX_NAME   "GVM.__GlobalDBIndex"
 Name of the namespace usage bitmap in redis. More...
 
#define redis_kb(__kb)   ((struct kb_redis *) (__kb))
 

Functions

static int redis_delete_all (struct kb_redis *kbr)
 Delete all the KB's content. More...
 
static int redis_lnk_reset (kb_t kb)
 Reset connection to the KB. This is called after each fork() to make sure connections aren't shared between concurrent processes. More...
 
static int redis_flush_all (kb_t kb, const char *except)
 Flush all the KB's content. Delete all namespaces. More...
 
static redisReply * redis_cmd (struct kb_redis *kbr, const char *fmt,...)
 Execute a redis command and get a redis reply. More...
 
static int try_database_index (struct kb_redis *kbr, int index)
 Attempt to atomically acquire ownership of a database. More...
 
static int fetch_max_db_index (struct kb_redis *kbr)
 Set the number of databases have been configured into kbr struct. More...
 
static int select_database (struct kb_redis *kbr)
 Select DB. More...
 
static int redis_release_db (struct kb_redis *kbr)
 Release DB. More...
 
static char * parse_port_of_addr (const char *addr, int tcp_indicator_len)
 
static redisContext * connect_redis (const char *addr, int len)
 
static int get_redis_ctx (struct kb_redis *kbr)
 Get redis context if it is already connected or do a a connection. More...
 
static int redis_test_connection (struct kb_redis *kbr)
 Test redis connection. More...
 
static int redis_delete (kb_t kb)
 Delete all entries and release ownership on the namespace. More...
 
static int redis_get_kb_index (kb_t kb)
 Return the kb index. More...
 
static int redis_memory_purge (kb_t kb)
 Attempt to purge dirty pages. More...
 
static int redis_new (kb_t *kb, const char *kb_path)
 Initialize a new Knowledge Base object. More...
 
static kb_t redis_direct_conn (const char *kb_path, const int kb_index)
 Connect to a Knowledge Base object with the given kb_index. More...
 
static kb_t redis_find (const char *kb_path, const char *key)
 Find an existing Knowledge Base object with key. More...
 
void kb_item_free (struct kb_item *item)
 Release a KB item (or a list). More...
 
static struct kb_itemredis2kbitem_single (const char *name, const redisReply *elt, int force_int)
 Give a single KB item. More...
 
static struct kb_itemredis2kbitem (const char *name, const redisReply *rep)
 Fetch a KB item or list from a redis Reply. More...
 
static struct kb_itemredis_get_single (kb_t kb, const char *name, enum kb_item_type type)
 Get a single KB element. More...
 
static char * redis_get_str (kb_t kb, const char *name)
 Get a single KB string item. More...
 
static int redis_push_str (kb_t kb, const char *name, const char *value)
 Push a new entry under a given key. More...
 
static char * redis_pop_str (kb_t kb, const char *name)
 Pops a single KB string item. More...
 
static int redis_get_int (kb_t kb, const char *name)
 Get a single KB integer item. More...
 
static char * redis_get_nvt (kb_t kb, const char *oid, enum kb_nvt_pos position)
 Get field of a NVT. More...
 
static nvti_tredis_get_nvt_all (kb_t kb, const char *oid)
 Get a full NVT. More...
 
static struct kb_itemredis_get_all (kb_t kb, const char *name)
 Get all items stored under a given name. More...
 
static struct kb_itemredis_get_pattern (kb_t kb, const char *pattern)
 Get all items stored under a given pattern. More...
 
static GSList * redis_get_oids (kb_t kb)
 Get all NVT OIDs. More...
 
static size_t redis_count (kb_t kb, const char *pattern)
 Count all items stored under a given pattern. More...
 
static int redis_del_items (kb_t kb, const char *name)
 Delete all entries under a given name. More...
 
static int redis_add_str_unique_volatile (kb_t kb, const char *name, const char *str, int expire, size_t len, int pos)
 Insert (append) a new unique and volatile entry under a given name. More...
 
static int redis_add_str_unique (kb_t kb, const char *name, const char *str, size_t len, int pos)
 Insert (append) a new unique entry under a given name. More...
 
static int redis_add_str (kb_t kb, const char *name, const char *str, size_t len)
 Insert (append) a new entry under a given name. More...
 
static int redis_set_str (kb_t kb, const char *name, const char *val, size_t len)
 Set (replace) a new entry under a given name. More...
 
static int redis_add_int_unique_volatile (kb_t kb, const char *name, int val, int expire)
 Insert (append) a new unique entry under a given name. More...
 
static int redis_add_int_unique (kb_t kb, const char *name, int val)
 Insert (append) a new unique entry under a given name. More...
 
static int redis_add_int (kb_t kb, const char *name, int val)
 Insert (append) a new entry under a given name. More...
 
static int redis_set_int (kb_t kb, const char *name, int val)
 Set (replace) a new entry under a given name. More...
 
static int redis_add_nvt (kb_t kb, const nvti_t *nvt, const char *filename)
 Insert a new nvt. More...
 
static int redis_save (kb_t kb)
 Save all the elements from the KB. More...
 

Variables

static const struct kb_operations KBRedisOperations
 Default KB operations. More...
 
const struct kb_operationsKBDefaultOperations = &KBRedisOperations
 Default KB operations. No selection mechanism is provided yet since there's only one implementation (redis-based). More...
 

Detailed Description

Knowledge base management API - Redis backend.

Contains specialized structures and functions to use redis as a KB server.

Definition in file kb.c.

Macro Definition Documentation

◆ _GNU_SOURCE

#define _GNU_SOURCE

Definition at line 11 of file kb.c.

◆ G_LOG_DOMAIN

#define G_LOG_DOMAIN   "libgvm util"

GLib logging domain.

Definition at line 27 of file kb.c.

◆ GLOBAL_DBINDEX_NAME

#define GLOBAL_DBINDEX_NAME   "GVM.__GlobalDBIndex"

Name of the namespace usage bitmap in redis.

Definition at line 45 of file kb.c.

◆ memdup

#define memdup   g_memdup

Definition at line 32 of file kb.c.

◆ redis_kb

#define redis_kb (   __kb)    ((struct kb_redis *) (__kb))

Definition at line 62 of file kb.c.

Function Documentation

◆ connect_redis()

static redisContext* connect_redis ( const char *  addr,
int  len 
)
static

Definition at line 263 of file kb.c.

264 {
265  const char *tcp_indicator = "tcp://";
266  const int tcp_indicator_len = strlen (tcp_indicator);
267  const int redis_default_port = 6379;
268 
269  int port, host_len;
270  char *tmp, *host;
271  redisContext *result;
272  static int warn_flag = 0;
273 
274  if (len < tcp_indicator_len + 1)
275  goto unix_connect;
276  if (memcmp (addr, tcp_indicator, tcp_indicator_len) != 0)
277  goto unix_connect;
278  host_len = len - tcp_indicator_len;
279  if ((tmp = parse_port_of_addr (addr, tcp_indicator_len)) == NULL)
280  port = redis_default_port;
281  else
282  {
283  port = atoi (tmp);
284  host_len -= strlen (tmp) + 1;
285  }
286  host = calloc (1, host_len);
287  memmove (host, addr + tcp_indicator_len, host_len);
288  result = redisConnect (host, port);
289  if (warn_flag == 0)
290  {
291  g_warning ("A Redis TCP connection is being used. This feature is "
292  "experimental and insecure, since it is not an encrypted "
293  "channel. We discourage its usage in production environments");
294  warn_flag = 1;
295  }
296  free (host);
297  return result;
298 unix_connect:
299  return redisConnectUnix (addr);
300 }

References parse_port_of_addr().

Referenced by get_redis_ctx(), redis_direct_conn(), redis_find(), and redis_flush_all().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ fetch_max_db_index()

static int fetch_max_db_index ( struct kb_redis kbr)
static

Set the number of databases have been configured into kbr struct.

Parameters
[in]kbrSubclass of struct kb where to save the max db index founded.
Returns
0 on success, -1 on error.

Definition at line 109 of file kb.c.

110 {
111  int rc = 0;
112  redisContext *ctx = kbr->rctx;
113  redisReply *rep = NULL;
114 
115  rep = redisCommand (ctx, "CONFIG GET databases");
116  if (rep == NULL)
117  {
118  g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
119  "%s: redis command failed with '%s'", __func__, ctx->errstr);
120  rc = -1;
121  goto err_cleanup;
122  }
123 
124  if (rep->type != REDIS_REPLY_ARRAY)
125  {
126  g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
127  "%s: cannot retrieve max DB number: %s", __func__, rep->str);
128  rc = -1;
129  goto err_cleanup;
130  }
131 
132  if (rep->elements == 2)
133  {
134  kbr->max_db = (unsigned) atoi (rep->element[1]->str);
135  }
136  else
137  {
138  g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
139  "%s: unexpected reply length (%zd)", __func__, rep->elements);
140  rc = -1;
141  goto err_cleanup;
142  }
143 
144  g_debug ("%s: maximum DB number: %u", __func__, kbr->max_db);
145 
146 err_cleanup:
147  if (rep != NULL)
148  freeReplyObject (rep);
149 
150  return rc;
151 }

References G_LOG_DOMAIN, kb_redis::max_db, and kb_redis::rctx.

Referenced by redis_find(), and select_database().

Here is the caller graph for this function:

◆ get_redis_ctx()

static int get_redis_ctx ( struct kb_redis kbr)
static

Get redis context if it is already connected or do a a connection.

Parameters
[in]kbrSubclass of struct kb where to fetch the context. or where it is saved in case of a new connection.
Returns
0 on success, -1 on connection error, -2 on unavailable DB slot.

Definition at line 312 of file kb.c.

313 {
314  int rc;
315 
316  if (kbr->rctx != NULL)
317  return 0;
318 
319  kbr->rctx = connect_redis (kbr->path, strlen (kbr->path));
320  if (kbr->rctx == NULL || kbr->rctx->err)
321  {
322  g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
323  "%s: redis connection error to %s: %s", __func__, kbr->path,
324  kbr->rctx ? kbr->rctx->errstr : strerror (ENOMEM));
325  redisFree (kbr->rctx);
326  kbr->rctx = NULL;
327  return -1;
328  }
329 
330  rc = select_database (kbr);
331  if (rc)
332  {
333  g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, "No redis DB available");
334  redisFree (kbr->rctx);
335  kbr->rctx = NULL;
336  return -2;
337  }
338 
339  g_debug ("%s: connected to redis://%s/%d", __func__, kbr->path, kbr->db);
340  return 0;
341 }

References connect_redis(), kb_redis::db, G_LOG_DOMAIN, kb_redis::path, kb_redis::rctx, and select_database().

Referenced by redis_add_int_unique(), redis_add_int_unique_volatile(), redis_add_str_unique(), redis_add_str_unique_volatile(), redis_cmd(), redis_get_pattern(), redis_new(), redis_set_int(), and redis_set_str().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ kb_item_free()

void kb_item_free ( struct kb_item item)

Release a KB item (or a list).

Parameters
[in]itemItem or list to be release

Definition at line 639 of file kb.c.

640 {
641  while (item != NULL)
642  {
643  struct kb_item *next;
644 
645  next = item->next;
646  if (item->type == KB_TYPE_STR && item->v_str != NULL)
647  g_free (item->v_str);
648  g_free (item);
649  item = next;
650  }
651 }

References KB_TYPE_STR, kb_item::next, kb_item::type, and kb_item::v_str.

Referenced by nvticache_get_prefs(), redis_get_int(), and redis_get_str().

Here is the caller graph for this function:

◆ parse_port_of_addr()

static char* parse_port_of_addr ( const char *  addr,
int  tcp_indicator_len 
)
inlinestatic

Definition at line 250 of file kb.c.

251 {
252  char *tmp;
253  int is_ip_v6;
254  if ((tmp = rindex (addr + tcp_indicator_len, ':')) == NULL)
255  return NULL;
256  is_ip_v6 = addr[tcp_indicator_len] == '[';
257  if (is_ip_v6 && (tmp - 1)[0] != ']')
258  return NULL;
259  return tmp + 1;
260 }

Referenced by connect_redis().

Here is the caller graph for this function:

◆ redis2kbitem()

static struct kb_item* redis2kbitem ( const char *  name,
const redisReply *  rep 
)
static

Fetch a KB item or list from a redis Reply.

Parameters
[in]nameName of the item.
[in]repA redisReply element where to fetch the item.
Returns
kb_item or list on success, NULL otherwise.

Definition at line 708 of file kb.c.

709 {
710  struct kb_item *kbi;
711 
712  kbi = NULL;
713 
714  switch (rep->type)
715  {
716  unsigned int i;
717 
718  case REDIS_REPLY_STRING:
719  case REDIS_REPLY_INTEGER:
720  kbi = redis2kbitem_single (name, rep, 0);
721  break;
722 
723  case REDIS_REPLY_ARRAY:
724  for (i = 0; i < rep->elements; i++)
725  {
726  struct kb_item *tmpitem;
727 
728  tmpitem = redis2kbitem_single (name, rep->element[i], 0);
729  if (tmpitem == NULL)
730  break;
731 
732  if (kbi != NULL)
733  {
734  tmpitem->next = kbi;
735  kbi = tmpitem;
736  }
737  else
738  kbi = tmpitem;
739  }
740  break;
741 
742  case REDIS_REPLY_NIL:
743  case REDIS_REPLY_STATUS:
744  case REDIS_REPLY_ERROR:
745  default:
746  break;
747  }
748 
749  return kbi;
750 }

References kb_item::name, kb_item::next, and redis2kbitem_single().

Referenced by redis_get_all(), and redis_get_pattern().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ redis2kbitem_single()

static struct kb_item* redis2kbitem_single ( const char *  name,
const redisReply *  elt,
int  force_int 
)
static

Give a single KB item.

Parameters
[in]nameName of the item.
[in]eltA redisReply element where to fetch the item.
[in]force_intTo force string to integer conversion.
Returns
Single retrieve kb_item on success, NULL otherwise.

Definition at line 663 of file kb.c.

664 {
665  struct kb_item *item;
666  size_t namelen;
667 
668  if (elt->type != REDIS_REPLY_STRING && elt->type != REDIS_REPLY_INTEGER)
669  return NULL;
670 
671  namelen = strlen (name) + 1;
672 
673  item = g_malloc0 (sizeof (struct kb_item) + namelen);
674  if (elt->type == REDIS_REPLY_INTEGER)
675  {
676  item->type = KB_TYPE_INT;
677  item->v_int = elt->integer;
678  }
679  else if (force_int)
680  {
681  item->type = KB_TYPE_INT;
682  item->v_int = atoi (elt->str);
683  }
684  else
685  {
686  item->type = KB_TYPE_STR;
687  item->v_str = memdup (elt->str, elt->len + 1);
688  item->len = elt->len;
689  }
690 
691  item->next = NULL;
692  item->namelen = namelen;
693  memset (item->name, 0, namelen);
694  memcpy (item->name, name, namelen);
695 
696  return item;
697 }

References KB_TYPE_INT, KB_TYPE_STR, kb_item::len, memdup, kb_item::name, kb_item::namelen, kb_item::next, kb_item::type, kb_item::v_int, and kb_item::v_str.

Referenced by redis2kbitem(), and redis_get_single().

Here is the caller graph for this function:

◆ redis_add_int()

static int redis_add_int ( kb_t  kb,
const char *  name,
int  val 
)
static

Insert (append) a new entry under a given name.

Parameters
[in]kbKB handle where to store the item.
[in]nameItem name.
[in]valItem value.
Returns
0 on success, non-null on error.

Definition at line 1543 of file kb.c.

1544 {
1545  redisReply *rep;
1546  int rc = 0;
1547 
1548  rep = redis_cmd (redis_kb (kb), "RPUSH %s %d", name, val);
1549  if (!rep || rep->type == REDIS_REPLY_ERROR)
1550  rc = -1;
1551  if (rep)
1552  freeReplyObject (rep);
1553 
1554  return rc;
1555 }

References redis_cmd(), and redis_kb.

Here is the call graph for this function:

◆ redis_add_int_unique()

static int redis_add_int_unique ( kb_t  kb,
const char *  name,
int  val 
)
static

Insert (append) a new unique entry under a given name.

Parameters
[in]kbKB handle where to store the item.
[in]nameItem name.
[in]valItem value.
Returns
0 on success, non-null on error.

Definition at line 1502 of file kb.c.

1503 {
1504  struct kb_redis *kbr;
1505  redisReply *rep;
1506  int rc = 0;
1507  redisContext *ctx;
1508 
1509  kbr = redis_kb (kb);
1510  if (get_redis_ctx (kbr) < 0)
1511  return -1;
1512  ctx = kbr->rctx;
1513  redisAppendCommand (ctx, "LREM %s 1 %d", name, val);
1514  redisAppendCommand (ctx, "RPUSH %s %d", name, val);
1515  redisGetReply (ctx, (void **) &rep);
1516  if (rep && rep->type == REDIS_REPLY_INTEGER && rep->integer == 1)
1517  g_debug ("Key '%s' already contained integer '%d'", name, val);
1518  freeReplyObject (rep);
1519  redisGetReply (ctx, (void **) &rep);
1520  if (rep == NULL || rep->type == REDIS_REPLY_ERROR)
1521  {
1522  rc = -1;
1523  goto out;
1524  }
1525 
1526 out:
1527  if (rep != NULL)
1528  freeReplyObject (rep);
1529 
1530  return rc;
1531 }

References get_redis_ctx(), kb_redis::rctx, and redis_kb.

Here is the call graph for this function:

◆ redis_add_int_unique_volatile()

static int redis_add_int_unique_volatile ( kb_t  kb,
const char *  name,
int  val,
int  expire 
)
static

Insert (append) a new unique entry under a given name.

Parameters
[in]kbKB handle where to store the item.
[in]nameItem name.
[in]valItem value.
[in]expireItem expire.
Returns
0 on success, non-null on error.

Definition at line 1449 of file kb.c.

1450 {
1451  struct kb_redis *kbr;
1452  redisReply *rep;
1453  int rc = 0;
1454  redisContext *ctx;
1455 
1456  kbr = redis_kb (kb);
1457  if (get_redis_ctx (kbr) < 0)
1458  return -1;
1459  ctx = kbr->rctx;
1460  redisAppendCommand (ctx, "LREM %s 1 %d", name, val);
1461  redisAppendCommand (ctx, "RPUSH %s %d", name, val);
1462  redisAppendCommand (ctx, "EXPIRE %s %d", name, expire);
1463  /* Check LREM reply. */
1464  redisGetReply (ctx, (void **) &rep);
1465  if (rep && rep->type == REDIS_REPLY_INTEGER && rep->integer == 1)
1466  g_debug ("Key '%s' already contained integer '%d'", name, val);
1467  freeReplyObject (rep);
1468  /* Check PUSH reply. */
1469  redisGetReply (ctx, (void **) &rep);
1470  if (rep == NULL || rep->type == REDIS_REPLY_ERROR)
1471  {
1472  rc = -1;
1473  goto out;
1474  }
1475  /* Check EXPIRE reply. */
1476  redisGetReply (ctx, (void **) &rep);
1477  if (rep == NULL || rep->type == REDIS_REPLY_ERROR
1478  || (rep && rep->type == REDIS_REPLY_INTEGER && rep->integer != 1))
1479  {
1480  g_warning ("%s: Not able to set expire", __func__);
1481  rc = -1;
1482  goto out;
1483  }
1484 
1485 out:
1486  if (rep != NULL)
1487  freeReplyObject (rep);
1488 
1489  return rc;
1490 }

References get_redis_ctx(), kb_redis::rctx, and redis_kb.

Here is the call graph for this function:

◆ redis_add_nvt()

static int redis_add_nvt ( kb_t  kb,
const nvti_t nvt,
const char *  filename 
)
static

Insert a new nvt.

Parameters
[in]kbKB handle where to store the nvt.
[in]nvtnvt to store.
[in]filenamePath to nvt to store.
Returns
0 on success, non-null on error.

Definition at line 1604 of file kb.c.

1605 {
1606  struct kb_redis *kbr;
1607  redisReply *rep = NULL;
1608  int rc = 0;
1609  unsigned int i;
1610  gchar *cves, *bids, *xrefs;
1611 
1612  if (!nvt || !filename)
1613  return -1;
1614 
1615  cves = nvti_refs (nvt, "cve", "", 0);
1616  bids = nvti_refs (nvt, "bid", "", 0);
1617  xrefs = nvti_refs (nvt, NULL, "cve,bid", 1);
1618 
1619  kbr = redis_kb (kb);
1620  rep = redis_cmd (
1621  kbr, "RPUSH nvt:%s %s %s %s %s %s %s %s %s %s %s %s %d %s %s",
1622  nvti_oid (nvt), filename,
1623  nvti_required_keys (nvt) ? nvti_required_keys (nvt) : "",
1624  nvti_mandatory_keys (nvt) ? nvti_mandatory_keys (nvt) : "",
1625  nvti_excluded_keys (nvt) ? nvti_excluded_keys (nvt) : "",
1627  nvti_required_ports (nvt) ? nvti_required_ports (nvt) : "",
1628  nvti_dependencies (nvt) ? nvti_dependencies (nvt) : "",
1629  nvti_tag (nvt) ? nvti_tag (nvt) : "", cves ? cves : "", bids ? bids : "",
1630  xrefs ? xrefs : "", nvti_category (nvt), nvti_family (nvt),
1631  nvti_name (nvt));
1632  g_free (cves);
1633  g_free (bids);
1634  g_free (xrefs);
1635  if (rep == NULL || rep->type == REDIS_REPLY_ERROR)
1636  rc = -1;
1637  if (rep != NULL)
1638  freeReplyObject (rep);
1639 
1640  if (nvti_pref_len (nvt))
1641  redis_cmd (kbr, "DEL oid:%s:prefs", nvti_oid (nvt));
1642  for (i = 0; i < nvti_pref_len (nvt); i++)
1643  {
1644  const nvtpref_t *pref = nvti_pref (nvt, i);
1645 
1646  rep = redis_cmd (kbr, "RPUSH oid:%s:prefs %d|||%s|||%s|||%s",
1647  nvti_oid (nvt), nvtpref_id (pref), nvtpref_name (pref),
1648  nvtpref_type (pref), nvtpref_default (pref));
1649  if (!rep || rep->type == REDIS_REPLY_ERROR)
1650  rc = -1;
1651  if (rep)
1652  freeReplyObject (rep);
1653  }
1654  rep = redis_cmd (kbr, "RPUSH filename:%s %lu %s", filename, time (NULL),
1655  nvti_oid (nvt));
1656  if (!rep || rep->type == REDIS_REPLY_ERROR)
1657  rc = -1;
1658  if (rep)
1659  freeReplyObject (rep);
1660  return rc;
1661 }

References nvti_category(), nvti_dependencies(), nvti_excluded_keys(), nvti_family(), nvti_mandatory_keys(), nvti_name(), nvti_oid(), nvti_pref(), nvti_pref_len(), nvti_refs(), nvti_required_keys(), nvti_required_ports(), nvti_required_udp_ports(), nvti_tag(), nvtpref_default(), nvtpref_id(), nvtpref_name(), nvtpref_type(), redis_cmd(), and redis_kb.

Here is the call graph for this function:

◆ redis_add_str()

static int redis_add_str ( kb_t  kb,
const char *  name,
const char *  str,
size_t  len 
)
static

Insert (append) a new entry under a given name.

Parameters
[in]kbKB handle where to store the item.
[in]nameItem name.
[in]strItem value.
[in]lenValue length. Used for blobs.
Returns
0 on success, non-null on error.

Definition at line 1378 of file kb.c.

1379 {
1380  struct kb_redis *kbr;
1381  redisReply *rep;
1382  int rc = 0;
1383 
1384  kbr = redis_kb (kb);
1385  if (len == 0)
1386  rep = redis_cmd (kbr, "RPUSH %s %s", name, str);
1387  else
1388  rep = redis_cmd (kbr, "RPUSH %s %b", name, str, len);
1389  if (!rep || rep->type == REDIS_REPLY_ERROR)
1390  rc = -1;
1391 
1392  if (rep)
1393  freeReplyObject (rep);
1394  return rc;
1395 }

References redis_cmd(), and redis_kb.

Here is the call graph for this function:

◆ redis_add_str_unique()

static int redis_add_str_unique ( kb_t  kb,
const char *  name,
const char *  str,
size_t  len,
int  pos 
)
static

Insert (append) a new unique entry under a given name.

Parameters
[in]kbKB handle where to store the item.
[in]nameItem name.
[in]strItem value.
[in]lenValue length. Used for blobs.
[in]posWhich position the value is appended to. 0 for right, 1 for left position in the list.
Returns
0 on success, non-null on error.

Definition at line 1320 of file kb.c.

1322 {
1323  struct kb_redis *kbr;
1324  redisReply *rep = NULL;
1325  int rc = 0;
1326  redisContext *ctx;
1327 
1328  kbr = redis_kb (kb);
1329  if (get_redis_ctx (kbr) < 0)
1330  return -1;
1331  ctx = kbr->rctx;
1332 
1333  /* Some VTs still rely on values being unique (ie. a value inserted multiple
1334  * times, will only be present once.)
1335  * Once these are fixed, the LREM becomes redundant and should be removed.
1336  */
1337  if (len == 0)
1338  {
1339  redisAppendCommand (ctx, "LREM %s 1 %s", name, str);
1340  redisAppendCommand (ctx, "%s %s %s", pos ? "LPUSH" : "RPUSH", name, str);
1341  redisGetReply (ctx, (void **) &rep);
1342  if (rep && rep->type == REDIS_REPLY_INTEGER && rep->integer == 1)
1343  g_debug ("Key '%s' already contained value '%s'", name, str);
1344  freeReplyObject (rep);
1345  redisGetReply (ctx, (void **) &rep);
1346  }
1347  else
1348  {
1349  redisAppendCommand (ctx, "LREM %s 1 %b", name, str, len);
1350  redisAppendCommand (ctx, "%s %s %b", pos ? "LPUSH" : "RPUSH", name, str,
1351  len);
1352  redisGetReply (ctx, (void **) &rep);
1353  if (rep && rep->type == REDIS_REPLY_INTEGER && rep->integer == 1)
1354  g_debug ("Key '%s' already contained string '%s'", name, str);
1355  freeReplyObject (rep);
1356  redisGetReply (ctx, (void **) &rep);
1357  }
1358  if (rep == NULL || rep->type == REDIS_REPLY_ERROR)
1359  rc = -1;
1360 
1361  if (rep != NULL)
1362  freeReplyObject (rep);
1363 
1364  return rc;
1365 }

References get_redis_ctx(), kb_redis::rctx, and redis_kb.

Here is the call graph for this function:

◆ redis_add_str_unique_volatile()

static int redis_add_str_unique_volatile ( kb_t  kb,
const char *  name,
const char *  str,
int  expire,
size_t  len,
int  pos 
)
static

Insert (append) a new unique and volatile entry under a given name.

Parameters
[in]kbKB handle where to store the item.
[in]nameItem name.
[in]strItem value.
[in]expireItem expire.
[in]lenValue length. Used for blobs.
[in]posWhich position the value is appended to. 0 for right, 1 for left position in the list.
Returns
0 on success, -1 on error.

Definition at line 1227 of file kb.c.

1229 {
1230  struct kb_redis *kbr;
1231  redisReply *rep = NULL;
1232  int rc = 0;
1233  redisContext *ctx;
1234 
1235  kbr = redis_kb (kb);
1236  if (get_redis_ctx (kbr) < 0)
1237  return -1;
1238  ctx = kbr->rctx;
1239 
1240  /* Some VTs still rely on values being unique (ie. a value inserted multiple
1241  * times, will only be present once.)
1242  * Once these are fixed, the LREM becomes redundant and should be removed.
1243  */
1244  if (len == 0)
1245  {
1246  redisAppendCommand (ctx, "LREM %s 1 %s", name, str);
1247  redisAppendCommand (ctx, "%s %s %s", pos ? "LPUSH" : "RPUSH", name, str);
1248  redisAppendCommand (ctx, "EXPIRE %s %d", name, expire);
1249  /* Check LREM reply. */
1250  redisGetReply (ctx, (void **) &rep);
1251  if (rep && rep->type == REDIS_REPLY_INTEGER && rep->integer == 1)
1252  g_debug ("Key '%s' already contained value '%s'", name, str);
1253  freeReplyObject (rep);
1254  /* Check PUSH reply. */
1255  redisGetReply (ctx, (void **) &rep);
1256  if (rep == NULL || rep->type == REDIS_REPLY_ERROR)
1257  {
1258  rc = -1;
1259  goto out;
1260  }
1261  /* Check EXPIRE reply. */
1262  redisGetReply (ctx, (void **) &rep);
1263  if (rep == NULL || rep->type == REDIS_REPLY_ERROR
1264  || (rep && rep->type == REDIS_REPLY_INTEGER && rep->integer != 1))
1265  {
1266  g_warning ("%s: Not able to set expire", __func__);
1267  rc = -1;
1268  goto out;
1269  }
1270  }
1271  else
1272  {
1273  redisAppendCommand (ctx, "LREM %s 1 %b", name, str, len);
1274  redisAppendCommand (ctx, "%s %s %b", pos ? "LPUSH" : "RPUSH", name, str,
1275  len);
1276  redisAppendCommand (ctx, "EXPIRE %s %d", name, expire);
1277  /* Check LREM reply. */
1278  redisGetReply (ctx, (void **) &rep);
1279  if (rep && rep->type == REDIS_REPLY_INTEGER && rep->integer == 1)
1280  g_debug ("Key '%s' already contained string '%s'", name, str);
1281  freeReplyObject (rep);
1282  /* Check PUSH reply. */
1283  redisGetReply (ctx, (void **) &rep);
1284  if (rep == NULL || rep->type == REDIS_REPLY_ERROR)
1285  {
1286  rc = -1;
1287  goto out;
1288  }
1289  /* Check EXPIRE reply. */
1290  redisGetReply (ctx, (void **) &rep);
1291  if (rep == NULL || rep->type == REDIS_REPLY_ERROR
1292  || (rep && rep->type == REDIS_REPLY_INTEGER && rep->integer != 1))
1293  {
1294  g_warning ("%s: Not able to set expire", __func__);
1295  rc = -1;
1296  goto out;
1297  }
1298  }
1299 
1300 out:
1301  if (rep != NULL)
1302  freeReplyObject (rep);
1303 
1304  return rc;
1305 }

References get_redis_ctx(), kb_redis::rctx, and redis_kb.

Here is the call graph for this function:

◆ redis_cmd()

static redisReply * redis_cmd ( struct kb_redis kbr,
const char *  fmt,
  ... 
)
static

Execute a redis command and get a redis reply.

Parameters
[in]kbrSubclass of struct kb to connect to.
[in]fmtFormatted variable argument list with the cmd to be executed.
Returns
Redis reply on success, NULL otherwise.

Definition at line 761 of file kb.c.

762 {
763  redisReply *rep;
764  va_list ap, aq;
765  int retry = 0;
766 
767  va_start (ap, fmt);
768  do
769  {
770  if (get_redis_ctx (kbr) < 0)
771  {
772  va_end (ap);
773  return NULL;
774  }
775 
776  va_copy (aq, ap);
777  rep = redisvCommand (kbr->rctx, fmt, aq);
778  va_end (aq);
779 
780  if (kbr->rctx->err)
781  {
782  if (rep != NULL)
783  freeReplyObject (rep);
784 
785  redis_lnk_reset ((kb_t) kbr);
786  retry = !retry;
787  }
788  else
789  retry = 0;
790  }
791  while (retry);
792 
793  va_end (ap);
794 
795  return rep;
796 }

References get_redis_ctx(), kb_redis::rctx, and redis_lnk_reset().

Referenced by redis_add_int(), redis_add_nvt(), redis_add_str(), redis_count(), redis_del_items(), redis_delete_all(), redis_get_all(), redis_get_nvt(), redis_get_nvt_all(), redis_get_oids(), redis_get_pattern(), redis_get_single(), redis_memory_purge(), redis_pop_str(), redis_push_str(), redis_save(), and redis_test_connection().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ redis_count()

static size_t redis_count ( kb_t  kb,
const char *  pattern 
)
static

Count all items stored under a given pattern.

Parameters
[in]kbKB handle where to count the items.
[in]pattern'*' pattern of the elements to count.
Returns
Count of items.

Definition at line 1163 of file kb.c.

1164 {
1165  struct kb_redis *kbr;
1166  redisReply *rep;
1167  size_t count;
1168 
1169  kbr = redis_kb (kb);
1170 
1171  rep = redis_cmd (kbr, "KEYS %s", pattern);
1172  if (rep == NULL)
1173  return 0;
1174 
1175  if (rep->type != REDIS_REPLY_ARRAY)
1176  {
1177  freeReplyObject (rep);
1178  return 0;
1179  }
1180 
1181  count = rep->elements;
1182  freeReplyObject (rep);
1183  return count;
1184 }

References redis_cmd(), and redis_kb.

Here is the call graph for this function:

◆ redis_del_items()

static int redis_del_items ( kb_t  kb,
const char *  name 
)
static

Delete all entries under a given name.

Parameters
[in]kbKB handle where to store the item.
[in]nameItem name.
Returns
0 on success, non-null on error.

Definition at line 1195 of file kb.c.

1196 {
1197  struct kb_redis *kbr;
1198  redisReply *rep;
1199  int rc = 0;
1200 
1201  kbr = redis_kb (kb);
1202 
1203  rep = redis_cmd (kbr, "DEL %s", name);
1204  if (rep == NULL || rep->type == REDIS_REPLY_ERROR)
1205  rc = -1;
1206 
1207  if (rep != NULL)
1208  freeReplyObject (rep);
1209 
1210  return rc;
1211 }

References redis_cmd(), and redis_kb.

Here is the call graph for this function:

◆ redis_delete()

static int redis_delete ( kb_t  kb)
static

Delete all entries and release ownership on the namespace.

Parameters
[in]kbKB handle to release.
Returns
0 on success, non-null on error.

Definition at line 392 of file kb.c.

393 {
394  struct kb_redis *kbr;
395 
396  kbr = redis_kb (kb);
397 
398  redis_delete_all (kbr);
399  redis_release_db (kbr);
400 
401  if (kbr->rctx != NULL)
402  {
403  g_free (kbr->path);
404  redisFree (kbr->rctx);
405  kbr->rctx = NULL;
406  }
407 
408  g_free (kb);
409  return 0;
410 }

References kb_redis::path, kb_redis::rctx, redis_delete_all(), redis_kb, and redis_release_db().

Referenced by redis_new().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ redis_delete_all()

int redis_delete_all ( struct kb_redis kbr)
static

Delete all the KB's content.

Parameters
[in]kbrSubclass of struct kb.
Returns
0 on success, non-null on error.

Definition at line 1806 of file kb.c.

1807 {
1808  int rc;
1809  redisReply *rep;
1810  struct sigaction new_action, original_action;
1811 
1812  /* Ignore SIGPIPE, in case of a lost connection. */
1813  new_action.sa_flags = 0;
1814  if (sigemptyset (&new_action.sa_mask))
1815  return -1;
1816  new_action.sa_handler = SIG_IGN;
1817  if (sigaction (SIGPIPE, &new_action, &original_action))
1818  return -1;
1819 
1820  if (kbr)
1821  g_debug ("%s: deleting all elements from KB #%u", __func__, kbr->db);
1822  rep = redis_cmd (kbr, "FLUSHDB");
1823  if (rep == NULL || rep->type != REDIS_REPLY_STATUS)
1824  {
1825  rc = -1;
1826  goto err_cleanup;
1827  }
1828 
1829  rc = 0;
1830 
1831 err_cleanup:
1832  if (sigaction (SIGPIPE, &original_action, NULL))
1833  return -1;
1834  if (rep != NULL)
1835  freeReplyObject (rep);
1836 
1837  return rc;
1838 }

References kb_redis::db, and redis_cmd().

Referenced by redis_delete(), redis_flush_all(), and redis_new().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ redis_direct_conn()

static kb_t redis_direct_conn ( const char *  kb_path,
const int  kb_index 
)
static

Connect to a Knowledge Base object with the given kb_index.

Parameters
[in]kb_pathPath to KB.
[in]kb_indexDB index
Returns
Knowledge Base object, NULL otherwise.

Definition at line 513 of file kb.c.

514 {
515  struct kb_redis *kbr;
516  redisReply *rep;
517 
518  if (kb_path == NULL)
519  return NULL;
520 
521  kbr = g_malloc0 (sizeof (struct kb_redis));
522  kbr->kb.kb_ops = &KBRedisOperations;
523  kbr->path = g_strdup (kb_path);
524 
525  kbr->rctx = connect_redis (kbr->path, strlen (kbr->path));
526  if (kbr->rctx == NULL || kbr->rctx->err)
527  {
528  g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
529  "%s: redis connection error to %s: %s", __func__, kbr->path,
530  kbr->rctx ? kbr->rctx->errstr : strerror (ENOMEM));
531  redisFree (kbr->rctx);
532  g_free (kbr->path);
533  g_free (kbr);
534  return NULL;
535  }
536  kbr->db = kb_index;
537  rep = redisCommand (kbr->rctx, "SELECT %d", kb_index);
538  if (rep == NULL || rep->type != REDIS_REPLY_STATUS)
539  {
540  if (rep != NULL)
541  freeReplyObject (rep);
542  redisFree (kbr->rctx);
543  kbr->rctx = NULL;
544  g_free (kbr->path);
545  g_free (kbr);
546  return NULL;
547  }
548  freeReplyObject (rep);
549  return (kb_t) kbr;
550 }

References connect_redis(), kb_redis::db, G_LOG_DOMAIN, kb_redis::kb, kb::kb_ops, KBRedisOperations, kb_redis::path, and kb_redis::rctx.

Here is the call graph for this function:

◆ redis_find()

static kb_t redis_find ( const char *  kb_path,
const char *  key 
)
static

Find an existing Knowledge Base object with key.

Parameters
[in]kb_pathPath to KB.
[in]keyMarker key to search for in KB objects.
Returns
Knowledge Base object, NULL otherwise.

Definition at line 561 of file kb.c.

562 {
563  struct kb_redis *kbr;
564  unsigned int i = 1;
565 
566  if (kb_path == NULL)
567  return NULL;
568 
569  kbr = g_malloc0 (sizeof (struct kb_redis));
570  kbr->kb.kb_ops = &KBRedisOperations;
571  kbr->path = g_strdup (kb_path);
572 
573  do
574  {
575  redisReply *rep;
576 
577  kbr->rctx = connect_redis (kbr->path, strlen (kbr->path));
578  if (kbr->rctx == NULL || kbr->rctx->err)
579  {
580  g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
581  "%s: redis connection error to %s: %s", __func__, kbr->path,
582  kbr->rctx ? kbr->rctx->errstr : strerror (ENOMEM));
583  redisFree (kbr->rctx);
584  g_free (kbr->path);
585  g_free (kbr);
586  return NULL;
587  }
588 
589  if (kbr->max_db == 0)
590  fetch_max_db_index (kbr);
591 
592  kbr->db = i;
593  rep = redisCommand (kbr->rctx, "HEXISTS %s %d", GLOBAL_DBINDEX_NAME, i);
594  if (rep == NULL || rep->type != REDIS_REPLY_INTEGER || rep->integer != 1)
595  {
596  if (rep != NULL)
597  freeReplyObject (rep);
598  i++;
599  redisFree (kbr->rctx);
600  kbr->rctx = NULL;
601  continue;
602  }
603  freeReplyObject (rep);
604  rep = redisCommand (kbr->rctx, "SELECT %u", i);
605  if (rep == NULL || rep->type != REDIS_REPLY_STATUS)
606  {
607  redisFree (kbr->rctx);
608  kbr->rctx = NULL;
609  }
610  else
611  {
612  freeReplyObject (rep);
613  if (key)
614  {
615  char *tmp = kb_item_get_str (&kbr->kb, key);
616  if (tmp)
617  {
618  g_free (tmp);
619  return (kb_t) kbr;
620  }
621  }
622  redisFree (kbr->rctx);
623  }
624  i++;
625  }
626  while (i < kbr->max_db);
627 
628  g_free (kbr->path);
629  g_free (kbr);
630  return NULL;
631 }

References connect_redis(), kb_redis::db, fetch_max_db_index(), G_LOG_DOMAIN, GLOBAL_DBINDEX_NAME, kb_redis::kb, kb_item_get_str(), kb::kb_ops, KBRedisOperations, kb_redis::max_db, kb_redis::path, and kb_redis::rctx.

Here is the call graph for this function:

◆ redis_flush_all()

static int redis_flush_all ( kb_t  kb,
const char *  except 
)
static

Flush all the KB's content. Delete all namespaces.

Parameters
[in]kbKB handle.
[in]exceptDon't flush DB with except key.
Returns
0 on success, non-null on error.

Definition at line 1696 of file kb.c.

1697 {
1698  unsigned int i = 1;
1699  struct kb_redis *kbr;
1700 
1701  kbr = redis_kb (kb);
1702  if (kbr->rctx)
1703  redisFree (kbr->rctx);
1704 
1705  g_debug ("%s: deleting all DBs at %s except %s", __func__, kbr->path, except);
1706  do
1707  {
1708  redisReply *rep;
1709 
1710  kbr->rctx = connect_redis (kbr->path, strlen (kbr->path));
1711  if (kbr->rctx == NULL || kbr->rctx->err)
1712  {
1713  g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
1714  "%s: redis connection error to %s: %s", __func__, kbr->path,
1715  kbr->rctx ? kbr->rctx->errstr : strerror (ENOMEM));
1716  redisFree (kbr->rctx);
1717  kbr->rctx = NULL;
1718  return -1;
1719  }
1720 
1721  kbr->db = i;
1722  rep = redisCommand (kbr->rctx, "HEXISTS %s %d", GLOBAL_DBINDEX_NAME, i);
1723  if (rep == NULL || rep->type != REDIS_REPLY_INTEGER || rep->integer != 1)
1724  {
1725  freeReplyObject (rep);
1726  redisFree (kbr->rctx);
1727  i++;
1728  continue;
1729  }
1730  freeReplyObject (rep);
1731  rep = redisCommand (kbr->rctx, "SELECT %u", i);
1732  if (rep == NULL || rep->type != REDIS_REPLY_STATUS)
1733  {
1734  freeReplyObject (rep);
1735  redisFree (kbr->rctx);
1736  kbr->rctx = NULL;
1737  }
1738  else
1739  {
1740  freeReplyObject (rep);
1741  /* Don't remove DB if it has "except" key. */
1742  if (except)
1743  {
1744  char *tmp = kb_item_get_str (kb, except);
1745  if (tmp)
1746  {
1747  g_free (tmp);
1748  i++;
1749  redisFree (kbr->rctx);
1750  continue;
1751  }
1752  }
1753  redis_delete_all (kbr);
1754  redis_release_db (kbr);
1755  redisFree (kbr->rctx);
1756  }
1757  i++;
1758  }
1759  while (i < kbr->max_db);
1760 
1761  g_free (kbr->path);
1762  g_free (kb);
1763  return 0;
1764 }

References connect_redis(), kb_redis::db, G_LOG_DOMAIN, GLOBAL_DBINDEX_NAME, kb_item_get_str(), kb_redis::max_db, kb_redis::path, kb_redis::rctx, redis_delete_all(), redis_kb, and redis_release_db().

Here is the call graph for this function:

◆ redis_get_all()

static struct kb_item* redis_get_all ( kb_t  kb,
const char *  name 
)
static

Get all items stored under a given name.

Parameters
[in]kbKB handle where to fetch the items.
[in]nameName of the elements to retrieve.
Returns
Linked struct kb_item instances to be freed with kb_item_free() or NULL if no element was found or on error.

Definition at line 1035 of file kb.c.

1036 {
1037  struct kb_redis *kbr;
1038  struct kb_item *kbi;
1039  redisReply *rep;
1040 
1041  kbr = redis_kb (kb);
1042 
1043  rep = redis_cmd (kbr, "LRANGE %s 0 -1", name);
1044  if (rep == NULL)
1045  return NULL;
1046 
1047  kbi = redis2kbitem (name, rep);
1048 
1049  freeReplyObject (rep);
1050 
1051  return kbi;
1052 }

References kb_item::name, redis2kbitem(), redis_cmd(), and redis_kb.

Here is the call graph for this function:

◆ redis_get_int()

static int redis_get_int ( kb_t  kb,
const char *  name 
)
static

Get a single KB integer item.

Parameters
[in]kbKB handle where to fetch the item.
[in]nameName of the element to retrieve.
Returns
An integer.

Definition at line 927 of file kb.c.

928 {
929  struct kb_item *kbi;
930 
932  if (kbi != NULL)
933  {
934  int res;
935 
936  res = kbi->v_int;
937  kb_item_free (kbi);
938  return res;
939  }
940  return -1;
941 }

References kb_item_free(), KB_TYPE_INT, kb_item::name, redis_get_single(), and kb_item::v_int.

Here is the call graph for this function:

◆ redis_get_kb_index()

static int redis_get_kb_index ( kb_t  kb)
static

Return the kb index.

Parameters
[in]kbKB handle.
Returns
kb_index on success, null on error.

Definition at line 420 of file kb.c.

421 {
422  int i;
423  i = ((struct kb_redis *) kb)->db;
424  if (i > 0)
425  return i;
426  return -1;
427 }

◆ redis_get_nvt()

static char* redis_get_nvt ( kb_t  kb,
const char *  oid,
enum kb_nvt_pos  position 
)
static

Get field of a NVT.

Parameters
[in]kbKB handle where to store the nvt.
[in]oidOID of NVT to get from.
[in]positionPosition of field to get.
Returns
Value of field, NULL otherwise.

Definition at line 953 of file kb.c.

954 {
955  struct kb_redis *kbr;
956  redisReply *rep;
957  char *res = NULL;
958 
959  kbr = redis_kb (kb);
960  if (position >= NVT_TIMESTAMP_POS)
961  rep = redis_cmd (kbr, "LINDEX filename:%s %d", oid,
962  position - NVT_TIMESTAMP_POS);
963  else
964  rep = redis_cmd (kbr, "LINDEX nvt:%s %d", oid, position);
965  if (!rep)
966  return NULL;
967  if (rep->type == REDIS_REPLY_INTEGER)
968  res = g_strdup_printf ("%lld", rep->integer);
969  else if (rep->type == REDIS_REPLY_STRING)
970  res = g_strdup (rep->str);
971  freeReplyObject (rep);
972 
973  return res;
974 }

References NVT_TIMESTAMP_POS, redis_cmd(), and redis_kb.

Here is the call graph for this function:

◆ redis_get_nvt_all()

static nvti_t* redis_get_nvt_all ( kb_t  kb,
const char *  oid 
)
static

Get a full NVT.

Parameters
[in]kbKB handle where to store the nvt.
[in]oidOID of NVT to get.
Returns
nvti_t of NVT, NULL otherwise.

Definition at line 985 of file kb.c.

986 {
987  struct kb_redis *kbr;
988  redisReply *rep;
989 
990  kbr = redis_kb (kb);
991  rep =
992  redis_cmd (kbr, "LRANGE nvt:%s %d %d", oid, NVT_FILENAME_POS, NVT_NAME_POS);
993  if (!rep)
994  return NULL;
995  if (rep->type != REDIS_REPLY_ARRAY || rep->elements != NVT_NAME_POS + 1)
996  {
997  freeReplyObject (rep);
998  return NULL;
999  }
1000  else
1001  {
1002  nvti_t *nvti = nvti_new ();
1003 
1004  nvti_set_oid (nvti, oid);
1005  nvti_set_required_keys (nvti, rep->element[NVT_REQUIRED_KEYS_POS]->str);
1006  nvti_set_mandatory_keys (nvti, rep->element[NVT_MANDATORY_KEYS_POS]->str);
1007  nvti_set_excluded_keys (nvti, rep->element[NVT_EXCLUDED_KEYS_POS]->str);
1009  nvti, rep->element[NVT_REQUIRED_UDP_PORTS_POS]->str);
1010  nvti_set_required_ports (nvti, rep->element[NVT_REQUIRED_PORTS_POS]->str);
1011  nvti_set_dependencies (nvti, rep->element[NVT_DEPENDENCIES_POS]->str);
1012  nvti_set_tag (nvti, rep->element[NVT_TAGS_POS]->str);
1013  nvti_add_refs (nvti, "cve", rep->element[NVT_CVES_POS]->str, "");
1014  nvti_add_refs (nvti, "bid", rep->element[NVT_BIDS_POS]->str, "");
1015  nvti_add_refs (nvti, NULL, rep->element[NVT_XREFS_POS]->str, "");
1016  nvti_set_category (nvti, atoi (rep->element[NVT_CATEGORY_POS]->str));
1017  nvti_set_family (nvti, rep->element[NVT_FAMILY_POS]->str);
1018  nvti_set_name (nvti, rep->element[NVT_NAME_POS]->str);
1019 
1020  freeReplyObject (rep);
1021  return nvti;
1022  }
1023 }

References NVT_BIDS_POS, NVT_CATEGORY_POS, NVT_CVES_POS, NVT_DEPENDENCIES_POS, NVT_EXCLUDED_KEYS_POS, NVT_FAMILY_POS, NVT_FILENAME_POS, NVT_MANDATORY_KEYS_POS, NVT_NAME_POS, NVT_REQUIRED_KEYS_POS, NVT_REQUIRED_PORTS_POS, NVT_REQUIRED_UDP_PORTS_POS, NVT_TAGS_POS, NVT_XREFS_POS, nvti_add_refs(), nvti_new(), nvti_set_category(), nvti_set_dependencies(), nvti_set_excluded_keys(), nvti_set_family(), nvti_set_mandatory_keys(), nvti_set_name(), nvti_set_oid(), nvti_set_required_keys(), nvti_set_required_ports(), nvti_set_required_udp_ports(), nvti_set_tag(), redis_cmd(), and redis_kb.

Here is the call graph for this function:

◆ redis_get_oids()

static GSList* redis_get_oids ( kb_t  kb)
static

Get all NVT OIDs.

Parameters
[in]kbKB handle where to fetch the items.
Returns
Linked list of all OIDs or NULL.

Definition at line 1128 of file kb.c.

1129 {
1130  struct kb_redis *kbr;
1131  redisReply *rep;
1132  GSList *list = NULL;
1133  size_t i;
1134 
1135  kbr = redis_kb (kb);
1136  rep = redis_cmd (kbr, "KEYS nvt:*");
1137  if (!rep)
1138  return NULL;
1139 
1140  if (rep->type != REDIS_REPLY_ARRAY)
1141  {
1142  freeReplyObject (rep);
1143  return NULL;
1144  }
1145 
1146  /* Fetch OID values from key names nvt:OID. */
1147  for (i = 0; i < rep->elements; i++)
1148  list = g_slist_prepend (list, g_strdup (rep->element[i]->str + 4));
1149  freeReplyObject (rep);
1150 
1151  return list;
1152 }

References redis_cmd(), and redis_kb.

Here is the call graph for this function:

◆ redis_get_pattern()

static struct kb_item* redis_get_pattern ( kb_t  kb,
const char *  pattern 
)
static

Get all items stored under a given pattern.

Parameters
[in]kbKB handle where to fetch the items.
[in]pattern'*' pattern of the elements to retrieve.
Returns
Linked struct kb_item instances to be freed with kb_item_free() or NULL if no element was found or on error.

Definition at line 1064 of file kb.c.

1065 {
1066  struct kb_redis *kbr;
1067  struct kb_item *kbi = NULL;
1068  redisReply *rep;
1069  unsigned int i;
1070 
1071  kbr = redis_kb (kb);
1072  rep = redis_cmd (kbr, "KEYS %s", pattern);
1073  if (!rep)
1074  return NULL;
1075  if (rep->type != REDIS_REPLY_ARRAY)
1076  {
1077  freeReplyObject (rep);
1078  return NULL;
1079  }
1080 
1081  if (get_redis_ctx (kbr) < 0)
1082  return NULL;
1083  for (i = 0; i < rep->elements; i++)
1084  redisAppendCommand (kbr->rctx, "LRANGE %s 0 -1", rep->element[i]->str);
1085 
1086  for (i = 0; i < rep->elements; i++)
1087  {
1088  struct kb_item *tmp;
1089  redisReply *rep_range;
1090 
1091  redisGetReply (kbr->rctx, (void **) &rep_range);
1092  if (!rep)
1093  continue;
1094  tmp = redis2kbitem (rep->element[i]->str, rep_range);
1095  if (!tmp)
1096  {
1097  freeReplyObject (rep_range);
1098  continue;
1099  }
1100 
1101  if (kbi)
1102  {
1103  struct kb_item *tmp2;
1104 
1105  tmp2 = tmp;
1106  while (tmp->next)
1107  tmp = tmp->next;
1108  tmp->next = kbi;
1109  kbi = tmp2;
1110  }
1111  else
1112  kbi = tmp;
1113  freeReplyObject (rep_range);
1114  }
1115 
1116  freeReplyObject (rep);
1117  return kbi;
1118 }

References get_redis_ctx(), kb_item::next, kb_redis::rctx, redis2kbitem(), redis_cmd(), and redis_kb.

Here is the call graph for this function:

◆ redis_get_single()

static struct kb_item* redis_get_single ( kb_t  kb,
const char *  name,
enum kb_item_type  type 
)
static

Get a single KB element.

Parameters
[in]kbKB handle where to fetch the item.
[in]nameName of the element to retrieve.
[in]typeDesired element type.
Returns
A struct kb_item to be freed with kb_item_free() or NULL if no element was found or on error.

Definition at line 809 of file kb.c.

810 {
811  struct kb_item *kbi;
812  struct kb_redis *kbr;
813  redisReply *rep;
814 
815  kbr = redis_kb (kb);
816  kbi = NULL;
817 
818  rep = redis_cmd (kbr, "LINDEX %s -1", name);
819  if (rep == NULL || rep->type != REDIS_REPLY_STRING)
820  {
821  kbi = NULL;
822  goto out;
823  }
824 
825  kbi = redis2kbitem_single (name, rep, type == KB_TYPE_INT);
826 
827 out:
828  if (rep != NULL)
829  freeReplyObject (rep);
830 
831  return kbi;
832 }

References KB_TYPE_INT, redis2kbitem_single(), redis_cmd(), and redis_kb.

Referenced by redis_get_int(), and redis_get_str().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ redis_get_str()

static char* redis_get_str ( kb_t  kb,
const char *  name 
)
static

Get a single KB string item.

Parameters
[in]kbKB handle where to fetch the item.
[in]nameName of the element to retrieve.
Returns
A struct kb_item to be freed with kb_item_free() or NULL if no element was found or on error.

Definition at line 844 of file kb.c.

845 {
846  struct kb_item *kbi;
847 
849  if (kbi != NULL)
850  {
851  char *res;
852 
853  res = kbi->v_str;
854  kbi->v_str = NULL;
855  kb_item_free (kbi);
856  return res;
857  }
858  return NULL;
859 }

References kb_item_free(), KB_TYPE_STR, kb_item::name, redis_get_single(), and kb_item::v_str.

Here is the call graph for this function:

◆ redis_lnk_reset()

static int redis_lnk_reset ( kb_t  kb)
static

Reset connection to the KB. This is called after each fork() to make sure connections aren't shared between concurrent processes.

Parameters
[in]kbKB handle.
Returns
0 on success, non-null on error.

Definition at line 1672 of file kb.c.

1673 {
1674  struct kb_redis *kbr;
1675 
1676  kbr = redis_kb (kb);
1677 
1678  if (kbr->rctx != NULL)
1679  {
1680  redisFree (kbr->rctx);
1681  kbr->rctx = NULL;
1682  }
1683 
1684  return 0;
1685 }

References kb_redis::rctx, and redis_kb.

Referenced by redis_cmd().

Here is the caller graph for this function:

◆ redis_memory_purge()

static int redis_memory_purge ( kb_t  kb)
static

Attempt to purge dirty pages.

Attempt to purge dirty pages so these can be reclaimed by the allocator. This command only works when using jemalloc as an allocator, and evaluates to a benign NOOP for all others. Command is applied to complete redis instance and not only single db.

Parameters
[in]kbKB handle where to run the command.
Returns
0 on success, non-null on error.

Definition at line 442 of file kb.c.

443 {
444  redisReply *rep;
445  int rc = 0;
446 
447  rep = redis_cmd (redis_kb (kb), "MEMORY PURGE");
448  if (!rep || rep->type == REDIS_REPLY_ERROR)
449  rc = -1;
450  if (rep)
451  freeReplyObject (rep);
452 
453  return rc;
454 }

References redis_cmd(), and redis_kb.

Referenced by redis_new().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ redis_new()

static int redis_new ( kb_t kb,
const char *  kb_path 
)
static

Initialize a new Knowledge Base object.

Parameters
[in]kbReference to a kb_t to initialize.
[in]kb_pathPath to KB.
Returns
0 on success, -1 on connection error, -2 when no DB is available, -3 when given kb_path was NULL.

Definition at line 466 of file kb.c.

467 {
468  struct kb_redis *kbr;
469  int rc = 0;
470 
471  if (kb_path == NULL)
472  return -3;
473 
474  kbr = g_malloc0 (sizeof (struct kb_redis));
475  kbr->kb.kb_ops = &KBRedisOperations;
476  kbr->path = g_strdup (kb_path);
477 
478  if ((rc = get_redis_ctx (kbr)) < 0)
479  {
480  redis_delete ((kb_t) kbr);
481  return rc;
482  }
483  if (redis_test_connection (kbr))
484  {
485  g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
486  "%s: cannot access redis at '%s'", __func__, kb_path);
487  redis_delete ((kb_t) kbr);
488  kbr = NULL;
489  rc = -1;
490  }
491 
492  /* Ensure that the new kb is clean */
493  redis_delete_all (kbr);
494 
495  *kb = (kb_t) kbr;
496 
497  /* Try to make unused memory available for the OS again. */
498  if (redis_memory_purge (*kb))
499  g_warning ("%s: Memory purge was not successful", __func__);
500 
501  return rc;
502 }

References G_LOG_DOMAIN, get_redis_ctx(), kb_redis::kb, kb::kb_ops, KBRedisOperations, kb_redis::path, redis_delete(), redis_delete_all(), redis_memory_purge(), and redis_test_connection().

Here is the call graph for this function:

◆ redis_pop_str()

static char* redis_pop_str ( kb_t  kb,
const char *  name 
)
static

Pops a single KB string item.

Parameters
[in]kbKB handle where to fetch the item.
[in]nameName of the key from where to retrieve.
Returns
A string to be freed or NULL if list is empty or on error.

Definition at line 900 of file kb.c.

901 {
902  struct kb_redis *kbr;
903  redisReply *rep;
904  char *value = NULL;
905 
906  kbr = redis_kb (kb);
907  rep = redis_cmd (kbr, "RPOP %s", name);
908  if (!rep)
909  return NULL;
910 
911  if (rep->type == REDIS_REPLY_STRING)
912  value = g_strdup (rep->str);
913  freeReplyObject (rep);
914 
915  return value;
916 }

References redis_cmd(), and redis_kb.

Here is the call graph for this function:

◆ redis_push_str()

static int redis_push_str ( kb_t  kb,
const char *  name,
const char *  value 
)
static

Push a new entry under a given key.

Parameters
[in]kbKB handle where to store the item.
[in]nameKey to push to.
[in]valueValue to push.
Returns
0 on success, non-null on error.

Definition at line 871 of file kb.c.

872 {
873  struct kb_redis *kbr;
874  redisReply *rep = NULL;
875  int rc = 0;
876 
877  if (!value)
878  return -1;
879 
880  kbr = redis_kb (kb);
881  rep = redis_cmd (kbr, "LPUSH %s %s", name, value);
882  if (!rep || rep->type == REDIS_REPLY_ERROR)
883  rc = -1;
884 
885  if (rep)
886  freeReplyObject (rep);
887 
888  return rc;
889 }

References redis_cmd(), and redis_kb.

Here is the call graph for this function:

◆ redis_release_db()

static int redis_release_db ( struct kb_redis kbr)
static

Release DB.

Parameters
[in]kbrSubclass of struct kb.
Returns
0 on success, -1 on error.

Definition at line 216 of file kb.c.

217 {
218  int rc;
219  redisContext *ctx = kbr->rctx;
220  redisReply *rep;
221 
222  if (ctx == NULL)
223  return -EINVAL;
224 
225  rep = redisCommand (ctx, "SELECT 0"); /* Management database*/
226  if (rep == NULL || rep->type != REDIS_REPLY_STATUS)
227  {
228  rc = -1;
229  goto err_cleanup;
230  }
231  freeReplyObject (rep);
232 
233  rep = redisCommand (ctx, "HDEL %s %d", GLOBAL_DBINDEX_NAME, kbr->db);
234  if (rep == NULL || rep->type != REDIS_REPLY_INTEGER)
235  {
236  rc = -1;
237  goto err_cleanup;
238  }
239 
240  rc = 0;
241 
242 err_cleanup:
243  if (rep != NULL)
244  freeReplyObject (rep);
245 
246  return rc;
247 }

References kb_redis::db, GLOBAL_DBINDEX_NAME, and kb_redis::rctx.

Referenced by redis_delete(), and redis_flush_all().

Here is the caller graph for this function:

◆ redis_save()

static int redis_save ( kb_t  kb)
static

Save all the elements from the KB.

Parameters
[in]kbKB handle.
Returns
0 on success, -1 on error.

Definition at line 1774 of file kb.c.

1775 {
1776  int rc;
1777  redisReply *rep;
1778  struct kb_redis *kbr;
1779 
1780  kbr = redis_kb (kb);
1781  g_debug ("%s: saving all elements from KB #%u", __func__, kbr->db);
1782  rep = redis_cmd (kbr, "SAVE");
1783  if (rep == NULL || rep->type != REDIS_REPLY_STATUS)
1784  {
1785  rc = -1;
1786  goto err_cleanup;
1787  }
1788 
1789  rc = 0;
1790 
1791 err_cleanup:
1792  if (rep != NULL)
1793  freeReplyObject (rep);
1794 
1795  return rc;
1796 }

References kb_redis::db, redis_cmd(), and redis_kb.

Here is the call graph for this function:

◆ redis_set_int()

static int redis_set_int ( kb_t  kb,
const char *  name,
int  val 
)
static

Set (replace) a new entry under a given name.

Parameters
[in]kbKB handle where to store the item.
[in]nameItem name.
[in]valItem value.
Returns
0 on success, non-null on error.

Definition at line 1567 of file kb.c.

1568 {
1569  struct kb_redis *kbr;
1570  redisReply *rep = NULL;
1571  redisContext *ctx;
1572  int rc = 0, i = 4;
1573 
1574  kbr = redis_kb (kb);
1575  if (get_redis_ctx (redis_kb (kb)) < 0)
1576  return -1;
1577  ctx = kbr->rctx;
1578  redisAppendCommand (ctx, "MULTI");
1579  redisAppendCommand (ctx, "DEL %s", name);
1580  redisAppendCommand (ctx, "RPUSH %s %d", name, val);
1581  redisAppendCommand (ctx, "EXEC");
1582  while (i--)
1583  {
1584  redisGetReply (ctx, (void **) &rep);
1585  if (!rep || rep->type == REDIS_REPLY_ERROR)
1586  rc = -1;
1587  if (rep)
1588  freeReplyObject (rep);
1589  }
1590 
1591  return rc;
1592 }

References get_redis_ctx(), kb_redis::rctx, and redis_kb.

Here is the call graph for this function:

◆ redis_set_str()

static int redis_set_str ( kb_t  kb,
const char *  name,
const char *  val,
size_t  len 
)
static

Set (replace) a new entry under a given name.

Parameters
[in]kbKB handle where to store the item.
[in]nameItem name.
[in]valItem value.
[in]lenValue length. Used for blobs.
Returns
0 on success, non-null on error.

Definition at line 1408 of file kb.c.

1409 {
1410  struct kb_redis *kbr;
1411  redisReply *rep = NULL;
1412  redisContext *ctx;
1413  int rc = 0, i = 4;
1414 
1415  kbr = redis_kb (kb);
1416  if (get_redis_ctx (kbr) < 0)
1417  return -1;
1418  ctx = kbr->rctx;
1419  redisAppendCommand (ctx, "MULTI");
1420  redisAppendCommand (ctx, "DEL %s", name);
1421  if (len == 0)
1422  redisAppendCommand (ctx, "RPUSH %s %s", name, val);
1423  else
1424  redisAppendCommand (ctx, "RPUSH %s %b", name, val, len);
1425  redisAppendCommand (ctx, "EXEC");
1426  while (i--)
1427  {
1428  redisGetReply (ctx, (void **) &rep);
1429  if (!rep || rep->type == REDIS_REPLY_ERROR)
1430  rc = -1;
1431  if (rep)
1432  freeReplyObject (rep);
1433  }
1434 
1435  return rc;
1436 }

References get_redis_ctx(), kb_redis::rctx, and redis_kb.

Here is the call graph for this function:

◆ redis_test_connection()

static int redis_test_connection ( struct kb_redis kbr)
static

Test redis connection.

Parameters
[in]kbrSubclass of struct kb to test.
Returns
0 on success, negative integer on error.

Definition at line 351 of file kb.c.

352 {
353  int rc = 0;
354  redisReply *rep;
355 
356  rep = redis_cmd (kbr, "PING");
357  if (rep == NULL)
358  {
359  /* not 100% relevant but hiredis doesn't provide us with proper error
360  * codes. */
361  rc = -ECONNREFUSED;
362  goto out;
363  }
364 
365  if (rep->type != REDIS_REPLY_STATUS)
366  {
367  rc = -EINVAL;
368  goto out;
369  }
370 
371  if (g_ascii_strcasecmp (rep->str, "PONG"))
372  {
373  rc = -EPROTO;
374  goto out;
375  }
376 
377 out:
378  if (rep != NULL)
379  freeReplyObject (rep);
380 
381  return rc;
382 }

References redis_cmd().

Referenced by redis_new().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ select_database()

static int select_database ( struct kb_redis kbr)
static

Select DB.

WARNING: do not call redis_cmd in here, since our context is not fully acquired yet!

Parameters
[in]kbrSubclass of struct kb where to save the db index.
Returns
0 on success, -1 on error.

Definition at line 164 of file kb.c.

165 {
166  int rc;
167  redisContext *ctx = kbr->rctx;
168  redisReply *rep = NULL;
169 
170  if (kbr->db == 0)
171  {
172  unsigned i;
173 
174  if (kbr->max_db == 0)
175  fetch_max_db_index (kbr);
176 
177  for (i = 1; i < kbr->max_db; i++)
178  {
179  rc = try_database_index (kbr, i);
180  if (rc == 0)
181  break;
182  }
183  }
184 
185  /* No DB available, give up. */
186  if (kbr->db == 0)
187  {
188  rc = -1;
189  goto err_cleanup;
190  }
191 
192  rep = redisCommand (ctx, "SELECT %u", kbr->db);
193  if (rep == NULL || rep->type != REDIS_REPLY_STATUS)
194  {
195  rc = -1;
196  goto err_cleanup;
197  }
198 
199  rc = 0;
200 
201 err_cleanup:
202  if (rep != NULL)
203  freeReplyObject (rep);
204 
205  return rc;
206 }

References kb_redis::db, fetch_max_db_index(), kb_redis::max_db, kb_redis::rctx, and try_database_index().

Referenced by get_redis_ctx().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ try_database_index()

static int try_database_index ( struct kb_redis kbr,
int  index 
)
static

Attempt to atomically acquire ownership of a database.

Returns
0 on success, negative integer otherwise.

Definition at line 78 of file kb.c.

79 {
80  redisContext *ctx = kbr->rctx;
81  redisReply *rep;
82  int rc = 0;
83 
84  rep = redisCommand (ctx, "HSETNX %s %d 1", GLOBAL_DBINDEX_NAME, index);
85  if (rep == NULL)
86  return -ENOMEM;
87 
88  if (rep->type != REDIS_REPLY_INTEGER)
89  rc = -EPROTO;
90  else if (rep->integer == 0)
91  rc = -EALREADY;
92  else
93  kbr->db = index;
94 
95  freeReplyObject (rep);
96 
97  return rc;
98 }

References kb_redis::db, GLOBAL_DBINDEX_NAME, and kb_redis::rctx.

Referenced by select_database().

Here is the caller graph for this function:

Variable Documentation

◆ KBDefaultOperations

const struct kb_operations* KBDefaultOperations = &KBRedisOperations

Default KB operations. No selection mechanism is provided yet since there's only one implementation (redis-based).

Definition at line 1877 of file kb.c.

Referenced by kb_add_int_unique_volatile(), kb_add_str_unique_volatile(), kb_direct_conn(), kb_find(), and kb_new().

◆ KBRedisOperations

static const struct kb_operations KBRedisOperations
static
Initial value:
= {
.kb_new = redis_new,
.kb_find = redis_find,
.kb_delete = redis_delete,
.kb_get_single = redis_get_single,
.kb_get_str = redis_get_str,
.kb_get_int = redis_get_int,
.kb_get_nvt = redis_get_nvt,
.kb_get_nvt_all = redis_get_nvt_all,
.kb_get_nvt_oids = redis_get_oids,
.kb_push_str = redis_push_str,
.kb_pop_str = redis_pop_str,
.kb_get_all = redis_get_all,
.kb_get_pattern = redis_get_pattern,
.kb_count = redis_count,
.kb_add_str = redis_add_str,
.kb_add_str_unique = redis_add_str_unique,
.kb_add_str_unique_volatile = redis_add_str_unique_volatile,
.kb_set_str = redis_set_str,
.kb_add_int = redis_add_int,
.kb_add_int_unique = redis_add_int_unique,
.kb_add_int_unique_volatile = redis_add_int_unique_volatile,
.kb_set_int = redis_set_int,
.kb_add_nvt = redis_add_nvt,
.kb_del_items = redis_del_items,
.kb_lnk_reset = redis_lnk_reset,
.kb_save = redis_save,
.kb_flush = redis_flush_all,
.kb_direct_conn = redis_direct_conn,
.kb_get_kb_index = redis_get_kb_index}

Default KB operations.

No selection mechanism is provided yet since there's only one implementation (redis-based).

Definition at line 1 of file kb.c.

Referenced by redis_direct_conn(), redis_find(), and redis_new().

nvti_pref
const nvtpref_t * nvti_pref(const nvti_t *n, guint p)
Get the n'th preferences of the NVT.
Definition: nvti.c:1224
NVT_EXCLUDED_KEYS_POS
@ NVT_EXCLUDED_KEYS_POS
Definition: kb.h:49
redis_kb
#define redis_kb(__kb)
Definition: kb.c:62
nvti_set_required_udp_ports
int nvti_set_required_udp_ports(nvti_t *n, const gchar *required_udp_ports)
Set the required udp ports of a NVT.
Definition: nvti.c:1830
NVT_BIDS_POS
@ NVT_BIDS_POS
Definition: kb.h:55
redis_add_str_unique_volatile
static int redis_add_str_unique_volatile(kb_t kb, const char *name, const char *str, int expire, size_t len, int pos)
Insert (append) a new unique and volatile entry under a given name.
Definition: kb.c:1227
kb_item_get_str
static char * kb_item_get_str(kb_t kb, const char *name)
Get a single KB string item.
Definition: kb.h:334
redis_get_all
static struct kb_item * redis_get_all(kb_t kb, const char *name)
Get all items stored under a given name.
Definition: kb.c:1035
redis_cmd
static redisReply * redis_cmd(struct kb_redis *kbr, const char *fmt,...)
Execute a redis command and get a redis reply.
Definition: kb.c:761
nvti_set_required_keys
int nvti_set_required_keys(nvti_t *n, const gchar *required_keys)
Set the required keys of a NVT.
Definition: nvti.c:1734
nvti_family
gchar * nvti_family(const nvti_t *n)
Get the family name.
Definition: nvti.c:1196
NVT_NAME_POS
@ NVT_NAME_POS
Definition: kb.h:59
nvti_oid
gchar * nvti_oid(const nvti_t *n)
Get the OID string.
Definition: nvti.c:649
redis_push_str
static int redis_push_str(kb_t kb, const char *name, const char *value)
Push a new entry under a given key.
Definition: kb.c:871
redis_direct_conn
static kb_t redis_direct_conn(const char *kb_path, const int kb_index)
Connect to a Knowledge Base object with the given kb_index.
Definition: kb.c:513
redis_del_items
static int redis_del_items(kb_t kb, const char *name)
Delete all entries under a given name.
Definition: kb.c:1195
redis_get_str
static char * redis_get_str(kb_t kb, const char *name)
Get a single KB string item.
Definition: kb.c:844
kb_item::len
size_t len
Definition: kb.h:78
redis_get_oids
static GSList * redis_get_oids(kb_t kb)
Get all NVT OIDs.
Definition: kb.c:1128
redis_new
static int redis_new(kb_t *kb, const char *kb_path)
Initialize a new Knowledge Base object.
Definition: kb.c:466
redis_get_pattern
static struct kb_item * redis_get_pattern(kb_t kb, const char *pattern)
Get all items stored under a given pattern.
Definition: kb.c:1064
redis2kbitem_single
static struct kb_item * redis2kbitem_single(const char *name, const redisReply *elt, int force_int)
Give a single KB item.
Definition: kb.c:663
try_database_index
static int try_database_index(struct kb_redis *kbr, int index)
Attempt to atomically acquire ownership of a database.
Definition: kb.c:78
kb_redis::kb
struct kb kb
Definition: kb.c:56
NVT_FILENAME_POS
@ NVT_FILENAME_POS
Definition: kb.h:46
connect_redis
static redisContext * connect_redis(const char *addr, int len)
Definition: kb.c:263
nvtpref_id
int nvtpref_id(const nvtpref_t *np)
Get the ID of a NVT Preference.
Definition: nvti.c:541
redis_delete_all
static int redis_delete_all(struct kb_redis *)
Delete all the KB's content.
Definition: kb.c:1806
nvti_set_name
int nvti_set_name(nvti_t *n, const gchar *name)
Set the name of a NVT.
Definition: nvti.c:1272
redis_lnk_reset
static int redis_lnk_reset(kb_t)
Reset connection to the KB. This is called after each fork() to make sure connections aren't shared b...
Definition: kb.c:1672
kb_item
Knowledge base item (defined by name, type (int/char*) and value). Implemented as a singly linked lis...
Definition: kb.h:69
redis_add_str_unique
static int redis_add_str_unique(kb_t kb, const char *name, const char *str, size_t len, int pos)
Insert (append) a new unique entry under a given name.
Definition: kb.c:1320
nvti_refs
gchar * nvti_refs(const nvti_t *n, const gchar *type, const gchar *exclude_types, guint use_types)
Get references as string.
Definition: nvti.c:804
nvti_required_udp_ports
gchar * nvti_required_udp_ports(const nvti_t *n)
Get the required udp ports list.
Definition: nvti.c:1140
nvti
The structure of a information record that corresponds to a NVT.
Definition: nvti.c:394
nvti_required_ports
gchar * nvti_required_ports(const nvti_t *n)
Get the required ports list.
Definition: nvti.c:1126
NVT_REQUIRED_UDP_PORTS_POS
@ NVT_REQUIRED_UDP_PORTS_POS
Definition: kb.h:50
nvti_category
gint nvti_category(const nvti_t *n)
Get the category for this NVT.
Definition: nvti.c:1237
NVT_TIMESTAMP_POS
@ NVT_TIMESTAMP_POS
Definition: kb.h:60
nvti_set_excluded_keys
int nvti_set_excluded_keys(nvti_t *n, const gchar *excluded_keys)
Set the excluded keys of a NVT.
Definition: nvti.c:1782
redis_get_kb_index
static int redis_get_kb_index(kb_t kb)
Return the kb index.
Definition: kb.c:420
redis_memory_purge
static int redis_memory_purge(kb_t kb)
Attempt to purge dirty pages.
Definition: kb.c:442
kb_item::v_int
int v_int
Definition: kb.h:75
kb_redis::path
char * path
Definition: kb.c:60
kb_item::name
char name[]
Definition: kb.h:82
kb_item::v_str
char * v_str
Definition: kb.h:74
NVT_XREFS_POS
@ NVT_XREFS_POS
Definition: kb.h:56
kb_item_free
void kb_item_free(struct kb_item *item)
Release a KB item (or a list).
Definition: kb.c:639
redis_get_int
static int redis_get_int(kb_t kb, const char *name)
Get a single KB integer item.
Definition: kb.c:927
nvti_add_refs
int nvti_add_refs(nvti_t *n, const gchar *type, const gchar *ref_ids, const gchar *ref_text)
Add many new vtref from a comma-separated list.
Definition: nvti.c:2006
redis_add_str
static int redis_add_str(kb_t kb, const char *name, const char *str, size_t len)
Insert (append) a new entry under a given name.
Definition: kb.c:1378
memdup
#define memdup
Definition: kb.c:32
nvtpref
The structure for a preference of a NVT.
Definition: nvti.c:477
get_redis_ctx
static int get_redis_ctx(struct kb_redis *kbr)
Get redis context if it is already connected or do a a connection.
Definition: kb.c:312
redis_set_str
static int redis_set_str(kb_t kb, const char *name, const char *val, size_t len)
Set (replace) a new entry under a given name.
Definition: kb.c:1408
nvti_pref_len
guint nvti_pref_len(const nvti_t *n)
Get the number of preferences of the NVT.
Definition: nvti.c:1209
NVT_CATEGORY_POS
@ NVT_CATEGORY_POS
Definition: kb.h:57
redis_release_db
static int redis_release_db(struct kb_redis *kbr)
Release DB.
Definition: kb.c:216
kb_redis::max_db
unsigned int max_db
Definition: kb.c:57
NVT_DEPENDENCIES_POS
@ NVT_DEPENDENCIES_POS
Definition: kb.h:52
kb::kb_ops
const struct kb_operations * kb_ops
Definition: kb.h:92
nvti_set_dependencies
int nvti_set_dependencies(nvti_t *n, const gchar *dependencies)
Set the dependencies of a NVT.
Definition: nvti.c:1710
redis_add_nvt
static int redis_add_nvt(kb_t kb, const nvti_t *nvt, const char *filename)
Insert a new nvt.
Definition: kb.c:1604
KB_TYPE_STR
@ KB_TYPE_STR
Definition: kb.h:36
kb_item::next
struct kb_item * next
Definition: kb.h:79
kb_redis::db
unsigned int db
Definition: kb.c:58
kb_redis
Subclass of struct kb, it contains the redis-specific fields, such as the redis context,...
Definition: kb.c:55
redis_flush_all
static int redis_flush_all(kb_t, const char *)
Flush all the KB's content. Delete all namespaces.
Definition: kb.c:1696
NVT_FAMILY_POS
@ NVT_FAMILY_POS
Definition: kb.h:58
redis_delete
static int redis_delete(kb_t kb)
Delete all entries and release ownership on the namespace.
Definition: kb.c:392
nvti_tag
gchar * nvti_tag(const nvti_t *n)
Get the tags.
Definition: nvti.c:1004
nvti_set_tag
int nvti_set_tag(nvti_t *n, const gchar *tag)
Set the tags of a NVT.
Definition: nvti.c:1663
redis_get_nvt
static char * redis_get_nvt(kb_t kb, const char *oid, enum kb_nvt_pos position)
Get field of a NVT.
Definition: kb.c:953
redis_pop_str
static char * redis_pop_str(kb_t kb, const char *name)
Pops a single KB string item.
Definition: kb.c:900
kb
Top-level KB. This is to be inherited by KB implementations.
Definition: kb.h:91
nvtpref_name
gchar * nvtpref_name(const nvtpref_t *np)
Get the Name of a NVT Preference.
Definition: nvti.c:555
nvti_mandatory_keys
gchar * nvti_mandatory_keys(const nvti_t *n)
Get the mandatory keys list.
Definition: nvti.c:1098
redis_save
static int redis_save(kb_t kb)
Save all the elements from the KB.
Definition: kb.c:1774
parse_port_of_addr
static char * parse_port_of_addr(const char *addr, int tcp_indicator_len)
Definition: kb.c:250
nvti_dependencies
gchar * nvti_dependencies(const nvti_t *n)
Get the dependencies list.
Definition: nvti.c:1070
redis2kbitem
static struct kb_item * redis2kbitem(const char *name, const redisReply *rep)
Fetch a KB item or list from a redis Reply.
Definition: kb.c:708
NVT_CVES_POS
@ NVT_CVES_POS
Definition: kb.h:54
NVT_MANDATORY_KEYS_POS
@ NVT_MANDATORY_KEYS_POS
Definition: kb.h:48
nvti_name
gchar * nvti_name(const nvti_t *n)
Get the name.
Definition: nvti.c:663
redis_count
static size_t redis_count(kb_t kb, const char *pattern)
Count all items stored under a given pattern.
Definition: kb.c:1163
select_database
static int select_database(struct kb_redis *kbr)
Select DB.
Definition: kb.c:164
KBRedisOperations
static const struct kb_operations KBRedisOperations
Default KB operations.
Definition: kb.c:47
kb_redis::rctx
redisContext * rctx
Definition: kb.c:59
redis_get_single
static struct kb_item * redis_get_single(kb_t kb, const char *name, enum kb_item_type type)
Get a single KB element.
Definition: kb.c:809
nvti_excluded_keys
gchar * nvti_excluded_keys(const nvti_t *n)
Get the excluded keys list.
Definition: nvti.c:1112
redis_find
static kb_t redis_find(const char *kb_path, const char *key)
Find an existing Knowledge Base object with key.
Definition: kb.c:561
redis_add_int_unique
static int redis_add_int_unique(kb_t kb, const char *name, int val)
Insert (append) a new unique entry under a given name.
Definition: kb.c:1502
nvti_set_required_ports
int nvti_set_required_ports(nvti_t *n, const gchar *required_ports)
Set the required ports of a NVT.
Definition: nvti.c:1806
kb_item::namelen
size_t namelen
Definition: kb.h:81
NVT_REQUIRED_KEYS_POS
@ NVT_REQUIRED_KEYS_POS
Definition: kb.h:47
nvtpref_default
gchar * nvtpref_default(const nvtpref_t *np)
Get the Default of a NVT Preference.
Definition: nvti.c:583
GLOBAL_DBINDEX_NAME
#define GLOBAL_DBINDEX_NAME
Name of the namespace usage bitmap in redis.
Definition: kb.c:45
nvti_new
nvti_t * nvti_new(void)
Create a new (empty) nvti structure.
Definition: nvti.c:597
NVT_TAGS_POS
@ NVT_TAGS_POS
Definition: kb.h:53
nvtpref_type
gchar * nvtpref_type(const nvtpref_t *np)
Get the Type of a NVT Preference.
Definition: nvti.c:569
KB_TYPE_INT
@ KB_TYPE_INT
Definition: kb.h:35
nvti_set_family
int nvti_set_family(nvti_t *n, const gchar *family)
Set the family of a NVT.
Definition: nvti.c:1941
kb_t
struct kb * kb_t
type abstraction to hide KB internals.
Definition: kb.h:98
nvti_set_category
int nvti_set_category(nvti_t *n, const gint category)
Set the category type of a NVT Info.
Definition: nvti.c:1981
G_LOG_DOMAIN
#define G_LOG_DOMAIN
GLib logging domain.
Definition: kb.c:27
NVT_REQUIRED_PORTS_POS
@ NVT_REQUIRED_PORTS_POS
Definition: kb.h:51
redis_get_nvt_all
static nvti_t * redis_get_nvt_all(kb_t kb, const char *oid)
Get a full NVT.
Definition: kb.c:985
nvti_set_oid
int nvti_set_oid(nvti_t *n, const gchar *oid)
Set the OID of a NVT Info.
Definition: nvti.c:1252
redis_test_connection
static int redis_test_connection(struct kb_redis *kbr)
Test redis connection.
Definition: kb.c:351
fetch_max_db_index
static int fetch_max_db_index(struct kb_redis *kbr)
Set the number of databases have been configured into kbr struct.
Definition: kb.c:109
nvti_set_mandatory_keys
int nvti_set_mandatory_keys(nvti_t *n, const gchar *mandatory_keys)
Set the mandatory keys of a NVT.
Definition: nvti.c:1758
redis_add_int
static int redis_add_int(kb_t kb, const char *name, int val)
Insert (append) a new entry under a given name.
Definition: kb.c:1543
redis_add_int_unique_volatile
static int redis_add_int_unique_volatile(kb_t kb, const char *name, int val, int expire)
Insert (append) a new unique entry under a given name.
Definition: kb.c:1449
kb_item::type
enum kb_item_type type
Definition: kb.h:70
redis_set_int
static int redis_set_int(kb_t kb, const char *name, int val)
Set (replace) a new entry under a given name.
Definition: kb.c:1567
nvti_required_keys
gchar * nvti_required_keys(const nvti_t *n)
Get the required keys list.
Definition: nvti.c:1084