Greenbone Vulnerability Management Libraries 22.35.9
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 const 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 const char *tmp;
272 char *host;
273 redisContext *result;
274 static int warn_flag = 0;
275
276 if (len < tcp_indicator_len + 1)
277 goto unix_connect;
278 if (memcmp (addr, tcp_indicator, tcp_indicator_len) != 0)
279 goto unix_connect;
280 host_len = len - tcp_indicator_len;
281 tmp = parse_port_of_addr (addr, tcp_indicator_len);
282 if (tmp == NULL)
283 port = redis_default_port;
284 else
285 {
286 port = atoi (tmp);
287 host_len -= strlen (tmp) + 1;
288 }
289 host = calloc (1, host_len);
290 memmove (host, addr + tcp_indicator_len, host_len);
291 result = redisConnect (host, port);
292 if (warn_flag == 0)
293 {
294 g_warning ("A Redis TCP connection is being used. This feature is "
295 "experimental and insecure, since it is not an encrypted "
296 "channel. We discourage its usage in production environments");
297 warn_flag = 1;
298 }
299 free (host);
300 return result;
301unix_connect:
302 return redisConnectUnix (addr);
303}
static const 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 315 of file kb.c.

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

644{
645 while (item != NULL)
646 {
647 struct kb_item *next;
648
649 next = item->next;
650 if (item->type == KB_TYPE_STR && item->v_str != NULL)
651 g_free (item->v_str);
652 g_free (item);
653 item = next;
654 }
655}
@ 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()

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

Definition at line 250 of file kb.c.

251{
252 const 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 712 of file kb.c.

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

668{
669 struct kb_item *item;
670 size_t namelen;
671
672 if (elt->type != REDIS_REPLY_STRING && elt->type != REDIS_REPLY_INTEGER)
673 return NULL;
674
675 namelen = strlen (name) + 1;
676
677 item = g_malloc0 (sizeof (struct kb_item) + namelen);
678 if (elt->type == REDIS_REPLY_INTEGER)
679 {
680 item->type = KB_TYPE_INT;
681 item->v_int = elt->integer;
682 }
683 else if (force_int)
684 {
685 item->type = KB_TYPE_INT;
686 item->v_int = atoi (elt->str);
687 }
688 else
689 {
690 item->type = KB_TYPE_STR;
691 item->v_str = memdup (elt->str, elt->len + 1);
692 item->len = elt->len;
693 }
694
695 item->next = NULL;
696 item->namelen = namelen;
697 memset (item->name, 0, namelen);
698 memcpy (item->name, name, namelen);
699
700 return item;
701}
#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 1547 of file kb.c.

1548{
1549 redisReply *rep;
1550 int rc = 0;
1551
1552 rep = redis_cmd (redis_kb (kb), "RPUSH %s %d", name, val);
1553 if (!rep || rep->type == REDIS_REPLY_ERROR)
1554 rc = -1;
1555 if (rep)
1556 freeReplyObject (rep);
1557
1558 return rc;
1559}
#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:765
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 1506 of file kb.c.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

396{
397 struct kb_redis *kbr;
398
399 kbr = redis_kb (kb);
400
401 redis_delete_all (kbr);
402 redis_release_db (kbr);
403
404 if (kbr->rctx != NULL)
405 {
406 g_free (kbr->path);
407 redisFree (kbr->rctx);
408 kbr->rctx = NULL;
409 }
410
411 g_free (kb);
412 return 0;
413}
static int redis_delete_all(struct kb_redis *)
Delete all the KB's content.
Definition kb.c:1810
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 1810 of file kb.c.

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

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

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

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

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

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

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

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

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

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

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

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

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

990{
991 struct kb_redis *kbr;
992 redisReply *rep;
993
994 kbr = redis_kb (kb);
995 rep =
996 redis_cmd (kbr, "LRANGE nvt:%s %d %d", oid, NVT_FILENAME_POS, NVT_NAME_POS);
997 if (!rep)
998 return NULL;
999 if (rep->type != REDIS_REPLY_ARRAY || rep->elements != NVT_NAME_POS + 1)
1000 {
1001 freeReplyObject (rep);
1002 return NULL;
1003 }
1004 else
1005 {
1006 nvti_t *nvti = nvti_new ();
1007
1008 nvti_set_oid (nvti, oid);
1013 nvti, rep->element[NVT_REQUIRED_UDP_PORTS_POS]->str);
1015 nvti_set_dependencies (nvti, rep->element[NVT_DEPENDENCIES_POS]->str);
1016 nvti_set_tag (nvti, rep->element[NVT_TAGS_POS]->str);
1017 nvti_add_refs (nvti, "cve", rep->element[NVT_CVES_POS]->str, "");
1018 nvti_add_refs (nvti, "bid", rep->element[NVT_BIDS_POS]->str, "");
1019 nvti_add_refs (nvti, NULL, rep->element[NVT_XREFS_POS]->str, "");
1020 nvti_set_category (nvti, atoi (rep->element[NVT_CATEGORY_POS]->str));
1021 nvti_set_family (nvti, rep->element[NVT_FAMILY_POS]->str);
1022 nvti_set_name (nvti, rep->element[NVT_NAME_POS]->str);
1023
1024 freeReplyObject (rep);
1025 return nvti;
1026 }
1027}
@ 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 1132 of file kb.c.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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 1881 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:875
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:1412
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:1231
static char * redis_get_nvt(kb_t kb, const char *oid, enum kb_nvt_pos position)
Get field of a NVT.
Definition kb.c:957
static kb_t redis_find(const char *kb_path, const char *key)
Find an existing Knowledge Base object with key.
Definition kb.c:565
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:1382
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:1453
static struct kb_item * redis_get_all(kb_t kb, const char *name)
Get all items stored under a given name.
Definition kb.c:1039
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:1547
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:517
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:1324
static char * redis_get_str(kb_t kb, const char *name)
Get a single KB string item.
Definition kb.c:848
static struct kb_item * redis_get_pattern(kb_t kb, const char *pattern)
Get all items stored under a given pattern.
Definition kb.c:1068
static GSList * redis_get_oids(kb_t kb)
Get all NVT OIDs.
Definition kb.c:1132
static int redis_save(kb_t kb)
Save all the elements from the KB.
Definition kb.c:1778
static int redis_get_int(kb_t kb, const char *name)
Get a single KB integer item.
Definition kb.c:931
static char * redis_pop_str(kb_t kb, const char *name)
Pops a single KB string item.
Definition kb.c:904
static int redis_new(kb_t *kb, const char *kb_path)
Initialize a new Knowledge Base object.
Definition kb.c:469
static int redis_get_kb_index(kb_t kb)
Return the kb index.
Definition kb.c:423
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:1506
static int redis_flush_all(kb_t, const char *)
Flush all the KB's content. Delete all namespaces.
Definition kb.c:1700
static size_t redis_count(kb_t kb, const char *pattern)
Count all items stored under a given pattern.
Definition kb.c:1167
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:1571
static int redis_add_nvt(kb_t kb, const nvti_t *nvt, const char *filename)
Insert a new nvt.
Definition kb.c:1608
static nvti_t * redis_get_nvt_all(kb_t kb, const char *oid)
Get a full NVT.
Definition kb.c:989
static int redis_del_items(kb_t kb, const char *name)
Delete all entries under a given name.
Definition kb.c:1199

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