Greenbone Vulnerability Management Libraries 22.32.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:
This graph shows which files directly or indirectly include this file:

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.
#define memdup   g_memdup
#define GLOBAL_DBINDEX_NAME   "GVM.__GlobalDBIndex"
 Name of the namespace usage bitmap in redis.
#define redis_kb(__kb)

Functions

static int redis_delete_all (struct kb_redis *kbr)
 Delete all the KB's content.
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.
static int redis_flush_all (kb_t kb, const char *except)
 Flush all the KB's content. Delete all namespaces.
static redisReply * redis_cmd (struct kb_redis *kbr, const char *fmt,...)
 Execute a redis command and get a redis reply.
static int try_database_index (struct kb_redis *kbr, int index)
 Attempt to atomically acquire ownership of a database.
static int fetch_max_db_index (struct kb_redis *kbr)
 Set the number of databases have been configured into kbr struct.
static int select_database (struct kb_redis *kbr)
 Select DB.
static int redis_release_db (struct kb_redis *kbr)
 Release DB.
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.
static int redis_test_connection (struct kb_redis *kbr)
 Test redis connection.
static int redis_delete (kb_t kb)
 Delete all entries and release ownership on the namespace.
static int redis_get_kb_index (kb_t kb)
 Return the kb index.
static int redis_memory_purge (kb_t kb)
 Attempt to purge dirty pages.
static int redis_new (kb_t *kb, const char *kb_path)
 Initialize a new Knowledge Base object.
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.
static kb_t redis_find (const char *kb_path, const char *key)
 Find an existing Knowledge Base object with key.
void kb_item_free (struct kb_item *item)
 Release a KB item (or a list).
static struct kb_itemredis2kbitem_single (const char *name, const redisReply *elt, int force_int)
 Give a single KB item.
static struct kb_itemredis2kbitem (const char *name, const redisReply *rep)
 Fetch a KB item or list from a redis Reply.
static struct kb_itemredis_get_single (kb_t kb, const char *name, enum kb_item_type type)
 Get a single KB element.
static char * redis_get_str (kb_t kb, const char *name)
 Get a single KB string item.
static int redis_push_str (kb_t kb, const char *name, const char *value)
 Push a new entry under a given key.
static char * redis_pop_str (kb_t kb, const char *name)
 Pops a single KB string item.
static int redis_get_int (kb_t kb, const char *name)
 Get a single KB integer item.
static char * redis_get_nvt (kb_t kb, const char *oid, enum kb_nvt_pos position)
 Get field of a NVT.
static nvti_tredis_get_nvt_all (kb_t kb, const char *oid)
 Get a full NVT.
static struct kb_itemredis_get_all (kb_t kb, const char *name)
 Get all items stored under a given name.
static struct kb_itemredis_get_pattern (kb_t kb, const char *pattern)
 Get all items stored under a given pattern.
static GSList * redis_get_oids (kb_t kb)
 Get all NVT OIDs.
static size_t redis_count (kb_t kb, const char *pattern)
 Count all items stored under a given pattern.
static int redis_del_items (kb_t kb, const char *name)
 Delete all entries under a given name.
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.
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.
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.
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.
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.
static int redis_add_int_unique (kb_t kb, const char *name, int val)
 Insert (append) a new unique entry under a given name.
static int redis_add_int (kb_t kb, const char *name, int val)
 Insert (append) a new entry under a given name.
static int redis_set_int (kb_t kb, const char *name, int val)
 Set (replace) a new entry under a given name.
static int redis_add_nvt (kb_t kb, const nvti_t *nvt, const char *filename)
 Insert a new nvt.
static int redis_save (kb_t kb)
 Save all the elements from the KB.

Variables

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

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.

Referenced by redis_find(), redis_flush_all(), redis_release_db(), and try_database_index().

◆ memdup

#define memdup   g_memdup

Definition at line 32 of file kb.c.

Referenced by redis2kbitem_single().

◆ redis_kb

Function Documentation

◆ connect_redis()

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

Definition at line 264 of file kb.c.

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

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()

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
146err_cleanup:
147 if (rep != NULL)
148 freeReplyObject (rep);
149
150 return rc;
151}
#define G_LOG_DOMAIN
GLib log domain.
Definition array.c:17
unsigned int max_db
Definition kb.c:57
redisContext * rctx
Definition kb.c:59

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()

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 314 of file kb.c.

315{
316 int rc;
317
318 if (kbr->rctx != NULL)
319 return 0;
320
321 kbr->rctx = connect_redis (kbr->path, strlen (kbr->path));
322 if (kbr->rctx == NULL || kbr->rctx->err)
323 {
324 g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
325 "%s: redis connection error to %s: %s", __func__, kbr->path,
326 kbr->rctx ? kbr->rctx->errstr : strerror (ENOMEM));
327 redisFree (kbr->rctx);
328 kbr->rctx = NULL;
329 return -1;
330 }
331
332 rc = select_database (kbr);
333 if (rc)
334 {
335 g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, "No redis DB available");
336 redisFree (kbr->rctx);
337 kbr->rctx = NULL;
338 return -2;
339 }
340
341 g_debug ("%s: connected to redis://%s/%d", __func__, kbr->path, kbr->db);
342 return 0;
343}
static int select_database(struct kb_redis *kbr)
Select DB.
Definition kb.c:164
static redisContext * connect_redis(const char *addr, int len)
Definition kb.c:264
char * path
Definition kb.c:60
unsigned int db
Definition kb.c:58

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 642 of file kb.c.

643{
644 while (item != NULL)
645 {
646 struct kb_item *next;
647
648 next = item->next;
649 if (item->type == KB_TYPE_STR && item->v_str != NULL)
650 g_free (item->v_str);
651 g_free (item);
652 item = next;
653 }
654}
@ KB_TYPE_STR
Definition kb.h:36
Knowledge base item (defined by name, type (int/char*) and value). Implemented as a singly linked lis...
Definition kb.h:69
enum kb_item_type type
Definition kb.h:70
char * v_str
Definition kb.h:74
struct kb_item * next
Definition kb.h:79

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()

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 tmp = strrchr (addr + tcp_indicator_len, ':');
255 if (tmp == NULL)
256 return NULL;
257 is_ip_v6 = addr[tcp_indicator_len] == '[';
258 if (is_ip_v6 && (tmp - 1)[0] != ']')
259 return NULL;
260 return tmp + 1;
261}

Referenced by connect_redis(), Ensure(), Ensure(), Ensure(), and main().

Here is the caller graph for this function:

◆ redis2kbitem()

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 711 of file kb.c.

712{
713 struct kb_item *kbi;
714
715 kbi = NULL;
716
717 switch (rep->type)
718 {
719 unsigned int i;
720
721 case REDIS_REPLY_STRING:
722 case REDIS_REPLY_INTEGER:
723 kbi = redis2kbitem_single (name, rep, 0);
724 break;
725
726 case REDIS_REPLY_ARRAY:
727 for (i = 0; i < rep->elements; i++)
728 {
729 struct kb_item *tmpitem;
730
731 tmpitem = redis2kbitem_single (name, rep->element[i], 0);
732 if (tmpitem == NULL)
733 break;
734
735 if (kbi != NULL)
736 {
737 tmpitem->next = kbi;
738 kbi = tmpitem;
739 }
740 else
741 kbi = tmpitem;
742 }
743 break;
744
745 case REDIS_REPLY_NIL:
746 case REDIS_REPLY_STATUS:
747 case REDIS_REPLY_ERROR:
748 default:
749 break;
750 }
751
752 return kbi;
753}
static struct kb_item * redis2kbitem_single(const char *name, const redisReply *elt, int force_int)
Give a single KB item.
Definition kb.c:666
char name[]
Definition kb.h:82

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()

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 666 of file kb.c.

667{
668 struct kb_item *item;
669 size_t namelen;
670
671 if (elt->type != REDIS_REPLY_STRING && elt->type != REDIS_REPLY_INTEGER)
672 return NULL;
673
674 namelen = strlen (name) + 1;
675
676 item = g_malloc0 (sizeof (struct kb_item) + namelen);
677 if (elt->type == REDIS_REPLY_INTEGER)
678 {
679 item->type = KB_TYPE_INT;
680 item->v_int = elt->integer;
681 }
682 else if (force_int)
683 {
684 item->type = KB_TYPE_INT;
685 item->v_int = atoi (elt->str);
686 }
687 else
688 {
689 item->type = KB_TYPE_STR;
690 item->v_str = memdup (elt->str, elt->len + 1);
691 item->len = elt->len;
692 }
693
694 item->next = NULL;
695 item->namelen = namelen;
696 memset (item->name, 0, namelen);
697 memcpy (item->name, name, namelen);
698
699 return item;
700}
#define memdup
Definition kb.c:32
@ KB_TYPE_INT
Definition kb.h:35
int v_int
Definition kb.h:75
size_t len
Definition kb.h:78
size_t namelen
Definition kb.h:81

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()

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 1546 of file kb.c.

1547{
1548 redisReply *rep;
1549 int rc = 0;
1550
1551 rep = redis_cmd (redis_kb (kb), "RPUSH %s %d", name, val);
1552 if (!rep || rep->type == REDIS_REPLY_ERROR)
1553 rc = -1;
1554 if (rep)
1555 freeReplyObject (rep);
1556
1557 return rc;
1558}
#define redis_kb(__kb)
Definition kb.c:62
static redisReply * redis_cmd(struct kb_redis *kbr, const char *fmt,...)
Execute a redis command and get a redis reply.
Definition kb.c:764
Top-level KB. This is to be inherited by KB implementations.
Definition kb.h:91

References redis_cmd(), and redis_kb.

Here is the call graph for this function:

◆ redis_add_int_unique()

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 1505 of file kb.c.

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

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

Here is the call graph for this function:

◆ redis_add_int_unique_volatile()

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 1452 of file kb.c.

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

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

Here is the call graph for this function:

◆ redis_add_nvt()

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 1607 of file kb.c.

1608{
1609 struct kb_redis *kbr;
1610 redisReply *rep = NULL;
1611 int rc = 0;
1612 unsigned int i;
1613 gchar *cves, *bids, *xrefs;
1614
1615 if (!nvt || !filename)
1616 return -1;
1617
1618 cves = nvti_refs (nvt, "cve", "", 0);
1619 bids = nvti_refs (nvt, "bid", "", 0);
1620 xrefs = nvti_refs (nvt, NULL, "cve,bid", 1);
1621
1622 kbr = redis_kb (kb);
1623 rep = redis_cmd (
1624 kbr, "RPUSH nvt:%s %s %s %s %s %s %s %s %s %s %s %s %d %s %s",
1625 nvti_oid (nvt), filename,
1626 nvti_required_keys (nvt) ? nvti_required_keys (nvt) : "",
1627 nvti_mandatory_keys (nvt) ? nvti_mandatory_keys (nvt) : "",
1628 nvti_excluded_keys (nvt) ? nvti_excluded_keys (nvt) : "",
1630 nvti_required_ports (nvt) ? nvti_required_ports (nvt) : "",
1631 nvti_dependencies (nvt) ? nvti_dependencies (nvt) : "",
1632 nvti_tag (nvt) ? nvti_tag (nvt) : "", cves ? cves : "", bids ? bids : "",
1633 xrefs ? xrefs : "", nvti_category (nvt), nvti_family (nvt),
1634 nvti_name (nvt));
1635 g_free (cves);
1636 g_free (bids);
1637 g_free (xrefs);
1638 if (rep == NULL || rep->type == REDIS_REPLY_ERROR)
1639 rc = -1;
1640 if (rep != NULL)
1641 freeReplyObject (rep);
1642
1643 if (nvti_pref_len (nvt))
1644 redis_cmd (kbr, "DEL oid:%s:prefs", nvti_oid (nvt));
1645 for (i = 0; i < nvti_pref_len (nvt); i++)
1646 {
1647 const nvtpref_t *pref = nvti_pref (nvt, i);
1648
1649 rep = redis_cmd (kbr, "RPUSH oid:%s:prefs %d|||%s|||%s|||%s",
1650 nvti_oid (nvt), nvtpref_id (pref), nvtpref_name (pref),
1651 nvtpref_type (pref), nvtpref_default (pref));
1652 if (!rep || rep->type == REDIS_REPLY_ERROR)
1653 rc = -1;
1654 if (rep)
1655 freeReplyObject (rep);
1656 }
1657 rep = redis_cmd (kbr, "RPUSH filename:%s %lu %s", filename, time (NULL),
1658 nvti_oid (nvt));
1659 if (!rep || rep->type == REDIS_REPLY_ERROR)
1660 rc = -1;
1661 if (rep)
1662 freeReplyObject (rep);
1663 return rc;
1664}
gchar * nvti_dependencies(const nvti_t *n)
Get the dependencies list.
Definition nvti.c:1032
guint nvti_pref_len(const nvti_t *n)
Get the number of preferences of the NVT.
Definition nvti.c:1171
gchar * nvti_required_udp_ports(const nvti_t *n)
Get the required udp ports list.
Definition nvti.c:1102
gchar * nvti_required_ports(const nvti_t *n)
Get the required ports list.
Definition nvti.c:1088
gchar * nvti_refs(const nvti_t *n, const gchar *type, const gchar *exclude_types, guint use_types)
Get references as string.
Definition nvti.c:766
gchar * nvtpref_type(const nvtpref_t *np)
Get the Type of a NVT Preference.
Definition nvti.c:532
gint nvti_category(const nvti_t *n)
Get the category for this NVT.
Definition nvti.c:1199
struct nvtpref nvtpref_t
The structure for a preference of a NVT.
gchar * nvti_family(const nvti_t *n)
Get the family name.
Definition nvti.c:1158
const nvtpref_t * nvti_pref(const nvti_t *n, guint p)
Get the n'th preferences of the NVT.
Definition nvti.c:1186
gchar * nvti_excluded_keys(const nvti_t *n)
Get the excluded keys list.
Definition nvti.c:1074
gchar * nvti_name(const nvti_t *n)
Get the name.
Definition nvti.c:625
gchar * nvti_oid(const nvti_t *n)
Get the OID string.
Definition nvti.c:611
int nvtpref_id(const nvtpref_t *np)
Get the ID of a NVT Preference.
Definition nvti.c:504
gchar * nvti_required_keys(const nvti_t *n)
Get the required keys list.
Definition nvti.c:1046
gchar * nvti_mandatory_keys(const nvti_t *n)
Get the mandatory keys list.
Definition nvti.c:1060
gchar * nvtpref_default(const nvtpref_t *np)
Get the Default of a NVT Preference.
Definition nvti.c:546
gchar * nvtpref_name(const nvtpref_t *np)
Get the Name of a NVT Preference.
Definition nvti.c:518
gchar * nvti_tag(const nvti_t *n)
Get the tags.
Definition nvti.c:966

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()

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 1381 of file kb.c.

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

References redis_cmd(), and redis_kb.

Here is the call graph for this function:

◆ redis_add_str_unique()

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 1323 of file kb.c.

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

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

Here is the call graph for this function:

◆ redis_add_str_unique_volatile()

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 1230 of file kb.c.

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

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

Here is the call graph for this function:

◆ redis_cmd()

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 764 of file kb.c.

765{
766 redisReply *rep;
767 va_list ap, aq;
768 int retry = 0;
769
770 va_start (ap, fmt);
771 do
772 {
773 if (get_redis_ctx (kbr) < 0)
774 {
775 va_end (ap);
776 return NULL;
777 }
778
779 va_copy (aq, ap);
780 rep = redisvCommand (kbr->rctx, fmt, aq);
781 va_end (aq);
782
783 if (kbr->rctx->err)
784 {
785 if (rep != NULL)
786 freeReplyObject (rep);
787
788 redis_lnk_reset ((kb_t) kbr);
789 retry = !retry;
790 }
791 else
792 retry = 0;
793 }
794 while (retry);
795
796 va_end (ap);
797
798 return rep;
799}
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:1675
struct kb * kb_t
type abstraction to hide KB internals.
Definition kb.h:98

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()

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 1166 of file kb.c.

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

References redis_cmd(), and redis_kb.

Here is the call graph for this function:

◆ redis_del_items()

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 1198 of file kb.c.

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

References redis_cmd(), and redis_kb.

Here is the call graph for this function:

◆ redis_delete()

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 394 of file kb.c.

395{
396 struct kb_redis *kbr;
397
398 kbr = redis_kb (kb);
399
400 redis_delete_all (kbr);
401 redis_release_db (kbr);
402
403 if (kbr->rctx != NULL)
404 {
405 g_free (kbr->path);
406 redisFree (kbr->rctx);
407 kbr->rctx = NULL;
408 }
409
410 g_free (kb);
411 return 0;
412}
static int redis_delete_all(struct kb_redis *)
Delete all the KB's content.
Definition kb.c:1809
static int redis_release_db(struct kb_redis *kbr)
Release DB.
Definition kb.c:216

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 1809 of file kb.c.

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

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()

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 516 of file kb.c.

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

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()

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 564 of file kb.c.

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

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()

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 1699 of file kb.c.

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

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()

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 1038 of file kb.c.

1039{
1040 struct kb_redis *kbr;
1041 struct kb_item *kbi;
1042 redisReply *rep;
1043
1044 kbr = redis_kb (kb);
1045
1046 rep = redis_cmd (kbr, "LRANGE %s 0 -1", name);
1047 if (rep == NULL)
1048 return NULL;
1049
1050 kbi = redis2kbitem (name, rep);
1051
1052 freeReplyObject (rep);
1053
1054 return kbi;
1055}
static struct kb_item * redis2kbitem(const char *name, const redisReply *rep)
Fetch a KB item or list from a redis Reply.
Definition kb.c:711

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

Here is the call graph for this function:

◆ redis_get_int()

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 930 of file kb.c.

931{
932 struct kb_item *kbi;
933
935 if (kbi != NULL)
936 {
937 int res;
938
939 res = kbi->v_int;
940 kb_item_free (kbi);
941 return res;
942 }
943 return -1;
944}
void kb_item_free(struct kb_item *item)
Release a KB item (or a list).
Definition kb.c:642
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:812

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()

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 422 of file kb.c.

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

References kb_redis::db.

◆ redis_get_nvt()

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 956 of file kb.c.

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

References NVT_TIMESTAMP_POS, redis_cmd(), and redis_kb.

Here is the call graph for this function:

◆ redis_get_nvt_all()

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 988 of file kb.c.

989{
990 struct kb_redis *kbr;
991 redisReply *rep;
992
993 kbr = redis_kb (kb);
994 rep =
995 redis_cmd (kbr, "LRANGE nvt:%s %d %d", oid, NVT_FILENAME_POS, NVT_NAME_POS);
996 if (!rep)
997 return NULL;
998 if (rep->type != REDIS_REPLY_ARRAY || rep->elements != NVT_NAME_POS + 1)
999 {
1000 freeReplyObject (rep);
1001 return NULL;
1002 }
1003 else
1004 {
1005 nvti_t *nvti = nvti_new ();
1006
1007 nvti_set_oid (nvti, oid);
1012 nvti, rep->element[NVT_REQUIRED_UDP_PORTS_POS]->str);
1014 nvti_set_dependencies (nvti, rep->element[NVT_DEPENDENCIES_POS]->str);
1015 nvti_set_tag (nvti, rep->element[NVT_TAGS_POS]->str);
1016 nvti_add_refs (nvti, "cve", rep->element[NVT_CVES_POS]->str, "");
1017 nvti_add_refs (nvti, "bid", rep->element[NVT_BIDS_POS]->str, "");
1018 nvti_add_refs (nvti, NULL, rep->element[NVT_XREFS_POS]->str, "");
1019 nvti_set_category (nvti, atoi (rep->element[NVT_CATEGORY_POS]->str));
1020 nvti_set_family (nvti, rep->element[NVT_FAMILY_POS]->str);
1021 nvti_set_name (nvti, rep->element[NVT_NAME_POS]->str);
1022
1023 freeReplyObject (rep);
1024 return nvti;
1025 }
1026}
@ NVT_FAMILY_POS
Definition kb.h:58
@ NVT_CATEGORY_POS
Definition kb.h:57
@ NVT_NAME_POS
Definition kb.h:59
@ NVT_TAGS_POS
Definition kb.h:53
@ NVT_BIDS_POS
Definition kb.h:55
@ NVT_EXCLUDED_KEYS_POS
Definition kb.h:49
@ NVT_REQUIRED_PORTS_POS
Definition kb.h:51
@ NVT_REQUIRED_UDP_PORTS_POS
Definition kb.h:50
@ NVT_FILENAME_POS
Definition kb.h:46
@ NVT_DEPENDENCIES_POS
Definition kb.h:52
@ NVT_CVES_POS
Definition kb.h:54
@ NVT_REQUIRED_KEYS_POS
Definition kb.h:47
@ NVT_XREFS_POS
Definition kb.h:56
@ NVT_MANDATORY_KEYS_POS
Definition kb.h:48
nvti_t * nvti_new(void)
Create a new (empty) nvti structure.
Definition nvti.c:559
int nvti_set_excluded_keys(nvti_t *n, const gchar *excluded_keys)
Set the excluded keys of a NVT.
Definition nvti.c:1744
struct nvti nvti_t
The structure of a information record that corresponds to a NVT.
int nvti_set_dependencies(nvti_t *n, const gchar *dependencies)
Set the dependencies of a NVT.
Definition nvti.c:1672
int nvti_set_required_ports(nvti_t *n, const gchar *required_ports)
Set the required ports of a NVT.
Definition nvti.c:1768
int nvti_set_oid(nvti_t *n, const gchar *oid)
Set the OID of a NVT Info.
Definition nvti.c:1214
int nvti_set_tag(nvti_t *n, const gchar *tag)
Set the tags of a NVT.
Definition nvti.c:1625
int nvti_set_mandatory_keys(nvti_t *n, const gchar *mandatory_keys)
Set the mandatory keys of a NVT.
Definition nvti.c:1720
int nvti_set_required_keys(nvti_t *n, const gchar *required_keys)
Set the required keys of a NVT.
Definition nvti.c:1696
int nvti_set_name(nvti_t *n, const gchar *name)
Set the name of a NVT.
Definition nvti.c:1234
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:1968
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:1792
int nvti_set_family(nvti_t *n, const gchar *family)
Set the family of a NVT.
Definition nvti.c:1903
int nvti_set_category(nvti_t *n, const gint category)
Set the category type of a NVT Info.
Definition nvti.c:1943
The structure of a information record that corresponds to a NVT.
Definition nvti.c:358

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()

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 1131 of file kb.c.

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

References redis_cmd(), and redis_kb.

Here is the call graph for this function:

◆ redis_get_pattern()

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 1067 of file kb.c.

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

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()

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 812 of file kb.c.

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

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()

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 847 of file kb.c.

848{
849 struct kb_item *kbi;
850
852 if (kbi != NULL)
853 {
854 char *res;
855
856 res = kbi->v_str;
857 kbi->v_str = NULL;
858 kb_item_free (kbi);
859 return res;
860 }
861 return NULL;
862}

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()

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 1675 of file kb.c.

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

References kb_redis::rctx, and redis_kb.

Referenced by redis_cmd().

Here is the caller graph for this function:

◆ redis_memory_purge()

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 444 of file kb.c.

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

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()

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 468 of file kb.c.

469{
470 struct kb_redis *kbr;
471 int rc = 0;
472
473 if (kb_path == NULL)
474 return -3;
475
476 kbr = g_malloc0 (sizeof (struct kb_redis));
478 kbr->path = g_strdup (kb_path);
479
480 rc = get_redis_ctx (kbr);
481 if (rc < 0)
482 {
483 redis_delete ((kb_t) kbr);
484 return rc;
485 }
486 if (redis_test_connection (kbr))
487 {
488 g_log (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
489 "%s: cannot access redis at '%s'", __func__, kb_path);
490 redis_delete ((kb_t) kbr);
491 kbr = NULL;
492 rc = -1;
493 }
494
495 /* Ensure that the new kb is clean */
496 redis_delete_all (kbr);
497
498 *kb = (kb_t) kbr;
499
500 /* Try to make unused memory available for the OS again. */
501 if (redis_memory_purge (*kb))
502 g_warning ("%s: Memory purge was not successful", __func__);
503
504 return rc;
505}
static int redis_memory_purge(kb_t kb)
Attempt to purge dirty pages.
Definition kb.c:444
static int redis_test_connection(struct kb_redis *kbr)
Test redis connection.
Definition kb.c:353
static int redis_delete(kb_t kb)
Delete all entries and release ownership on the namespace.
Definition kb.c:394

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()

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 903 of file kb.c.

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

References redis_cmd(), and redis_kb.

Here is the call graph for this function:

◆ redis_push_str()

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 874 of file kb.c.

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

References redis_cmd(), and redis_kb.

Here is the call graph for this function:

◆ redis_release_db()

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
242err_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()

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 1777 of file kb.c.

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

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

Here is the call graph for this function:

◆ redis_set_int()

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 1570 of file kb.c.

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

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

Here is the call graph for this function:

◆ redis_set_str()

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 1411 of file kb.c.

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

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

Here is the call graph for this function:

◆ redis_test_connection()

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 353 of file kb.c.

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

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()

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
201err_cleanup:
202 if (rep != NULL)
203 freeReplyObject (rep);
204
205 return rc;
206}
static int try_database_index(struct kb_redis *kbr, int index)
Attempt to atomically acquire ownership of a database.
Definition kb.c:78

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()

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 1880 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

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}
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:874
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:1411
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:1230
static char * redis_get_nvt(kb_t kb, const char *oid, enum kb_nvt_pos position)
Get field of a NVT.
Definition kb.c:956
static kb_t redis_find(const char *kb_path, const char *key)
Find an existing Knowledge Base object with key.
Definition kb.c:564
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:1381
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:1452
static struct kb_item * redis_get_all(kb_t kb, const char *name)
Get all items stored under a given name.
Definition kb.c:1038
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:1546
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:516
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:1323
static char * redis_get_str(kb_t kb, const char *name)
Get a single KB string item.
Definition kb.c:847
static struct kb_item * redis_get_pattern(kb_t kb, const char *pattern)
Get all items stored under a given pattern.
Definition kb.c:1067
static GSList * redis_get_oids(kb_t kb)
Get all NVT OIDs.
Definition kb.c:1131
static int redis_save(kb_t kb)
Save all the elements from the KB.
Definition kb.c:1777
static int redis_get_int(kb_t kb, const char *name)
Get a single KB integer item.
Definition kb.c:930
static char * redis_pop_str(kb_t kb, const char *name)
Pops a single KB string item.
Definition kb.c:903
static int redis_new(kb_t *kb, const char *kb_path)
Initialize a new Knowledge Base object.
Definition kb.c:468
static int redis_get_kb_index(kb_t kb)
Return the kb index.
Definition kb.c:422
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:1505
static int redis_flush_all(kb_t, const char *)
Flush all the KB's content. Delete all namespaces.
Definition kb.c:1699
static size_t redis_count(kb_t kb, const char *pattern)
Count all items stored under a given pattern.
Definition kb.c:1166
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:1570
static int redis_add_nvt(kb_t kb, const nvti_t *nvt, const char *filename)
Insert a new nvt.
Definition kb.c:1607
static nvti_t * redis_get_nvt_all(kb_t kb, const char *oid)
Get a full NVT.
Definition kb.c:988
static int redis_del_items(kb_t kb, const char *name)
Delete all entries under a given name.
Definition kb.c:1198

Default KB operations.

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

Definition at line 47 of file kb.c.

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